• Vuex快速入门


    1.vuex简介

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

    uni-app 内置了 Vuex (opens new window)

    优势

    • Vuex的状态存储是响应式的,可跟踪每一个状态变化,一旦它改变,所有关联组件都会自动更新相对应的数据。
    • 共享数据,解决了非父子组件的消息传递(将数据存放在state中)。
    • 统一状态管理,减少了请求次数,有些情景可以直接从内存中的state获取数据

    项目结构

    使用 Vuex 需要遵守的规则:

    • 应用层级的状态应该集中到单个 store 对象中。

    • 提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。

    • 异步逻辑都应该封装到 action 里面。

    核心概念

    每一个 Vuex 应用的核心就是 store(仓库),它包含着你的应用中大部分的状态 (state)。

    状态管理有5个核心:stategettermutationactionmodule

    2.使用详解

    在项目根目录中创建 store 文件夹,专门用来存放 vuex 相关的模块

    在 store 目录上鼠标右键,选择 新建 -> js文件,新建 store.js 文件:

    在 store.js 中按照如下 4 个步骤初始化 Store 的实例对象

    1. // 1. 导入 Vue 和 Vuex
    2. import Vue from 'vue'
    3. import Vuex from 'vuex'
    4. // 2. 将 Vuex 安装为 Vue 的插件
    5. Vue.use(Vuex)
    6. // 3. 创建 Store 的实例对象
    7. const store = new Vuex.Store({
    8. // TODO:挂载 store 模块
    9. modules: {},
    10. })
    11. // 4. 向外共享 Store 的实例对象
    12. export default store

    在 main.js 中导入 store 实例对象并挂载到 Vue 的实例上:

    1. // 1. 导入 store 的实例对象
    2. import store from './store/store.js'
    3. // 省略其它代码...
    4. const app = new Vue({
    5. ...App,
    6. // 2. 将 store 挂载到 Vue 实例上
    7. store,
    8. })
    9. app.$mount()

     以我的项目中购物车模块为例

    在 store 目录上鼠标右键,选择 新建 -> js文件,创建购物车的 store 模块,命名为 cart.js

    在 cart.js 中,初始化如下的 vuex 模块:

    1. export default {
    2. // 为当前模块开启命名空间
    3. namespaced: true,
    4. // 模块的 state 数据
    5. state: () => ({
    6. // 购物车的数组,用来存储购物车中每个商品的信息对象
    7. // 每个商品的信息对象,都包含如下 6 个属性:
    8. // { goods_id, goods_name, goods_price, goods_count, goods_small_logo, goods_state }
    9. cart: [],
    10. }),
    11. // 模块的 mutations 方法
    12. mutations: {},
    13. // 模块的 getters 属性
    14. getters: {},
    15. }

    在 store/store.js 模块中,导入并挂载购物车的 vuex 模块,示例代码如下:

    1. import Vue from 'vue'
    2. import Vuex from 'vuex'
    3. // 1. 导入购物车的 vuex 模块
    4. import moduleCart from './cart.js'
    5. Vue.use(Vuex)
    6. const store = new Vuex.Store({
    7. // TODO:挂载 store 模块
    8. modules: {
    9. // 2. 挂载购物车的 vuex 模块,模块内成员的访问路径被调整为 m_cart,例如:
    10. // 购物车模块中 cart 数组的访问路径是 m_cart/cart
    11. m_cart: moduleCart,
    12. },
    13. })
    14. export default store

    在商品详情页goods_detail.vue 中,修改  标签中的代码如下:

    1. // 从 vuex 中按需导出 mapState 辅助方法
    2. import { mapState } from 'vuex'
    3. export default {
    4. computed: {
    5. // 调用 mapState 方法,把 m_cart 模块中的 cart 数组映射到当前页面中,作为计算属性来使用
    6. // ...mapState('模块的名称', ['要映射的数据名称1', '要映射的数据名称2'])
    7. ...mapState('m_cart', ['cart']),
    8. },
    9. // 省略其它代码...
    10. }

    注意:今后无论映射 mutations 方法,还是 getters 属性,还是 state 中的数据,都需要指定模块的名称,才能进行映射。

    1. <view class="yf">快递:免运费 -- {{cart.length}}view>

    实现加入购物车的功能

    1. // 模块的 mutations 方法
    2. mutations: {
    3. addToCart(state, goods) {
    4. // 根据提交的商品的Id,查询购物车中是否存在这件商品
    5. // 如果不存在,则 findResult 为 undefined;否则,为查找到的商品信息对象
    6. const findResult = state.cart.find((x) => x.goods_id === goods.goods_id)
    7. if (!findResult) {
    8. // 如果购物车中没有这件商品,则直接 push
    9. state.cart.push(goods)
    10. } else {
    11. // 如果购物车中有这件商品,则只更新数量即可
    12. findResult.goods_count++
    13. }
    14. },
    15. },

    在商品详情页面中,通过 mapMutations 这个辅助方法,把 vuex 中 m_cart 模块下的 addToCart 方法映射到当前页面:

    1. // 按需导入 mapMutations 这个辅助方法
    2. import { mapMutations } from 'vuex'
    3. export default {
    4. methods: {
    5. // 把 m_cart 模块中的 addToCart 方法映射到当前页面使用
    6. ...mapMutations('m_cart', ['addToCart']),
    7. },
    8. }

    为商品导航组件 uni-goods-nav 绑定 @buttonClick="buttonClick" 事件处理函数:

    1. // 右侧按钮的点击事件处理函数
    2. buttonClick(e) {
    3. // 1. 判断是否点击了 加入购物车 按钮
    4. if (e.content.text === '加入购物车') {
    5. // 2. 组织一个商品的信息对象
    6. const goods = {
    7. goods_id: this.goods_info.goods_id, // 商品的Id
    8. goods_name: this.goods_info.goods_name, // 商品的名称
    9. goods_price: this.goods_info.goods_price, // 商品的价格
    10. goods_count: 1, // 商品的数量
    11. goods_small_logo: this.goods_info.goods_small_logo, // 商品的图片
    12. goods_state: true // 商品的勾选状态
    13. }
    14. // 3. 通过 this 调用映射过来的 addToCart 方法,把商品信息对象存储到购物车中
    15. this.addToCart(goods)
    16. }
    17. }

    动态统计购物车中商品的总数量

    在 cart.js 模块中,在 getters 节点下定义一个 total 方法,用来统计购物车中商品的总数量:

    1. // 模块的 getters 属性
    2. getters: {
    3. // 统计购物车中商品的总数量
    4. total(state) {
    5. let c = 0
    6. // 循环统计商品的数量,累加到变量 c 中
    7. state.cart.forEach(goods => c += goods.goods_count)
    8. return c
    9. }
    10. }

     通过 watch 侦听器,监听计算属性 total 值的变化,从而动态为购物车按钮的徽标赋值

    1. watch: {
    2. // 定义 total 侦听器,指向一个配置对象
    3. total: {
    4. // handler 属性用来定义侦听器的 function 处理函数
    5. handler(newVal) {
    6. const findResult = this.options.find(x => x.text === '购物车')
    7. if (findResult) {
    8. findResult.info = newVal
    9. }
    10. },
    11. // immediate 属性用来声明此侦听器,是否在页面初次加载完毕后立即调用
    12. immediate: true
    13. }
    14. }

    持久化存储购物车中的商品 

    在 cart.js 模块中,声明一个叫做 saveToStorage 的 mutations 方法,此方法负责将购物车中的数据持久化存储到本地:

    1. // 将购物车中的数据持久化存储到本地
    2. saveToStorage(state) {
    3. uni.setStorageSync('cart', JSON.stringify(state.cart))
    4. }

    修改 mutations 节点中的 addToCart 方法,在处理完商品信息后,调用步骤 1 中定义的 saveToStorage 方法:

    1. addToCart(state, goods) {
    2. // 根据提交的商品的Id,查询购物车中是否存在这件商品
    3. // 如果不存在,则 findResult 为 undefined;否则,为查找到的商品信息对象
    4. const findResult = state.cart.find(x => x.goods_id === goods.goods_id)
    5. if (!findResult) {
    6. // 如果购物车中没有这件商品,则直接 push
    7. state.cart.push(goods)
    8. } else {
    9. // 如果购物车中有这件商品,则只更新数量即可
    10. findResult.goods_count++
    11. }
    12. // 通过 commit 方法,调用 m_cart 命名空间下的 saveToStorage 方法
    13. this.commit('m_cart/saveToStorage')
    14. }

    修改 cart.js 模块中的 state 函数,读取本地存储的购物车数据,对 cart 数组进行初始化:

    1. // 模块的 state 数据
    2. state: () => ({
    3. // 购物车的数组,用来存储购物车中每个商品的信息对象
    4. // 每个商品的信息对象,都包含如下 6 个属性:
    5. // { goods_id, goods_name, goods_price, goods_count, goods_small_logo, goods_state }
    6. cart: JSON.parse(uni.getStorageSync('cart') || '[]')
    7. }),

  • 相关阅读:
    跨平台游戏引擎 Axmol-2.1.3 发布
    web课程设计网页规划与设计 基于HTML+CSS+JavaScript制作智能停车系统公司网站静态模板
    【leetcode】滑动窗口专题
    SpringBoot + FFmpeg实现一个简单的M3U8切片转码系统
    后台管理----搜索,重置功能
    java 实现命令行模式
    后端技术知识点内容-全部内容-面试宝典-后端面试知识点
    【Golang开发面经】奇安信(两轮技术面)
    Meta-World:多任务、持续学习、终身学习、元学习、强化学习的基准和评估
    SAS|proc report
  • 原文地址:https://blog.csdn.net/m0_63748493/article/details/126945558