Vue.js 如何避免创建数百个文件。vue

Vue.js 如何避免创建数百个文件。vue,vue.js,nuxt.js,vuex,vue-router,Vue.js,Nuxt.js,Vuex,Vue Router,我正在建立一个有很多项目的网站。 因此,路径如下所示: example.com/catalog/indior/fireflace/awesome one 目前我正在创建成百上千的Vue实例: AwesomeOne.vue AnotherOne.vue YetAnotherThing.vue ... AhundredthThing.vue 它们内部只有一个经过过滤的数组,并将一个道具传递给可重用组件,该组件使用来自Vuex存储的数据。 所以我在想,有没有办法避免创建这么多Vue文件?我用Nuxt

我正在建立一个有很多项目的网站。 因此,路径如下所示:

example.com/catalog/indior/fireflace/awesome one

目前我正在创建成百上千的
Vue
实例:

AwesomeOne.vue
AnotherOne.vue
YetAnotherThing.vue
...
AhundredthThing.vue
它们内部只有一个经过过滤的数组,并将一个道具传递给可重用组件,该组件使用来自
Vuex
存储的数据。 所以我在想,有没有办法避免创建这么多
Vue
文件?我用
Nuxt.js
解决了这个问题,但是它只自动生成路由,这使得开发稍微容易一些。但是我仍然需要创建很多内部代码几乎相同的文件(实际上只有三个字的区别:计算属性的名称、过滤器选项和道具的名称)

我在考虑使用
Vuex.state
中的数据动态分配URL的一些计算属性。但我不能把东西放在一起

按要求张贴代码: Catalog.vue

<template>
  <v-main>
    <v-row>
      <v-col
        v-for="category in categories"
        :key="category.i"
      >
        <v-card
          router
          :to="category.link"
        >
          <v-img
            height="250"
            width="250"
            :src="category.img"
          />
          <v-card-title>
            {{ category.name }}
          </v-card-title>
        </v-card>
      </v-col>
    </v-row>
  </v-main>
</template>

<script>
export default {
computed: {
  categories () {
    return this.$store.state.categories
  }
}
}
</script>

你们很接近,有几种不同的方法可以解决这个问题。我将展示IMO最简单的方法,即继续使用道具,并将您拥有的硬编码数据推送到组件层次结构的更上一层

我将使用
IndividualItem.vue
作为示例,因为它是迄今为止最明显的应用方法:

<template>
  <v-sheet>
    <v-card>
      <individual-item-view :items="this.items" />
      <v-card />
    </v-card>
  </v-sheet>
</template>

<script>
import IndividualItemView from "../../../../components/IndividualItemView.vue";
export default {
  components: { IndividualItemView },

  // Add a prop for the title
  props: {
    title: {
      type: String,
      required: true,
    },
  },

  // Filter only store items with that title
  computed: {
    items() {
      return this.$store.state.items.filter(
        (item) => item.title === this.title
      );
    },
  },
};
</script>
然后,组件的用户可能会这样做(注意:您可以创建
obossanaitem
与您已经使用的方法完全相同,只是在父组件范围内):


作为最后一条结束语建议(可能是您缺少的部分),几乎所有硬编码数据(如
title:obossana
)都应该直接来自页面组件或API,而API最终允许您创建可重用组件

例如,负责为
example.com/catalog/indior/fireflace/awesomeone
呈现页面的页面组件应该负责向其所有子组件提供呈现正确数据所需的信息

这不是唯一的方法,但它肯定是最容易开始使用的方法,我建议使用它,而不是为每个类别、子类别等创建特定组件


正如我在本文开头提到的,您已经非常接近了,您只需要继续将特定的数据项抽象到父组件。Vue和Nuxt还有其他一些功能,比如,它们也可以帮助使特定的过滤调用可重用,但这是另一个主题。

好吧,我想出来了

\u view.vue
对于单个项目视图:

<script>
export default {
  async asyncData() {
    const items = await fetch(
      'API URL here'
    ).then((res) => res.json())

    return { items }
  },
  data() {
    return {
      params: this.$route.params.view,
      title: '',
    }
  },
  computed: {
    filteredItems() {
      return this.items.filter((item) => item.title === this.$route.params.view)
    },
  },
}
</script>
h1
h2
h3
标签帮助我(通过显示)变量值

文件树是(根目录本身):

还有一点
api.json

{
    "title": "stremnaya-arka",
    "path": "/catalog/outdoor/arcs/stremnaya-arka",
    "name": "Стрёмная арка",
    "type": "arcs",    
}
文件名可能有点混乱,但我希望不是这样


我希望它能帮助其他和我一样挣扎的新手;)

