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頁面中,還會調用 increment
和 decrement
兩個mutations去更新 count
值。
運行小程式,可以看到初始進入index頁面時是這樣的,頁面上顯示的計數結果是0:

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

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

小結
通過這個例子,是不是感覺到使用Vuex做頁面間的傳值和數據同步特別簡單?另外,你也可以在 src/stores
目錄下按需創建多個store模組,獨立管理不同業務範圍的數據,並按需導入頁面組件使用。
Vuex是開發中一件非常得力的工具,希望你能儘快掌握它。更多的用法可以參考官方文檔:https://vuex.vuejs.org/zh/