EmmmuaCode EmmmuaCode
首页​
导航🚀​
  • 数据结构
  • 计算机网络
  • Java基础

    • JavaSE
    • JVM虚拟机
    • JUC并发编程
  • JavaWeb

    • Servlet
    • MVC
    • filter|listener
  • HTML
  • CSS
  • JavaScript
  • Vue
  • uni-app
  • Spring5
  • SpringMVC
  • SpringBoot2
  • SpringCloud
  • SpringSecurity
  • 搜索引擎

    • ElasticSearch
  • 消息队列

    • RabbitMQ
  • 服务器

    • Nginx🌐
  • 服务框架

    • Dubbo
  • Python基础
  • 数据分析
  • Hadoop
  • SQL 数据库

    • MySQL
  • NoSQL 数据库

    • NoSQL数据库概论
    • Redis
    • MongoDB
    • HBase
  • 框架

    • MyBatis
    • MyBatis-Plus
    • ShardingSphere
  • 部署

    • Linux
    • Docker
  • 管理

    • Maven
    • Git
  • 友情链接
  • 优秀博客文章
  • 索引

    • 分类
    • 标签
    • 归档
  • 其他

    • 关于
Github (opens new window)

wufan

海内存知己,天涯若比邻。
首页​
导航🚀​
  • 数据结构
  • 计算机网络
  • Java基础

    • JavaSE
    • JVM虚拟机
    • JUC并发编程
  • JavaWeb

    • Servlet
    • MVC
    • filter|listener
  • HTML
  • CSS
  • JavaScript
  • Vue
  • uni-app
  • Spring5
  • SpringMVC
  • SpringBoot2
  • SpringCloud
  • SpringSecurity
  • 搜索引擎

    • ElasticSearch
  • 消息队列

    • RabbitMQ
  • 服务器

    • Nginx🌐
  • 服务框架

    • Dubbo
  • Python基础
  • 数据分析
  • Hadoop
  • SQL 数据库

    • MySQL
  • NoSQL 数据库

    • NoSQL数据库概论
    • Redis
    • MongoDB
    • HBase
  • 框架

    • MyBatis
    • MyBatis-Plus
    • ShardingSphere
  • 部署

    • Linux
    • Docker
  • 管理

    • Maven
    • Git
  • 友情链接
  • 优秀博客文章
  • 索引

    • 分类
    • 标签
    • 归档
  • 其他

    • 关于
Github (opens new window)
  • HTML

    • HTML
  • CSS

    • CSS
    • CSS-02
    • CSS-03
    • CSS-浮动(float)
    • CSS-定位(position)
    • CSS3 新特性
    • CSS3 2D和3D的使用
  • JavaScript

    • JavaScript
    • JavaScript 变量
    • JavaScript 数据类型
    • JavaScript 运算符与语句
    • JavaScript For循环与数组
    • JavaScript 函数
    • JavaScript 对象
    • ES6
  • Vue

    • Vue 快速上手
  • uni-app

    • 从基础概念到uni-app项目搭建
    • 页面优化与数据处理的深入实践
    • Vuex 的应用与购物车功能实现
      • 1. vuex基本使用
        • 1.1 vuex基本介绍
        • 1.2 配置 vuex
        • 1.3 定义数据和使用数据
        • 1.4 vuex中模块的概念
      • 2. 添加购物车功能
        • 2.1 新建cart模块
        • 2.2 实现加入购物车的功能
        • 2.3 使用createlogger插件
        • 2.4 统计购物车中商品的总数量
        • 2.5 持久化存储购物车中的商品
      • 3. 动态设置tabbar数字
        • 3.1 tabBar 页面设置数字徽标
        • 3.2 将设置 tabBar 徽标的代码抽离为 mixins
    • 购物车与结算区域的功能实现与优化
    • 购物车与结算区域的深入优化与功能完善
    • 微信支付功能的实现与流程
  • studynotes
  • web
  • uni-app
wufan
2024-11-21
目录

Vuex 的应用与购物车功能实现

# 1. vuex基本使用

