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

Vue.js 2 - Sharing XHR Data between Views WITHOUT using Vuex?

我正在自学 Vue.js 2. 我的任务是从 Hacker News API 中提取 post 的列表。单击列表 post 后,一个新视图将显示特定 post.

中的一些数据

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

(我正在使用 vue-router 和 vue-resource(?),而不是 Vuex(这是一个很小的应用程序)。)

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

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 接收 item-specific 数据)

<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>

提前致谢!

问题是第一个视图不是第二个视图的直接后代,因此您不能通过 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 组件中我可以通过 this.$route.params.id(我已经计算好了)。获得 id 后,我可以简单地对特定项目的数据发出 ajax 请求。

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

使用 Vuex

如果由于某种原因无法通过特定 ID 检索记录并且不想重复调用,则需要在非后代组件之间共享状态,这就是 Vuex 的用武之地。

人们对 vuex 有一个误解,认为它很复杂,但如果你只想在几个组件之间共享状态,它真的很简单(而且它的大小不到 10kb)所以真的没有太大用处试图避免它,所有你需要添加到你的项目是:

store.js

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)

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

import Vue from 'vue'
import store from './store'

import App from './components/App.vue'

new Vue({
  store, // this will be available in components via this.$store
  render: h => h(App)
}).$mount('#app')

您还必须进行一些更改,例如在推送到路由之前提交状态、添加计算以从存储中获取状态以及从路由中删除不再需要的 ID。

我已经更新了 JSFiddle 以向您展示它是如何工作的:https://jsfiddle.net/craig_h_411/bvswc0kb/