vuex的作用:在多个组件之间共享状态
-
应用场景
- 多个界面之间的共享问题
- 用户登录状态,用户名,头像,地理位置等
- 商品的收藏,购物车
- 下载
npm install vuex --save
- 使用:
-
在src文件夹下创建
store文件夹,内置index.js文件 -
index.js文件:-
import Vuex from 'vuex'; //将vuex挂在到vue的原型上 Vue.use(Vuex); //创建对象 const store = new Vuex.Store({ state: {//定义数据 }, mutations: { }, actions: { }, getters: { }, modules: { } }) //导出store export { store }
-
-
main.js文件中挂载-
import {store} from './store/index' new Vue({ el: '#app', store, components: { App }, template: '<App/>' })
-
-
常量
- 在store文件中新建一个mutations-types.js的文件
const GlobalCount = 'globalCount'; const GlobalObj = 'globalObj'; const GlobalArr = 'globalArr'; const ADD = 'add'; const AddPeople = 'addPeople'; const GlobalCountPower = 'globalCountPower'; const GlobalArrFilter = 'globalArrFilter'; const ChangeName = 'changeName'; const AsynChangeName = 'asynChangeName'; export{ GlobalCount, GlobalObj, GlobalArr, ADD, AddPeople, GlobalCountPower, GlobalArrFilter, ChangeName, AsynChangeName } - 在
store文件中的index.jsimport Vue from 'vue'; import Vuex from 'vuex'; //将vuex挂在到vue的原型上 Vue.use(Vuex); import { GlobalCount, GlobalObj, GlobalArr, ADD, AddPeople, GlobalCountPower, GlobalArrFilter, ChangeName, AsynChangeName } from './mutations-types'; //创建对象 const store = new Vuex.Store({ state: { [GlobalCount]: 999, [GlobalObj]: { name: '张三', age: 12 }, [GlobalArr]: [{ name: '李四', age: 16 }, { name: '王五', age: 20 }, { name: '赵六', age: 30 } ] }, mutations: { [ADD](state) { state[GlobalCount]++; }, [AddPeople](state, Payload) { console.log(Payload) //传参方式一的参数格式:{name: "新人", age: 1} console.log(Payload) //传参方式二的参数格式:{type: "addPeople", name: "新人", age: 1} state[GlobalArr].push(Payload) }, [ChangeName](state,Payload){ state[GlobalObj].name=Payload; } }, actions: {//只要是修改state中的值,一步操作都必须在这里面完成,不能再调用组件中编写异步操作 [AsynChangeName](context,Payload){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ context.commit(ChangeName,Payload.name); resolve('成功了') },2000) }) } }, getters: { [GlobalCountPower](state) { return state[GlobalCount] * state[GlobalCount]; }, [GlobalArrFilter](state, getters) { return function (age) { return state[GlobalArr].filter(item => { return item.age > age }) } } }, modules: { } }) //导出store export { store } - 在组件中使用
<template> <div id="app"> <h1>vuex学习</h1> <p>{{customName3}}</p> <p>{{customName}}</p> <p>{{customName2}}</p> <p>{{customName1(20)}}</p> <button @click='addCount'>++</button> <button @click='addPeople({ "name":"新人", "age":1 })'>+人</button> <button @click='changeName'>一步操作:改名字</button> </div> </template> <script> import { mapState, mapGetters, mapMutations, mapActions } from "vuex"; import {GlobalCount, GlobalObj, GlobalArr, ADD, AddPeople, GlobalCountPower, GlobalArrFilter, ChangeName, AsynChangeName } from './store/mutations-types'; export default { name: "App", data() { return { count: 0 }; }, computed: { ...mapState({ customName:GlobalCount, customName2:GlobalArr, customName3: GlobalObj }), ...mapGetters({ customName1:GlobalArrFilter }) }, methods: { // addCount(){ // this.$store.commit('add') // }, ...mapMutations({ addCount:ADD, addPeople:AddPeople//这种带参数的提交会默认将addPeople的参数穿进去 }), // addPeople(){//传参方式一 // this.$store.commit('addPeople',{ // name:'新人', // age:1 // }) // }, // addPeople(){//传参方式二 // this.$store.commit({ // type:'addPeople', // name:'新人', // age:1 // }) // } changeName() { this.$store.dispatch(AsynChangeName, { name: "新名字" }).then(res=>{ console.log(res) }) } } }; </script>
参数详解
state- 在
store文件中的index.js中定义state:作用:定义需要共享的数据state: { globalCount: 999, studentArr: [{ name: '肖宝成', age: 25 }, { name: '王亚婷', age: 24 } ] } - 在组件中使用
<template> <div id="app"> <h1>vuex学习</h1> <p>{{changeMsg}}</p> <p>{{custom1}}</p> <p>{{custom2}}</p> </div> </template> <script> import { mapState } from 'vuex' export default{ computed: {//利用计算属性简化调用 changeMsg() { return this.$store.state[state中对应的数据[key]] return this.$store.state.globalCount; }, ...mapGetters({ [自定义名称]: "[state中对应的数据[key]]", customName1:"globalCount", customName2:"studentArr", [自定义名称](){ return this.$store.state[state中对应的数据[key]] + this[组件中对应的局部数据]; return this.$store.state[GlobalCount] + this.count; } }) } } </script>
- 在
getters- 在
store文件中的index.js中定义getters:作用对state中的数据进行处理getters: { power(state) {//接受一个参数 return state.globalCount * state.globalCount }, filterAge(state) {//接受一个参数 return state.studentArr.filter(item => { return item.age > 24 }) }, filterAgeLength(state,getters){//接受两个参数 return getters.filterAge.length }, filterAgeParams(state){//接受一个参数 return function(params){//接受组件中的传参 return state.studentArr.filter(item => { return item.age > params }) } } } - 在组件中使用
<template> <div id="app"> <h1>vuex学习</h1> <p>{{changeMsg}}</p> <p>{{changeMsg1}}</p> <p>{{custom1}}</p> <p>{{custom2}}</p> <p>{{custom3}}</p> <p>{{custom4(20)}}</p> </div> </template> <script> import { mapGetters } from 'vuex' export default{ changeMsg() { return this.$store.getters[getters中对应的数据[key]] return this.$store.getters.power; }, changeMsg1() { return this.$store.getters[getters中对应的函数名称]('有参数传参') return this.$store.getters.filterAgeParams(24); }, ...mapGetters({ [自定义名称]: "[getters中对应的函数名称]" custom1: "power", custom2:"filterAge", custom3:"filterAgeLength", custom4:"filterAgeParams" }) } </script>
- 在
mutations:中不能处理异步操作,切记!mutations:用于操作state中的数据mutations: { add(state) {//不传参 state.globalCount+=speed; }, reduce(state) {//不传参 state.globalCount-=speed; }, addPeople(state,obj){//传参 方法一传参打印obj==>{name: "张三", age: 12} 方法二传参打印obj==>{type: "addPeople", name: "张三", age: 12} state.studentArr.push(obj) } }- 在组件中使用
<template> <div id="app"> <h1>vuex学习</h1> <p>{{customName}}</p> <p>{{customName2}}</p> <button @click='addCount'>++</button> <button @click='addPeople({ "name":"新人", "age":1 })'>+人</button> </div> </template> <script> import { mapState,mapGetters,mapMutations } from "vuex"; export default { name: "App", computed: { ...mapState({ customName:'globalCount', customName2:'globalArr' }), ...mapGetters({ customName1:'globalArrFilter' }) }, methods: { // addCount(){ // this.$store.commit('add') // }, ...mapMutations({ addCount:'add', addPeople:'addPeople'//这种带参数的提交会默认将addPeople的参数穿进去 }), // addPeople(){//传参方式一 // this.$store.commit('addPeople',{ // name:'新人', // age:1 // }) // }, // addPeople(){//传参方式二 // this.$store.commit({ // type:'addPeople', // name:'新人', // age:1 // }) // } } }; </script>
- actions
- actions:用于操作state中的数据:一步操作,不能再调用的组件中进行异步操作,必须在这里
import { AsynChangeName } from ".mutations-types"; actions: {//只要是修改state中的值,一步操作都必须在这里面完成,不能再调用组件中编写异步操作 [AsynChangeName](context,Payload){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ context.commit(ChangeName,Payload.name); resolve('成功了') },2000) }) } } - 在组件中使用
<template> <button @click='changeName({ name:"新名字" })'>一步操作:改名字</button> <template/> <script> import { mapActions } from "vuex"; import { AsynChangeName } from "./store/mutations-types"; export default{ ...mapActions({//默认会携带changeName('传参') changeName: AsynChangeName }), // changeName(obj) { // this.$store // .dispatch(AsynChangeName,obj) // .then(res => { // console.log(res); // }); // } } </script>
- actions:用于操作state中的数据:一步操作,不能再调用的组件中进行异步操作,必须在这里