Vuex基本使用

1、安装Vuex

命令行输入:npm i vuex@3

注意:默认安装的是Vuex 4版本,适用与Vue 3,而Vuex 3版本适用于Vue 2,所以安装的时候要注意指定安装版本号

2、创建store

目前有两种方式:

1)创建vuex文件夹,然后在文件夹里面创建store.js

2)创建store文件夹,然后在文件夹里面创建index.js

目前开发中,两种方式都比较常用,官方介绍的是第二种。

3、在js文件中,定义actions、mutations、state对象,创建Vuex实例对象,并配置参数

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

//用于响应组件的动作
const actions = {}
//用于操作数据
const mutations = {}
//用于保存数据
const state = {}

export default new Vuex.Store({
    actions,
    mutations,
    state
})

4、在入口文件中(main.js)中,引用store,并配置Vue实例参数

import Vue from 'vue'
import App from './App.vue'
import store from './store'

Vue.config.productionTip = false

const vm = new Vue({
  store,
  render: h => h(App),
}).$mount('#app')
console.log(vm)

5、实际使用案例

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

//用于响应组件的动作
const actions = {
    addStaff(context,staff){
        let name = staff.name
        let salary = staff.salary
        if(name.trim() == '' || name.length > 4){
            // console.log('姓名不合法')
            return 301
        }
        if(isNaN(+salary)){
            // console.log('工资输入不合法')
            return 401
        }
        context.commit('ADD_STAFF',staff)
        return 200
    }
}
//用于操作数据
const mutations = {
    ADD_STAFF(state,staff){
        state.persons.unshift(staff)
    },
    ADD_ITEM(state,item){
        state.items.unshift(item)
        // console.log(state.items)
    }
}
//用于保存数据
const state = {
    persons:[],
    items:[]
}
export default new Vuex.Store({
    actions,
    mutations,
    state
})

1)组件中读取vuex数据:$store.state.items

2)组件中修改vuex数据:$store.dispatch('actions中的方法名',数据)或者$store.commit('mutations中的方法名',数据)

备注:若没有网络请求或者其他业务逻辑,可以直接跳过actions,可以不写dispatch,直接编写commit

问题:

    1. 为什么业务逻辑不写在组件中,而是写在Vuex的actions方法中?

为了复用,比如在实际工作当中,我们要创建一个订单,这时候需要判断用户是否登录,商品库存是否满足购买需求等等,如果写在组件中,那么在多个需要创建订单的页面中,都要写判断逻辑,而且一旦需要修改逻辑,那么所有组件都要更改,而写在actions方法中,就不存在上述问题

    1. actions方法中,第一个参数上下文中,为什么不只包含commit,反而要包含dispatch等其他

如果只包含commit方法,那么就没办法拿到state中的数据进行使用,也没有办法调用其他的dispatch方法进行业务逻辑判断,在实际工作当中,经常会把业务逻辑单独封装,以实现公用

    1. 为什么不在actions方法中进行对state数据的操作?

因为如果在actions方法中进行对state数据的操作,Vuex开发工具监测不到

Vuex核心特性

1、getters的使用:
○概念:当state中的数据需要经过加工后在使用时,可以使用getters进行加工(类似于计算属性computed)。并不是强制要求必须使用getters,比如仅在单个组件中需要对数据加工,完全可以使用computed,但是当多个组件功能都使用加工后的数据时,可以采用getters加工复用。
○在js中追加getters配置,示例代码:

  • 在js中追加getters配置,示例代码:
const getters = {
    nums(){
        return state.persons.length
    },
    total(){
        return state.persons.reduce((sum,item) => sum + item.salary,0)
    },
    totalPay(){
        return state.items.filter(item => item.type==0).reduce((sum,item) => sum + item.amount,0)
    },
    totalIncome(){
        return state.items.filter(item => item.type==1).reduce((sum,item) => sum + item.amount,0)
    }
}

export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})
    • 组件中读取getters数据:$store.getters.totalPay

2、四个map方法的使用

