V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
1340641314
V2EX  ›  分享创造

vuet 插件之 route:实现简易版 vue-cnode,实现列表点击详情返回后显示之前的数据

  •  
  •   1340641314 ·
    lzxb · 2017-05-23 10:31:19 +08:00 · 1980 次点击
    这是一个创建于 2733 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 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

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3616 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 48ms · UTC 04:35 · PVG 12:35 · LAX 20:35 · JFK 23:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.