preface

Since the release of vue.js 2.x, I have worked on seven or eight projects and developed my own state management mode, which I call Vuet. It drives status updates with rules, it leads to a surge in productivity, it’s like a prairie, and you’re a wild horse, and it was born for agile development.

The reason

In large Vue application development, multi-component communication and multi-page communication are often difficult to overcome. A page component is often mixed with the code for obtaining data from the page and the code for responding to user operations. If it is careless, it will make the code chaotic. A, B, and C all need the same data, then write and send requests to each page, and soon the code becomes bloated. So we need a third-party library like Vuex to manage state

Vuet was originally created

From the list click go in to details, after returning from details, we look forward to show back to its original position, rather than the entire page to initialize, to request data, so the user experience is extremely bad, we look forward to have a state rules to define how to update, this is Vuet js was born in the first place. It defines state updates by rules, and it is also a new state management mode of VUe.js. Naturally rules-driven, the topic of this tutorial will be surprisingly simple, as we only need to define rules for page updates.

What do you need Vuet for when you have Vuex?

Vuex and Vuet start from a different point of view. Vuex does not recommend updating the status directly, but updates the status by submitting mutation, while Vuet is allowed. Therefore, Vuex and Vuet can be used together and have different application scenarios. Where Vuex should be used, Vuex can be used and where Vuet is available, Vuet can be used

start

The above nonsense so long, but also because vuet.js has just been born, need everyone’s support. Well, let’s get to the topic!

The directory structure

| - pages / / page components | | - topic/theme/module | | - Detail. Vue / / theme details | | -- List. Vue / / topic List related | | - the router / / router | - Index. Js / / entry file | | -- the router. Js / / instantiate VueRouter | - vuet / / vuet | | - index. The js / / entry file | | - topic - detail. Js / / Theme details the status of the | | - topic - list. Js / / topic list of state | | -- vuet. Js / / instantiate vuet | - index. HTML page entry / / program files. | - the main js / / Vue instantiation entry documentsCopy the code

Above is our basic directory structure for this project

Install the module

npm install vue vue-router vuet --saveCopy the code

These are the basic modules, and I don’t think we need to say more.

The route rules

The key to this chapter is the route rule, which can help you get, update, reset the state of the page. V-vuet-scroll command will help you handle the global scroll bar of the page and the scroll bar of the div element itself

Code community API as an example

  • main.js

      import Vue from 'vue'
      import router from './router/'
      import vuet from './vuet/'
    
      export default new Vue({
        el: '#app',
        vuet,
        router,
        render (h) {
          return h('router-view')}})Copy the code
  • vuet/index.js

      import vuet from './vuet'
    
      export default vuetCopy the code
  • vuet/vuet.js

      import Vue from 'vue'
      import Vuet from 'vuet'
      import topicList from './topic-list'
      import topicDetail from './topic-detail'
    
      Vue.use(Vuet)
    
      const vuet = new Vuet({
        data () {
          return {
            loading: true, // 请求中
            loaderr: false // 请求失败
          }
        },
        pathJoin: '-', // 父子模块的连接路径
        modules: {
          topic: {
            list: topicList,
            detail: topicDetail
          }
        }
      })
    
      vuet.beforeEach(({ path, params, state }) => {
        state.loading = true
        state.loaderr = false
      })
    
      vuet.afterEach((err, { path, params, state }) => {
        state.loading = false
        state.loaderr = !!err
      })
    
      export default vuetCopy the code
  • vuet/topic-list.js

    Export default {routeWatch: 'query', // Define page update rules data () {return {data: [], tabs: [{label: 'all ', value: 'all'}, {value: label: 'essence', 'good'}, {label: 'share' value: 'share'}, {label: 'q&a' value: 'ask'}, {label: 'Recruitment ', value: 'job' } ] } }, async fetch ({ route }) { const { tab = '' } = route.query const { data } = await window.fetch(`https://cnodejs.org/api/v1/topics?mdrender=false&tab=${tab}`).then(response => response.json()) return { data } } }Copy the code
  • vuet/topic-detail.js

    Export default {routeWatch: 'params.id', // Define page update rules data () {return {data: {id: null, author_id: null, TAB: null, content: null, title: null, last_reply_at: null, good: false, top: false, reply_count: 0, visit_count: 0, create_at: null, author: { loginname: null, avatar_url: null }, replies: [], is_collect: false } } }, async fetch ({ route }) { const { data } = await window.fetch(`https://cnodejs.org/api/v1/topic/${route.params.id}`).then(response => response.json()) return { data } } }Copy the code
  • router/index.js

      import router from './router'
    
      export default routerCopy the code
  • router/router.js

      import Vue from 'vue'
      import VueRouter from 'vue-router'
      import TopicList from '.. /pages/topic/List'
      import TopicDetail from '.. /pages/topic/Detail'
    
      Vue.use(VueRouter)
    
      const RouterView = {
        render (h) {
          return h('router-view')}}const router = new VueRouter({
        routes: [{path: '/'.component: RouterView,
            children: [{path: ' '.name: 'topic-list'.component: TopicList
              },
              {
                path: '/:id'.name: 'topic-detail'.component: TopicDetail
              }
            ]
          }
        ]
      })
    
      export default routerCopy the code
    • pages/topic/List.vue

      <template>
        <! The route rule is also used in the component to handle the scrolling of the page. If you want to record both the global scroll bar and div scroll bar at the same time, you can set window.self to record N scroll positions. V-vuet-scroll ="{path: 'topic-detail', name: 'XXX'}" -->
        <div v-vuet-scroll.window="{ path: 'topic-list' }">
          <header>
            <ul>
              <li v-for="item in list.tabs">
                <router-link :to="{ name: 'topic-list', query: { tab: item.value } }">{{ item.label }}</router-link>
              </li>
            </ul>
          </header>
          <ul class="list">
            <li v-for="item in list.data">
                <router-link :to="{ name: 'topic-detail', params: { id: item.id } }">{{ item.title }}</router-link>
            </li>
          </ul>
        </div>
      </template>
      <script>
        import { mapRules, mapModules } from 'vuet'
      
        export default {
          mixins: [
            // Set the update rule for the module
            mapRules({
              route: 'topic-list'
            }),
            // The status of the connection module
            mapModules({
              list: 'topic-list'}})]</script>
      <style scoped>
      
      </style>Copy the code
    • pages/topic/Detail.vue

      <template>
        <div v-vuet-scroll.window="{ path: 'topic-detail' }">
          <h3>{{ detail.data.title }}</h3>
          <div v-html="detail.data.content"></div>
        </div>  
      </template>
      <script>
        import { mapRules, mapModules } from 'vuet'
      
        export default {
          mixins: [
            // Set the update rule for the module
            mapRules({
              route: 'topic-detail'
            }),
            // The status of the connection module
            mapModules({
              detail: 'topic-detail'}})]</script>
      <style scoped>
      
      </style>Copy the code

conclusion

At first glance, Vuet doesn’t seem very complicated. You just need to define the module state and then set the corresponding rules in the component to update the module state. In fact, vuet’s own route rule can record the global scroll bar and div’s own scroll bar at the same time, which greatly improves our user experience

  • Example source code
  • Vuet official