1)mapState方法,用于帮助我们映射state中数据为计算属性

  	computed:{
        //mapState的对象写法
        ...mapState({'list':'persons'}),
        //等同于
        list(){
            return this.$store.state.persons
        }
    }
  	computed:{
        //mapState的数组写法
        ...mapState(['persons']),
        //等同于
        persons(){
            return this.$store.state.persons
        }
    }

2)mapGetters方法,用于帮助我们将getters中数据为计算属性

  	computed:{
        //mapGetters的对象写法
        ...mapGetters({'income':'totalIncome'}),
        //等同于
        income(){
            return this.$store.getters.totalIncome
        }
    }
  	computed:{
        //mapGetters的数组写法
        ...mapState(['totalIncome']),
        //等同于
        totalIncome(){
            return this.$store.getters.totalIncome
        }
    }

3)mapActions方法,用于帮助我们生成与actions对应的方法,即:包含$store.dispatch(xxx)的函数

  	methods:{
        //原始写法
        /* average(){
            this.$store.dispatch('average')
        } */
        //使用mapActions对象写法
        // ...mapActions({average:'average'})
        //使用mapActions数组写法
        ...mapActions(['average'])
    }

4)mapMutations方法,用于帮助我们生成与mutations对应的方法,即:包含$store.commit(xxx)的函数

  	methods:{
        //原始写法
        /* ADD_AVERAGE(){
            this.$store.commit('ADD_AVERAGE')
        } */
        //使用mapMutations对象写法
        // ...mapMutations({ADD_AVERAGE:'ADD_AVERAGE'})
        //使用mapMutations数组写法
        ...mapMutations(['ADD_AVERAGE']),
    }

3、模块化+命名空间

1)目的:让代码更好维护,让多种数据分类更加清晰

2)使用:

  • 按照一定规则将数据分别定义在不同的js文件中,注意:namespaced属性要设置为true
export default {
    namespaced:true,
    actions:{
        addStaff(context,staff){
            let name = staff.name
            let salary = staff.salary
            if(name.trim() == '' || name.length > 4){
                // console.log('姓名不合法')
                return 301
            }
            if(isNaN(+salary)){
                // console.log('工资输入不合法')
                return 401
            }
            context.commit('ADD_STAFF',staff)
            return 200
        },
        average(context){
            let salary = (context.getters.total / context.getters.nums).toFixed(2)
            // console.log(salary)
            context.commit('AVERAGE',salary)
        }
    },
    mutations:{
        ADD_STAFF(state,staff){
            state.persons.unshift(staff)
        },
        AVERAGE(state,salary){
            state.wage = salary
        },
        ADD_AVERAGE(state){
            state.wage = +state.wage + 100
        }
    },
    state:{
        persons:[],
        wage:''
    },
    getters:{
        nums(state){
            return state.persons.length
        },
        total(state){
            return state.persons.reduce((sum,item) => sum + item.salary,0)
        },
    }
}
      • 在store.js文件中,引用定义好的文件,并通过modules属性进行加载
import Vue from 'vue'
import Vuex from 'vuex'
import persons from './persons'
import accounts from './accounts'
Vue.use(Vuex)

export default new Vuex.Store({
    modules:{
        personOption:persons,
        accountOption:accounts
    }
})
      • 开启命名空间后,读取state数据
  • 方式一:直接读取 $store.state.accountOption(命名空间名称).items
    • 方式二:借助mapState读取 ...mapState('personOption',['persons','wage'])
  • 开启命名空间后,读取getters数据
  • 方式一:直接读取 $store.getters['accountOption(命名空间名称)/totalPay(getters方法名)']
    • 方式二:借助mapGetters读取 ...mapGetters('personOption',['nums','total'])
  • 开启命名空间后,组件中调用dispatch
  • 方式一:直接调用 $store.dispatch('personOption/addStaff',obj)
    • 方式二:借助mapActions调用 ...mapActions('personOption',['average'])

Element-ui:npm i element-ui -S

如何配置element-ui

import ElementUI from 'element-ui'

import locale from 'element-ui/lib/locale/lang/en'

Vue.use(ElementUI, { locale })

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值