Vue.js 2 - 在没有使用Vuex的情况下在视图之间共享XHR数据?

时间:2017-11-08 10:58:34

标签: vuejs2 vue-router

我自学Vue.js 2.我的任务是从Hacker News API中提取一系列帖子。点击列表帖子后,新视图将显示该特定帖子的部分数据。

我很难理解如何在第一个视图中路由到第二个视图时如何在第二个视图中填充REST API数据。

(我使用的是vue-router和vue-resource(?),而不是Vuex(它是一个如此小的应用程序)。)

下面是Item.vue和List.vue。从List.vue,我尝试通过单击列表项来路由到Item.vue。例如,单击一个名为" Guy with Tough Time with Vue"的列表项,然后打开第二个视图以显示帖子的标题,分数,URL和评论" Guy has Tough Time与Vue"。

List.vue(创建列表,XHR请求)

<template>
<div class="list-container">
<h1>List Vue</h1>
<ul class="item-list" v-for="(item, index) in this.items">
  <li>
    <router-link class="list-item" :to="/views">
      {{index + 1}}. {{item.title}}
      <div class="points">
        Points: {{item.points}}
      </div>
    </router-link>
  </li>
</ul>
</div>
</template>
<script>
export default {
 name: 'List',
 props:[]
 data(){
  return {
    items: []
  }
 },
 mounted: function(){
   console.log("created");
  this.fetchList();
 },
 methods: {
   fetchList(){
  this.$http.get('http://hn.algolia.com/api/v1/search?query=javascript&hitsPerPage=25').then((response) => {
     this.items = response.data.hits;
   })
  }
 }
}

Item.vue(从List.vue接收特定于项目的数据)

<template>
 <video id="bgvid" playsinline autoplay loop>
   <source src="./src/assets/rad.mp4" type="video/mp4">
  <div class="item-container">
<h1>Item Vue</h1>
<div class="post-title"></div>
<div class="post-score"></div>
<div class="post-url"></div>
<ul class="post-comments">
  <li class="sngl-comment">

  </li>
</ul>

</div>
</video>
</template>
<script>
export default {
 name: 'Item',
 data(){
   return {
   item: {}
 }
},
mounted: function(){
  console.log("created");
},
methods: {

}
 }
</script>

提前致谢!

1 个答案:

答案 0 :(得分:0)

问题是第一个视图不是第二个视图的直接后代,因此您无法通过props将数据传递给它。我实际上不会使用vuex,而是通过特定列表项的路径传递id并按id获取该单个项目,例如:

const View1 = {
  template: `<div>
    <ul>
      <li v-for="item in list"><router-link :to="'view2/'+item.id">{{item.name}}</router-link></li>
    </ul>
  </div>`,
  data() {
    return {
      list: [{
        id: 1,
        name: 'foo'
      }, {
        id: 2,
        name: 'bar'
      }, {
        id: 3,
        name: 'baz'
      }]
    }
  }
}

const View2 = {
  template: `<div>Fetch item {{id}} <br /><router-link to="/">back</router-link></div>`,
  created(){
     console.log('Fetch data for item '+ this.id);
  },
  computed:{
    id(){
      return this.$route.params.id
    }
  }
}

const routes = [{
  path: '/',
  component: View1
}, {
  path: '/view2/:id',
  component: View2
}]

const router = new VueRouter({
  routes // short for `routes: routes`
})

var app = new Vue({
  router
}).$mount('#app')

在此,我已将View2上的路由设置为:view2/:id(请参阅:Dynamic route matching),现在在View2组件中,我可以通过{{访问该ID 1}}(我把它放在计算中)。一旦我得到this.$route.params.id,我就可以简单地为特定项目的数据发出ajax请求。

这里是JSFiddle:https://jsfiddle.net/craig_h_411/3hwr6mcd/

使用Vuex

如果由于某种原因您无法按特定ID检索记录,并且您不想复制该呼叫,则需要在非后代组件和Vuex之间共享状态进来了。

对vuex存在一种误解,认为这很复杂,但如果你只是想在几个组件之间共享状态,那么它真的很简单(并且它不到10kb)因此,试图避免使用它并没有多大用处,您需要添加到项目中的是:

<强> store.js

id

然后在你的app.js(或你有主Vue实例的任何地方)你会做类似的事情:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = {
  state:{
    item: {}
  },
  mutations:{
    setItem(state, value){
      state.item = value;
    }
  }
}

export default new Vuex.Store(store)

您还必须进行一些更改,例如在推送到路线之前提交状态,添加计算以从商店获取状态并从路径中删除ID,因为它不再需要

我已经更新了JSFiddle,以向您展示如何运作:https://jsfiddle.net/craig_h_411/bvswc0kb/