在 Vue 2.x 发布之后,各种 cnode 设置的版本随之而来,但是很多的版本都没有实现从列表点击详情后返回列表能显示原来的数据。下面我就给大家介绍下 Vuet 的 route 插件,他能够轻松的帮你实现这个功能,我们以 cnode 社区的 API 为例,一步步带大家实现这个功能 第一步我们需要先安装 Vue、VueRouter、Vuet
npm install --save vue vue-router vuet
第二步,我们创建 Vuet 的实例,vuet.js
import Vue from 'vue'
import Vuet from 'vuet'
Vue.use(Vuet)
const { fetch } = window
export default new Vuet({
  data () {
    return {}
  },
  modules: {
    cnode: { // 定义模块名称
      route: { // 要使用的插件
        list: { // 这里可以随便起个名称
          data () { // 定义这个数据的基本字段
            return {
              list: []
            }
          },
          watch: 'query', // route 插件的配置,如果有多个条件的话,可以设置一个数组
          fetch () { // 配置请求的方法,必须 return 一个 Promise
            const search = this.app.$route.fullPath.split('?')[1] || ''
            return fetch(`https://cnodejs.org/api/v1/topics?${search}`)
              .then(response => response.json())
              .then((res) => {
                return { list: res.data }
              })
          }
        },
        detail: { // 这里是详情,和列表页面同理
          data () {
            return {
              id: '',
              author_id: '',
              tab: '',
              content: '',
              title: '',
              last_reply_at: '',
              good: false,
              top: false,
              reply_count: 0,
              visit_count: 0,
              create_at: '',
              author: {
                loginname: '',
                avatar_url: ''
              },
              replies: [],
              is_collect: false
            }
          },
          watch: 'params.id',
          fetch () {
            return fetch(`https://cnodejs.org/api/v1/topic/${this.app.$route.params.id}`)
              .then(response => response.json())
              .then((res) => {
                return res.data
              })
          }
        }
      }
    }
  }
})
第三步,我们创建 Vue 和 VueRouter 的实例,mian.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import vuet from './vuet'
import List from './List'
import Detail from './Detail'
Vue.use(VueRouter)
// 配置路由相关
const router = new VueRouter({
  routes: [
    {
      path: '/',
      name: 'index',
      component: List
    },
    {
      path: '/:id',
      name: 'detail',
      component: Detail
    }
  ]
})
export default new Vue({
  el: '#app', // 这里是因为演示的目的,随便写的,根据你的程序写对应的初始化元素
  vuet, // 在 Vue 的根组件中安装 vuet
  router,
  render (h) {
    return h('router-view')
  }
})
第四步,我们创建列表组件 List.vue
<template>
  <div>
    <header>
      <span v-for="(item, $index) in tabs" :key="item.value">
        <router-link :to="{ name: 'index', query: { tab: item.value } }">
          {{ item.label }}
        </router-link>
      </span>
    </header>
    <ul>
      <li v-for="(item, $index) in list.list" :key="item.id">
        <router-link :to="{ name: 'detail', params: { id: item.id } }">
          {{ item.title }}
        </router-link>
      </li>
    </ul>
  </div>
</template>
<script>
  import { mapMixins, mapState } from 'vuet'
  export default {
    mixins: [...mapMixins('cnode/route/list')], // 链接数据的更新逻辑
    data () {
      return {
        // 其实这里的数据是写死的数据,大家可以放到 local 插件中使用的。
        // 具体怎么用,大家自己发挥一下想象力咯
        tabs: [
          {
            label: '全部',
            value: 'all'
          },
          {
            label: '精华',
            value: 'good'
          },
          {
            label: '分享',
            value: 'share'
          },
          {
            label: '问答',
            value: 'ask'
          },
          {
            label: '招聘',
            value: 'job'
          }
        ]
      }
    },
    // 链接数据,重定向向为 list,这样 this.list.xxx 就能访问到我们 vuet 中的数据了
    // 哈哈,是不是好简单
    computed: mapState({ list: 'cnode/route/list' })
  }
</script>
第五步,我们创建详情的组件,Detail.vue
<template>
  <div>
    <h2>{{ detail.title }}</h2>
    <article v-html="detail.content"></article>
  </div>
</template>
<script>
  import { mapMixins, mapState } from 'vuet'
  export default {
    mixins: [...mapMixins('cnode/route/detail')],
    computed: mapState({ detail: 'cnode/route/detail' })
  }
</script>
虽然 vuet 插件目前只内置了 5 个插件,但是他压缩之后的包也就才 6kb,可谓是麻雀虽小,但是五脏俱全。 最后给上vuet 官方的地址,欢迎大家 star