# 1.1 vuex基本介绍

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

# 1.2 配置 vuex

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

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

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

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


     






     



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

# 1.3 定义数据和使用数据

  1. 通过state定义数据

    const store = new Vuex.Store({
      // TODO:挂载 store 模块
      modules: {},
      state: {
    	  test: '测试'
      }
    })
    
    1
    2
    3
    4
    5
    6
    7
  2. 在页面中通过计算属性使用数据

    computed: {
      test() {
        return this.$store.state.test
      }
    },
    
    1
    2
    3
    4
    5
  3. 页面中使用数据

    {{test}}
    
    1

# 1.4 vuex中模块的概念

  1. 可以通过modules定义模块
  2. 模块中包含state、mutation、action、getters

# 2. 添加购物车功能

# 2.1 新建cart模块

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

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

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




     








     





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

# 2.2 实现加入购物车的功能

  1. 在 store 目录下的 cart.js 模块中,封装一个将商品信息加入购物车的 mutations 方法,命名为 addToCart。示例代码如下:

    export default {
      // 为当前模块开启命名空间
      namespaced: true,
    
      // 模块的 state 数据
      state: () => ({
        // 购物车的数组,用来存储购物车中每个商品的信息对象
        // 每个商品的信息对象,都包含如下 6 个属性:
        // { goods_id, goods_name, goods_price, goods_count, goods_small_logo, goods_state }
        cart: [],
      }),
    
      // 模块的 mutations 方法
      mutations: {
        addToCart(state, goods) {
          // 根据提交的商品的Id,查询购物车中是否存在这件商品
          // 如果不存在,则 findResult 为 undefined;否则,为查找到的商品信息对象
          const findResult = state.cart.find((x) => x.goods_id === goods.goods_id)
    
          if (!findResult) {
            // 如果购物车中没有这件商品,则直接 push
            state.cart.push(goods)
          } else {
            // 如果购物车中有这件商品,则只更新数量即可
            findResult.goods_count++
          }
        },
      },
    
      // 模块的 getters 属性
      getters: {},
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
  2. 在商品详情页面中,通过 mapMutations 这个辅助方法,把 vuex 中 m_cart 模块下的 addToCart 方法映射到当前页面:

    // 按需导入 mapMutations 这个辅助方法
    import { mapMutations } from 'vuex'
    
    export default {
      methods: {
        // 把 m_cart 模块中的 addToCart 方法映射到当前页面使用
        ...mapMutations('cart', ['addToCart']),
      },
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
  3. 为商品导航组件 uni-goods-nav 绑定 @buttonClick="buttonClick" 事件处理函数:

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

# 2.3 使用createlogger插件

  1. 引入createlogger
import Vuex, {
	createLogger
} from 'vuex'
1
2
3
  1. 启用插件
const store = new Vuex.Store({
	// TODO:挂载 store 模块
	modules: {
		cart: moduleCart
	},
	plugins: process.env.NODE_ENV !== 'production' ? [createLogger()] : []
})
1
2
3
4
5
6
7

# 2.4 统计购物车中商品的总数量

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

    // 模块的 getters 属性
    getters: {
       // 统计购物车中商品的总数量
       total(state) {
          return state.carts.length
       }
    }
    
    1
    2
    3
    4
    5
    6
    7
  2. 在商品详情页面的 script 标签中,按需导入 mapGetters 方法并进行使用:


     




     



    // 按需导入 mapGetters 这个辅助方法
    import { mapGetters } from 'vuex'
    
    export default {
      computed: {
        // 把 cart 模块中名称为 total 的 getter 映射到当前页面中使用
        ...mapGetters('cart', ['total']),
      },
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
  3. 动态为购物车按钮的徽标赋值:

    <van-goods-action-icon :info="total" icon="cart-o" text="购物车" bind:click="onClickIcon" />
    
    1

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

  1. 引入saveToStorage

    export default {
    	mutations: {
    		addToCart(state, goods) {
    			// 根据提交的商品的Id,查询购物车中是否存在这件商品
    			// 如果不存在,则 findResult 为 undefined;否则,为查找到的商品信息对象
    			const findResult = state.cart.find((x) => x.goods_id === goods.goods_id)
    
    			if (!findResult) {
    				// 如果购物车中没有这件商品,则直接 push
    				state.cart.push(goods)
    			} else {
    				// 如果购物车中有这件商品,则只更新数量即可
    				findResult.goods_count++
    			}
    			uni.setStorageSync('cart', state.cart)
    		},
    	}
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
  2. 修改 cart.js 模块中的 state 函数,读取本地存储的购物车数据,对 cart 数组进行初始化:

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

# 3. 动态设置tabbar数字

# 3.1 tabBar 页面设置数字徽标

需求描述:从商品详情页面导航到购物车页面之后,需要为 tabBar 中的购物车动态设置数字徽标。

  1. 把 Store 中的 total 映射到 cart.vue 中使用:


     







     



    // 按需导入 mapGetters 这个辅助方法
    import { mapGetters } from 'vuex'
    
    export default {
      data() {
        return {}
      },
      computed: {
        // 将 m_cart 模块中的 total 映射为当前页面的计算属性
        ...mapGetters('m_cart', ['total']),
      },
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
  2. 在页面刚显示出来的时候,立即调用 setBadge 方法,为 tabBar 设置数字徽标:

    onShow() {
       // 在页面刚展示的时候,设置数字徽标
       this.setBadge()
    }
    
    1
    2
    3
    4
  3. 在 methods 节点中,声明 setBadge 方法如下,通过 uni.setTabBarBadge() 为 tabBar 设置数字徽标:




     
     
     
     



    methods: {
       setBadge() {
          // 调用 uni.setTabBarBadge() 方法,为购物车设置右上角的徽标
          uni.setTabBarBadge({
             index: 2, // 索引
             text: this.total + '' // 注意:text 的值必须是字符串,不能是数字
          })
       }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

# 3.2 将设置 tabBar 徽标的代码抽离为 mixins

注意:除了要在 cart.vue 页面中设置购物车的数字徽标,还需要在其它 3 个 tabBar 页面中,为购物车设置数字徽标。

此时可以使用 Vue 提供的 mixins (opens new window) 特性,提高代码的可维护性。

  1. 在项目根目录中新建 mixins 文件夹,并在 mixins 文件夹之下新建 tabbar-badge.js 文件,用来把设置 tabBar 徽标的代码封装为一个 mixin 文件:

    import { mapGetters } from 'vuex'
    
    // 导出一个 mixin 对象
    export default {
      computed: {
        ...mapGetters('cart', ['total']),
      },
      onShow() {
        // 在页面刚展示的时候,设置数字徽标
        this.setBadge()
      },
      methods: {
        setBadge() {
          // 调用 uni.setTabBarBadge() 方法,为购物车设置右上角的徽标
          uni.setTabBarBadge({
            index: 2,
            text: this.total + '', // 注意:text 的值必须是字符串,不能是数字
          })
        },
      },
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
  2. 修改 home.vue,cate.vue,cart.vue,my.vue 这 4 个 tabBar 页面的源代码,分别导入 @/mixins/tabbar-badge.js 模块并进行使用:


     



     



    // 导入自己封装的 mixin 模块
    import badgeMix from '@/mixins/tabbar-badge.js'
    
    export default {
      // 将 badgeMix 混入到当前的页面中进行使用
      mixins: [badgeMix],
      // 省略其它代码...
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
#uni-app#小程序
上次更新: 2024/11/21, 09:18:32
页面优化与数据处理的深入实践
购物车与结算区域的功能实现与优化

← 页面优化与数据处理的深入实践 购物车与结算区域的功能实现与优化→

最近更新
01
微信支付功能的实现与流程
11-21
02
购物车与结算区域的深入优化与功能完善
11-21
03
购物车与结算区域的功能实现与优化
11-21
更多文章>
Theme by Vdoing | Copyright © 2023-2024 EmmmuaCode | 黔ICP备2022009864号-2
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式