通过购物车的一个案列, 把 vuex 学习了一篇.
vuex 概念浅谈
Vuex 是一个专为 vue.js 应用程序开发的状态管理模式. 它采用集中式存储管理应用的所有组件的状态, 并以相应的规则保证状态以一种可预测的方式发生变化. 简单的来说, 就是数据共用, 对数据集中起来进行统一的管理.
如果您的应用够简单, 您最好不要使用 Vuex. 一个简单的 global event bus 就足够您所需了. 但是, 如果您需要构建是一个中大型单页应用, 您很可能会考虑如何更好地在组件外部管理状态, Vuex 将会成为自然而然的选择.
核心概念主要有这些
State
Vuex 使用单一状态树 -- 是的, 用一个对象就包含了全部的应用层级状态, 将所需要的数据写放这里, 类似于 data.
Getter
有时候我们需要从 store 中的 state 中派生出一些状态, 使用 Getter, 类似于 computed.
Mutation
更改 Vuex 的 store 中的状态的唯一方法, 类似 methods.
Action
Action 提交的是 mutation, 而不是直接变更状态, 可以包含任意异步操作, 这里主要是操作异步操作的, 使用起来几乎和 mutations 方法一模一样, 类似 methods.
Module
当应用变得非常复杂时, store 对象就有可能变得相当臃肿. Vuex 允许我们将 store 分割成模块(module). 每个模块拥有自己的 state,mutation,action,getter, 甚至是嵌套子模块.
vuex
首先需要创建一个 Vue 项目
- # 全局安装 vue-cli
- $ NPM install --global vue-cli
- # 创建一个基于 webpack 模板的新项目
- $ vue init webpack my-project
- # 安装依赖, 走你
- $ cd my-project
- $ NPM install
- $ NPM run dev
安装 vuex
NPM install --save vuex
对 vuex 进行配置
1. 创建一个 store 文件夹
2. 在 store 文件夹下创建如图的一系列 JS 文件
这里写图片描述
3. 在 main.JS 文件中引入上面创建的 store.JS
- import store from './store'
- new Vue({
- el: '#app',
- store, // 将 store 暴露出来
- components: { App },
- template: '<App/>'
- })
4. 将要存放的数据写在 state 对象中, state 则存写在 index.JS 文件中.
- import Vue from 'vue'
- import Vuex from 'vuex'
- import mutations from './mutations'
- import actions from './actions'
- import getters from './getters'
- import shop from './modules/shop'
- Vue.use(Vuex)
- const state = {
- goods: [
- {
- id: '0',
- name: 'vivo-X20Plus 屏幕指纹版',
- hint: '逆光也清晰, 照亮你的美',
- price: 3596.00,
- num: 0,
- img: require('../assets/v.jpg')
- },
- {
- id: '1',
- name: '华为 mate10Plus',
- hint: '真正的人工智能芯片',
- price: 4999.00,
- num: 0,
- img: require('../assets/h.jpeg')
- },
- {
- id: '2',
- name: '华为 mate10Plus',
- hint: '真正的人工智能芯片',
- price: 4999.00,
- num: 0,
- img: require('../assets/v.jpg')
- }
- ],
- totalPrice: 0.00,
- totalNum: 0
- }
- export default new Vuex.Store({
- state,
- mutations,
- actions,
- getters,
- modules: {
- shop //shop 模块
- }
- })
5. 将改变 state 原始数据的方法写在 mutation.JS 文件中, 可以使用常量替代 Mutation 事件类型, 用不用常量取决于你 -- 在需要多人协作的大型项目中, 这会很有帮助. 可以让你的代码合作者对整个 App 包含的 mutation 一目了然.
- // 使用常量, 这是 mutation-type.JS 文件
- export const ADD_CART = 'ADD_CART'
- export const REDUCE_CART = 'REDUCE_CART'
- // 这是 mutation.JS 文件
- import {
- ADD_CART,
- REDUCE_CART
- } from './mutation-types.js'
- export default {
- [ADD_CART] (state, id) {
- state.goods[id].num++
- state.totalNum++
- state.totalPrice += state.goods[id].price
- // console.log(state.totalPrice)
- },
- [REDUCE_CART] (state, id) {
- if (state.goods[id].num> 0) {
- state.goods[id].num--
- state.totalNum--
- state.totalPrice -= state.goods[id].price
- }
- }
- }
6. 对 state 数据派生出一些状态, 例如需要知道商品的个数
- const getters = {
- goods_obj: state => state.goods,
- goods_length: state => state.goods.length
- }
- export default getters
7. 使用 vuex, 获取数据, 方法.
- <template>
- <div class="hello">
- <ul class="shop_container">
- <li v-for="item in $store.state.goods" :key="item.id" class="shop_container_li">
- <div class="shop_img">
- <img :src="item.img" alt=""width="100%"height="100%"/>
- </div>
- <div class="shop_detail">
- <p>{{item.name}}</p>
- <p>{{item.hint}}</p>
- <p>¥{{item.price}}</p>
- <p>
- <span class="shop_reduce" @click="reduce_num(item.id)">-</span>
- <span class="shop_num">{{item.num}}</span>
- <span class="shop_add" @click="add_num(item.id)">+</span>
- </p>
- </div>
- </li>
- </ul>
- <div class="foot">
- <div class="total_price">
- <span > 合计:¥{{totalPrice}}</span>
- </div>
- <div class="total_num" :class="{payment: totalNum}">
- <span > 去结账:{{totalNum}}</span>
- </div>
- </div>
- </div>
- </template>
- <script>
- import {mapState, mapMutations, mapGetters} from 'vuex'
- export default {
- name: 'HelloWorld',
- data () {
- return {
- }
- },
- created () {
- // console.log(this.goods)
- // console.log(this.goods_obj)
- // console.log(this.goods_length)
- // console.log(this.$store.state.shop) // 模块化 Vuex 允许我们将 store 分割成模块 (module) 每个模块拥有自己的 state,mutation,action,getter,
- },
- computed: {
- ...mapState([
- // 获取 state 中的数据可以通过 mapState 辅助函数获取, 也可以直接获取 例: this.$store.state.goods
- 'goods', 'totalPrice', 'totalNum'
- ]),
- ...mapGetters([
- 'goods_obj', 'goods_length'
- ])
- },
- methods: {
- ...mapMutations([
- // 获取 mutation 中的方法可以通过 mapMutations 辅助函数获取, 也可以直接获取.
- 'ADD_CART'
- // 'REDUCE_CART'
- ]),
- reduce_num (id) {
- // this.REDUCE_CART(id)
- this.$store.commit('REDUCE_CART', id) // 也可以直接获取
- },
- add_num (id) {
- this.ADD_CART(id) // 通过 mapMutations 辅助函数获取
- }
- }
- }
- </script>
8. 假如数据过多, 复杂, 可以进行模块化来开发, 可以将上述的 state,mutation,action 等可以同时写在 shop.JS 文件中, 此时 shop 就是一个模块了.
总结
若数据不是很多, 也不复杂, 我们也可以在构造 vue 实例 data 中存放我们所需要的共用数据. 一旦数据较多, 复杂, vuex 是一个非常不错的选择, 对于状态管理.
努力学习中, 希望能和大神一起.
GitHub 地址: https://github.com/flym1013/vuexDemo
效果预览地址: https://flym1013.github.io/vuexDemoBuild/
效果图预览
这里写图片描述
来源: http://www.jianshu.com/p/1c7a0b3266c3