抱歉,我有点忙着学习Nuxt.js。现在我有时间看看这里。我想我们这里有误解。我知道如何传递道具和创建可重用组件。问题是,我必须实际创建所有文件:
catalog.vue
,其中将嵌套
indior.vue
,其中将嵌套
fireflaces.vue
(其中嵌套了可重用的
ItemView.vue
),其中将嵌套
awesome fireflace.vue
(其中嵌套了可重用的
IndividualItemView.vue
)。我的问题是,我不想创建100x
文件。vue
中包含相同的代码,只有一个不同的道具传递到其中的可重用组件中。
壁炉。vue
好的,我找到了我一直在寻找的东西。它称为动态页面。我希望我能找到如何应用它的方法:)
<template>
  <v-sheet>
    <v-card>
      <individual-item-view :items="this.obossana" />
      <v-card />
    </v-card>
  </v-sheet>
</template>

<script>
import IndividualItemView from '../../../../components/IndividualItemView.vue'
export default {
  components: { IndividualItemView },
    
    computed: {
  items () {
    return this.$store.state.items
  },
  obossana () {
      return this.items.filter((item) => item.title === "obossana");
    },  

}
}
</script>

<style>

</style>
<template>
  <v-sheet>
    <v-card
      v-for="item in items"
      :key="item.i"
    >
      <v-card-title> {{ item.name }} </v-card-title>
      
      <expandable-image
        class="image"
        close-on-background-click       
        :src="item.img"
      />
      <v-card-subtitle> Цена: {{ item.price }} раз послать тебя ко всем чертям </v-card-subtitle>
      <v-card-text> {{ item.description }} </v-card-text>
    </v-card>
  </v-sheet>
</template>

<script>

export default {
    mounted() {
    const viewportMeta = document.createElement('meta');
    viewportMeta.name = 'viewport';
    viewportMeta.content = 'width=device-width, initial-scale=1';
    document.head.appendChild(viewportMeta);
  },
props: {
        items: {
        type: Array,
        required: true,
        },
    },
}
</script>

<style scoped>
.image {
  width: 400px;
  max-width: 100%;
}
</style>
 {
        name: "Обоссаная банкетка",
        title: "obossana",
        type: "banquet",
        path: "/catalog/indoor/banquet/obossana",
        price: "215361",
        img:
          "https://b2.3ddd.ru/media/cache/tuk_model_custom_filter_ru/model_images/0000/0000/0079/79546.53239b3804d0a.jpeg",
        description: "blah blah blah",
      },
<template>
  <v-sheet>
    <v-card>
      <individual-item-view :items="this.items" />
      <v-card />
    </v-card>
  </v-sheet>
</template>

<script>
import IndividualItemView from "../../../../components/IndividualItemView.vue";
export default {
  components: { IndividualItemView },

  // Add a prop for the title
  props: {
    title: {
      type: String,
      required: true,
    },
  },

  // Filter only store items with that title
  computed: {
    items() {
      return this.$store.state.items.filter(
        (item) => item.title === this.title
      );
    },
  },
};
</script>
<IndividualItem title="obossana" />
<template>
  <v-sheet>
    <v-card>
      <individual-item-view :items="this.items" />
      <v-card />
    </v-card>
  </v-sheet>
</template>

<script>
import IndividualItemView from "../../../../components/IndividualItemView.vue";
export default {
  components: { IndividualItemView },

  // Any items may be passed in, allowing the user to group
  // different items together however they need.
  props: {
    items: {
      type: Array,
      default: () => [],
    },
  },
};
</script>
<IndividualItem :items="obossanaItems" />
<script>
export default {
  async asyncData() {
    const items = await fetch(
      'API URL here'
    ).then((res) => res.json())

    return { items }
  },
  data() {
    return {
      params: this.$route.params.view,
      title: '',
    }
  },
  computed: {
    filteredItems() {
      return this.items.filter((item) => item.title === this.$route.params.view)
    },
  },
}
</script>
<template>
  <v-main>
    <h1>API: items</h1>
    <h2>'/catalog/_subcategory/_individualitem/_view.vue' here</h2>
    <h3>params.view: {{ params }}</h3>
    <v-card v-for="item in filteredItems" :key="item.i">
      <v-avatar size="200">
        <img :src="item.img" alt="картинка предмета" />
      </v-avatar>
      <v-card-title>
        {{ item.name }} and item.title: {{ item.title }}
      </v-card-title>
      <v-card-subtitle>Цена: {{ item.price }} сантиметров</v-card-subtitle>
      <v-card-text> {{ item.description }} </v-card-text>
    </v-card>
  </v-main>
</template>
├── index.vue
├── _subcategory
│   ├── _individualitem
│   │   └── _view.vue
│   └── _items.vue
└── _type.vue
{
    "title": "stremnaya-arka",
    "path": "/catalog/outdoor/arcs/stremnaya-arka",
    "name": "Стрёмная арка",
    "type": "arcs",    
}