我一直在尝试vue.js,并且在路由时难以访问组件中的JS对象值。
使用这个仓库https://github.com/johnayeni/filter-app-vue-js进行实验,我只是在尝试复制一个基本的“产品列表”和“产品描述”应用程序,但我无法使其正常运行。存储库的主页(SearchPage.vue组件)用作“产品列表”,我只是想添加“产品描述”组件,一次只显示一项。
我添加了一个“描述页面”组件(称为“ item.vue”),以允许用户单击一种语言/框架,然后将其路由到item.vue,以仅显示该特定对象的关联信息(item.name,item.logo等),即不显示任何其他语言。
下面是一些教程,这是我尝试过的:
首先,我将ID添加到JS对象(位于data / data.js中),即 id:'1'。
const data = [
{
id: '1',
name: 'vue js',
logo: 'http://... .png',
stack: [ 'framework', 'frontend', 'web', 'mobile' ],
},
{
id: '2',
name: 'react js',
logo: 'http://... .png',
stack: [ 'framework', 'frontend', 'web', 'mobile' ]
},
...
];
export default data
然后,我将item.name(在ItemCard.vue中)包装在路由器链接标记中:
<router-link :to="'/item/'+item.id"> {{ item.name}} </router-link>
然后我在router / index.js中添加了新路径:
{
path: './item/:id',
component: item,
props: true
}
但是,当单击该路由器链接时,我只能访问“ .id”(通过$ route.params.id),但无法获取.name或.logo。如何访问其他值(即item.name,item.logo等)?我觉得我走错了路。
非常感谢您的帮助。
答案 0 :(得分:4)
您访问id
的唯一原因是它是一个URL参数:./item/:id
。
您在此处有几种选择,具体取决于您要完成的工作:
如@dziraf所建议,您可以使用vuex
创建一个商店,从而使您可以在应用程序中的任何位置访问所有数据:
export default {
computed: {
data() {
return this.$store.data;
}
}
}
在此处了解更多信息:https://vuex.vuejs.org/
作为替代方案,您可以仅导入数据,并通过其id
抓取正确的项目:
import data from './data.js';
export default {
computed: {
data() {
return data.find(d => d.id === this.$route.params.id);
}
}
}
仅取决于您要执行的操作。
答案 1 :(得分:2)
我想您只需要一个包装器组件即可从URL中获取所需的项目并呈现适当的项目。假设有一个ItemWrapper:
<template>
<item-card :item="item"></item-card>
</template>
<script>
import ItemCard from './ItemCard.vue';
import data from '../data/data';
export default {
components: {
ItemCard,
},
props: {
stackNameUrl: {
required: true,
type: String,
},
},
data() {
return {
item: {},
}
},
computed: {
stackName() {
return decodeURI(this.stackNameUrl);
}
},
created() {
this.item = data.find( fw => fw.name === this.stackName);
}
}
</script>
<style>
</style>
此组件采用一个属性,该属性是用uri编码的stack / fw名称,对其进行解码,然后基于该字符串从数据中找到fw,并使用fw项呈现ItemCard
。
为此,我们需要设置路由器,以便/item/vue js
f.i.使用'vue js'作为ItemWrapper
道具来渲染stackNameUrl
。为此,重要的一点是将props
设置为true:
import Vue from 'vue';
import Router from 'vue-router';
import SearchPage from '@/components/SearchPage';
import ItemWrapper from '@/components/ItemWrapper';
Vue.use(Router);
export default new Router({
routes: [
{
path: '/',
name: 'SearchPage',
component: SearchPage
},
{
path: '/item/:stackNameUrl',
name: 'ItemWrapper',
component: ItemWrapper,
props: true,
},
]
});
现在,我们需要修改SearchPage.vue
以使堆栈框充当链接。代替:
<!-- iterate data -->
<item-card v-for="(item, index) in filteredData" :key="index" :item="item"></item-card>
我们现在放置:
<template v-for="(item, index) in filteredData" >
<router-link :to="'/item/' + item.name" :key="index">
<item-card :key="index" :item="item"></item-card>
</router-link>
</template>
因此,现在每个组件都放置在指向item/name
的链接中。
瞧瞧。
一些注意事项:
:param
是vue路由器正常工作的关键。您想使用它来呈现ItemCard
本身。那可能有效,但是您需要从组件created()
的数据中检索fw。这会将您的卡组件与data.js
绑定在一起,这很不好,因为这种组件可以重用,并且采用item
参数比在这种情况下从文件中获取数据要好得多。因此,创建了ItemWrapper
来代理请求并为卡选择正确的框架。
您仍然应该检查用户键入错误字符串的情况。
在寻求vuex解决方案之前,先深入探索Vue。 Vuex很棒,但通常会导致代码变脆,不应过度使用。