Vue基本帮助:访问组件

时间:2018-08-07 18:55:57

标签: javascript vue.js vuejs2 vue-component vue-router

我一直在尝试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等)?我觉得我走错了路。

非常感谢您的帮助。

2 个答案:

答案 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很棒,但通常会导致代码变脆,不应过度使用。