mpvue開發小程式教程(六)

  • 2019 年 10 月 7 日
  • 筆記

作者:一斤程式碼,原文地址:https://dwz.cn/u3dqw5wd

在上一章節中,我們列舉了在Vue中能用但在mpvue中不能用或需要特別注意的特性,在實際開發前了解一下還是很有必要的,可以避免浪費找錯誤的時間。

如果你使用過原生的小程式框架,你一定經歷過或思考過怎麼解決以下的問題:

  • 怎麼存放可全局訪問的變數?
  • 頁面跳轉的時候,怎麼傳遞參數到下一個頁面比較好?
  • 頁面返回上一頁的時候,怎麼傳遞當前頁的數據到上一頁?
  • 多個頁面間需要同步數據,怎麼做比較好?

網上一搜,解決的方法通常也是五花八門的,什麼通過app上的globalData啊、通過存取storage啊、通過一個單獨的模組(module)啊、通過Page路由棧啊、通過引入自定義事件啊、通過引入redux啊,等等等等……

在原生小程式框架里,確實沒有提供什麼太統一的方式來指導開發者解決這個問題,大家只能各自用著暫時能解決當前問題的方案。

不過,既然我們用了Vue/mpvue,遇到這種情況,自然而然的就會想到一個方案,那就是Vuex。Vuex 是一個專為 Vue 應用程式開發的狀態管理模式,它採用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。

通過使用Vuex,我們可以在mpvue里很方便的對需要在app、頁面、組件之間共享的數據進行很好的統一管理,可以更方便有效的在各個程式碼部分對這些共享數據進行訪問,同時可以使得你的程式碼條理變得更加清晰。

我們知道,Vuex一般有2種用法,當創建好store後:

  • 第一種用法是將store綁定到需要訪問store內容的Vue實例上,然後通過該Vue實例下組件的 this.$store來引用;或通過 mapState等一系列映射函數將store中的state、getters、mutations、actions等映射成組件的計算屬性或methods方法來使用;
  • 第二種用法是直接在組件中通過 import導入store所在的模組文件,然後調用該store上的相關方法和屬性,比如 commit()dispatch()等方法來操作store中的內容。

經過我的實測,上面的這兩種方式在mpvue中也都是可用的。但是,由於mpvue不像Vue Web單頁應用那種單Vue實例的結構,而是採用了多Vue實例的結構(app和各個頁面都會由單獨的Vue實例來管理),所以我個人推薦採用上面所說的第二種用法,這種方式會更加靈活和簡單一些。

讓我們開始寫程式碼,先在 src目錄下新建一個stores目錄,接著在stores目錄下新建一個名為 global-store.js的文件:

import Vue from 'vue'  import Vuex from 'vuex';    Vue.use(Vuex);    export default new Vuex.Store({    state: {      count: 0    },    mutations: {      increment: (state) => {        state.count += 1      },      decrement: (state) => {        state.count -= 1      }    }  });

在這個程式碼中,我們新建了一個 Store實例,管理了一個名為 count的數字類型的狀態,並定義了2個mutations去操作(增減)這個狀態值。

接著,我們要在2個頁面中訪問這個store。讓我們在 src/pages目錄下編寫2個頁面:index和test1。

這是 pages/index/index.vue的程式碼內容:

<template>    <div class="container">      <div>計數結果:{{count}}</div>      <a href="/pages/test1/main" class="navlink">進入計數器頁面</a>    </div>  </template>    <script>  import globalStore from "../../stores/global-store";    export default {    computed: {      count() {        return globalStore.state.count;      }    }  };  </script>    <style scoped>  .navlink {    text-decoration: underline;  }  </style>

這是 pages/test1/index.vue的程式碼內容:

<template>    <div class="container btns">      <button class="calbtn" @click="hanleDecrement">-</button>      <span class="calnum">{{count}}</span>      <button class="calbtn" @click="hanleIncrement">+</button>    </div>  </template>    <script>  import globalStore from "../../stores/global-store";    export default {    computed: {      count() {        return globalStore.state.count;      }    },      methods: {      hanleIncrement() {        globalStore.commit("increment");      },        hanleDecrement() {        globalStore.commit("decrement");      }    }  };  </script>    <style scoped>  .btns {    display: flex;    align-items: center;  }  .calnum {    color: red;    font-size: 32px;  }  </style>

這樣,我們就有了2個使用了我們定義的global-store的頁面,這些頁面都會從store中獲取 count狀態值並顯示;在test1頁面中,還會調用 incrementdecrement兩個mutations去更新 count值。

運行小程式,可以看到初始進入index頁面時是這樣的,頁面上顯示的計數結果是0:

然後點擊「進入計數器頁面」進到test1頁面,並在這個頁面上點擊加減按鈕操作一下,當中顯示的count數會發生改變:

最後,點擊左上角返回按鈕返回index頁面,你將發現這個頁面上的計數結果也已經發生了改變,自動同步成前面操作後的結果了:

小結

通過這個例子,是不是感覺到使用Vuex做頁面間的傳值和數據同步特別簡單?另外,你也可以在 src/stores目錄下按需創建多個store模組,獨立管理不同業務範圍的數據,並按需導入頁面組件使用。

Vuex是開發中一件非常得力的工具,希望你能儘快掌握它。更多的用法可以參考官方文檔:https://vuex.vuejs.org/zh/