Vuex

Posted 库里不会投三分

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vuex相关的知识,希望对你有一定的参考价值。

文章目录

Vuex简介

Vuex是什么

  1. 概念:专门在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 vue 应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信
  2. Vuex Github地址

什么时候使用Vuex

  1. 多个组件依赖于同一状态
  2. 来自不同组件的行为需要变更同一状态

多个组件依赖于同一个状态(变量),或者来自不同组件的行为需要变更同一个状态(其实就是多个不同组件的读写),最好应用vuex!

Vuex工作原理

对下图的解释:

  • store(其实就是上图Vuex):Actions,Mutations,State的父亲,它们三个之间的状态转换(灰色箭头的api)由store提供(store.dispatch,store.commit等等)

  • Actions:一个普普通通的Object类型对象,vc的改变会先通过store.dispatch()将值传递给action。然后经由action通过store.commit()发送给Mutations。

    • Actions还可以通过ajax和后端交互,就是下图中的Backend API,通过后端接口拿数据,也是组装到Action中

    • 如果不调用Backend API,VC可以直接将数据交给Mutations,绕开Actions。也就是说Actions是可以跳过的

      • 类似生活,Actions类似我们的服务员,Mutations类似我们的厨师,Vue Components就是我们的客户,我们点菜时,可以通过服务员去点菜,如果我们熟悉菜品,也可以不需要服务员的帮助,直接让厨师做
      • 但是如果我们不了解菜品,就肯定需要服务员的帮助,如果我们需要后端接口的数据,就类似需要服务员的帮助,就必须有Actions的介入
  • Mutations(n. 突变,变更):它是一个Object类型的对象。负责真正处理,加工修改数据,处理完成后将处理完成的数据传入State中

  • Vue的开发工具,Devtools,监测的就是Mutations里的数据

  • State:也是一个Object类型的对象,vuex会将里面的数据进行渲染,还给VC,更新VC

Vuex环境搭建

下载vuex

  • 你在vue2的项目中,只能安装vue3版本
  • 你在vue3的项目中,只能安装vue4版本
  • 所以这里安装vue3:npm i vuex@3

创建src/store/index.js

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
   
//准备actions对象——响应组件中用户的动作、处理业务逻辑
const actions = 
//准备mutations对象——修改state中的数据
const mutations = 
//准备state对象——保存具体的数据
const state = 
   
//创建并暴露store
export default new Vuex.Store(
   	actions,
   	mutations,
   	state
)

  • 根据上面的工作原理,store中应该至少包含 actions,mutations,state这三个东西,然后将这三个东西塞入new出来的store中,最后再暴露store:
  • 这里注意Vue.use(Vuex),如果写在我们的main.js中,我们知道import引入文件的执行是先于我们本文件js代码的执行,所以会导致我们使用vuex时,并没有引入vuex

传入store配置项

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

Vue.config.productionTip = false

Vue.use(Vuex)

new Vue(
    el:"#app",
    render: h => h(App),
    store
)

  • src/main.js中创建 vm 时传入store配置项

    • import store from ‘./store’ 自动扫描store文件夹下的index.js文件
  • store是简写 ,完整写法是 store:store

求和案例

纯vue版本

App.vue

<template>
	<div class="container">
		<Count/>
	</div>
</template>

<script>
	import Count from './components/Count'
	export default 
		name:'App',
		components:Count
	
</script>

<template>
	<div>
		<h1>当前求和为:sum</h1>
		<select v-model.number="n">
			<option value="1">1</option>
			<option value="2">2</option>
			<option value="3">3</option>
		</select>
		<button @click="increment">+</button>
		<button @click="decrement">-</button>
		<button @click="incrementOdd">当前求和为奇数再加</button>
		<button @click="incrementWait">等一等再加</button>
	</div>
</template>

<script>
	export default 
		name:'Count',
		data() 
			return 
				n:1, //用户选择的数字
				sum:0 //当前的和
			
		,
		methods: 
			increment()
				this.sum += this.n
			,
			decrement()
				this.sum -= this.n
			,
			incrementOdd()
				if(this.sum % 2)
					this.sum += this.n
				
			,
			incrementWait()
				setTimeout(()=>
					this.sum += this.n
				,500)
			,
		,
	
</script>

<style>
	button
		margin-left: 5px;
	
</style>


  • 我们操作的sum在组件本身,所以直接操作就行

Vuex版本

Count.vue

<template>
	<div>
		<h1>当前求和为:$store.state.sum</h1>
		<select v-model.number="n">
			<option value="1">1</option>
			<option value="2">2</option>
			<option value="3">3</option>
		</select>
		<button @click="increment">+</button>
		<button @click="decrement">-</button>
		<button @click="incrementOdd">当前求和为奇数再加</button>
		<button @click="incrementWait">等一等再加</button>
	</div>
</template>

<script>
	export default 
		name:'Count',
		data() 
			return 
				n:1, //用户选择的数字
			
		,
		methods: 
			increment()
				this.$store.commit('ADD',this.n)
			,
			decrement()
				this.$store.commit('SUBTRACT',this.n)
			,
			incrementOdd()
				this.$store.dispatch('addOdd',this.n)
			,
			incrementWait()
				this.$store.dispatch('addWait',this.n)
			,
		,
	
</script>

<style>
	button
		margin-left: 5px;
	
</style>

对应index.js编写

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
   
//准备actions对象——响应组件中用户的动作
const actions = 
    addOdd(context,value)
        console.log("actions中的addOdd被调用了")
        if(context.state.sum % 2)
            context.commit('ADD',value)
        
    ,
    addWait(context,value)
        console.log("actions中的addWait被调用了")
        setTimeout(()=>
			context.commit('ADD',value)
		,500)
    ,

//准备mutations对象——修改state中的数据
const mutations = 
    ADD(state,value)
        state.sum += value
    ,
    SUBTRACT(state,value)
        state.sum -= value
    

//准备state对象——保存具体的数据
const state = 
    sum:0 //当前的和

   
//创建并暴露store
export default new Vuex.Store(
    actions,
    mutations,
    state
)

总结:

Vuex的基本使用:

  • 初始化数据state,配置actions、mutations,操作文件store.js
//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//引用Vuex
Vue.use(Vuex)

const actions = 
    //响应组件中加的动作
	jia(context,value)
		// console.log('actions中的jia被调用了',miniStore,value)
		context.commit('JIA',value)
	,


const mutations = 
    //执行加
	JIA(state,value)
		// console.log('mutations中的JIA被调用了',state,value)
		state.sum += value
	


//初始化数据
const state = 
   sum:0


//创建并暴露store
export default new Vuex.Store(
	actions,
	mutations,
	state,
)
  • 组件中读取vuex中的数据:$store.state.sum
  • 组件中修改vuex中的数据:$store.dispatch(‘action中的方法名’,数据) 或 $store.commit(‘mutations中的方法名’,数据)
    • actions中的方法也进行$store.dispatch(‘action中的方法名’,数据)

备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接编写commit

  • 为什么业务逻辑写这里面,也是有对应可能对代码进行服用,如果都想实现同一个功能,如果在单独的组件中,在别的组件中想用,则需要又写

getters配置项

count.vue

<template>
	<div>
		<h1>当前求和为:$store.state.sum</h1>
		<h3>当前求和的10倍为:$store.getters.bigSum</h3>
		<select v-model.number="n">
			<option value="1">1</option>
			<option value="2">2</option>
			<option value="3">3</option>
		</select>
		<button @click="increment">+</button>
		<button @click="decrement">-</button>
		<button @click="incrementOdd">当前求和为奇数再加</button>
		<button @click="incrementWait">等一等再加</button>
	</div>
</template>

<script>
	export default 
		name:'Count',
		data() 
			return 
				n:1, //用户选择的数字
			
		,
		methods: 
			increment()
				this.$store.commit('ADD',this.n)
			,
			decrement()
				this.$store.commit('SUBTRACT',this.n)
			,
			incrementOdd()
				this.$store.dispatch('addOdd',this.n)
			,
			incrementWait()
				this.$store.dispatch('addWait',this.n)
			,
		,
	
</script>

<style>
	button
		margin-left: 5px;
	
</style>

index.js

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
   
//准备actions对象——响应组件中用户的动作
const actions = 
    addOdd(context,value)
        console.log("actions中的addOdd被调用了")
        if(context.state.sum % 2)
            context.commit('ADD',value)
        
    ,
    addWait(context,value)
        console.log("actions中的addWait被调用了")
        setTimeout(()=>
			context.commit('ADD',value)
		,500)
    ,

//准备mutations对象——修改state中的数据
const mutations = 
    ADD(state,value)
        state.sum += value
    ,
    SUBTRACT(state,value)
        state.sum -= value
    

//准备state对象——保存具体的数据
const state = 
    sum:0 //当前的和

//准备getters对象——用于将state中的数据进行加工
const getters = 
    bigSum()
        return state.sum * 10
    

   
//创建并暴露store
export default new Vuex.Store(
    actions,
    mutations,
    state,
    getters
)

总结:

getters配置项的使用:

概念:当state中的数据需要经过加工后再使用时,可以使用getters加工在store.js中追加getters配置

  • 非常类似我们data和计算属性的关系
const getters = 
	bigSum(state)
		return state.sum * 10
	


//创建并暴露store
export default new Vuex.Store(
	...
	getters
)
  • 组件中读取数据:$store.getters.bigSum

四个map方法的使用

mapState与mapGetters

想使用需要先引入import mapState,mapGetters from ‘vuex’

index.js

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
   
//准备actions对象——响应组件中用户的动作
const actions = 
    addOdd(context,value)
        console.log("actions中的addOdd被调用了")
        if(context.state.sum % 2)
            context.commit('ADD',value)
        
    ,
    addWait(context,value)
        console.log("actions中的addWait被调用了")
        setTimeout(()=>
			context.commit('ADD',value)
		,500)
    ,

//准备mutations对象——修改state中的数据
const mutations = 
    ADD(state,value)
        state.sum += value
    ,
    SUBTRACT(state,value)
        state.sum -= value
    

//准备state对象——保存具体的数据
const state = 
    sum:0, //当前的和
    name:'JOJO',
    school:'尚硅谷',

//准备getters对象——用于将state中的数据进行加工
const getters = 
    bigSum()
        return state.sum * 10
    

   
//创建并暴露store
export default new Vuex.Store(
    actions,
    mutations,
    state,
    getters
)

Count.vue

<template>
	<div>
		<h1>当前求和为:sum</h1>
		<h3>当前求和的10倍为:bigSum</h3>
		<h3>我是name,我在school学习</h3>
		<select v-model.number="n">
			<option value="1">1</option>
			<option value="2">2</option>
			<option value="3">3</option>
		</select>
		<button @click="increment">+</button>
		<button @click="decrement">-</button>
		<button @click="incrementOdd">当前求和为奇数再加</button>
		<button @click="incrementWait">等一等再加</button>
	</div>
</template>

<script>
	import mapState,mapGetters from 'vuex'

	export default 
		name:'Count',
		data() 
			return 
				n:1, //用户选择的数字
			
		,
		methods: 
			increment()
				this.$store.commit('ADD',this.n)
			,
			decrement()
				this.$store.commit('SUBTRACT',this.n)
			,
			incrementOdd()
				this.$store.dispatch('addOdd',this.n)
			,
			incrementWait()
				this.$store.dispatch('addWait',this.n)
			,
		,
		computed:		
			// 借助mapState生成计算属性(数组写法)
			// ...mapState(['sum','school','name']),
			// 借助mapState生成计算属性(对象写法)
			...mapState(sum:'sum',school:'school',name:'name'),

			...mapGetters(['bigSum'])
		
	
</script>

<style>
	button
		margin-left: 5px;
	
</style>

  • … 是ES6的格式,是将这个对象中的所有key:value展开放到当前这个对象中

总结:

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

computed: 
    //借助mapState生成计算属性:sum、school、subject(对象写法)
     ...mapState(sum:'sum',school:'school',subject:'subject'),      
	//借助mapState生成计算属性:sum、school、subject(数组写法)
	 ...mapState(['sum','school','subject']),

mapGetters方法:用于帮助我们映射getters中的数据为计算属性

computed: 
    //借助mapGetters生成计算属性:bigSum(对象写法)
    ...mapGetters(bigSum:'bigSum'),

	//借助mapGetters生成计算属性:bigSum(数组写法)
	...mapGetters(['bigSum'])
,
  • 数组写法需要我们的计算属性名和我们的state中对象的属性名相同

mapActions与mapMutations

想使用先引入import mapMutations,mapActions from ‘vuex’

<template>
	<div>
		<h1>当前求和为:sum</h1>
		<h3>当前求和的10倍为:bigSum</h3>
		<h3>我是name,我在school学习</h3>
		<select v-model.number="n">
			<option value="1">1</option>
			<option value="2">2</option>
			<option value="3">3</option>
		</select>
		<button @click="increment(n)">+</button>
		<button @click="decrement(n)">-</button>
		<button @click="incrementOdd(n)">当前求和为奇数再加</button>
		<button @click="incrementWait(n)">等一等再加</button>
	</div>
</template>

<script>
	import mapState,mapGetters,mapMutations,mapActions from 'vuex'

	export default 
		name:'Count',
		data() 
			return 
				n:1, //用户选择的数字
			
		,
		methods: 
			// 借助mapActions生成:increment、decrement(对象形式)
			...mapMutations(increment:'ADD',decrement:'SUBTRACT'),

			// 借助mapActions生成:incrementOdd、incrementWait(对象形式)
			...mapActions(incrementOdd:'addOdd',incrementWait:'addWait')
		,
		computed:		
			// 借助mapState生成计算属性(数组写法)
			// ...mapState(['sum','school','name']),
			// 借助mapState生成计算属性(对象写法)
			...mapState(sum:'sum',school:'school',name:'name'),

			...mapGetters(['bigSum'])
		
	
</script>

<style>
	button
		margin-left: 5px;
	
</style>

总结:

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

methods:
    //靠mapActions生成:incrementOdd、incrementWait(对象形式)
    ...mapActions(incrementOdd:'jiaOdd',incrementWait:'jiaWait')

    //靠mapActions生成:incrementOdd、incrementWait(数组形式)
    ...mapActions(['jiaOdd','jiaWait'])

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

methods:
    //靠mapActions生成:increment、decrement(对象形式)
    ...mapMutations(increment:'JIA',decrement:'JIAN'),
    

    //靠mapMutations生成:JIA、JIAN(对象形式)
    ...mapMutations(['JIA','JIAN']),


备注:mapActions与mapMutations使用时,若需要传递参数,则需要在模板中绑定事件时传递好参数,否则参数是事件对象

多组件共享数据

count.vue

<template>
	<div>
		<h1>当前求和为:sum</h1>
		<h3>当前求和的10倍为:bigSum</h3>
		<h3>我是name,我在school学习</h3>
		<h3 style="color:red">Person组件的总人数是:personList.length</h3>
		<select v-model.number="n">
			<option value="1">1</option>
			<option value="2">2</option>
			<option value="3">3</option>
		</select>
		<button @click="increment(n)">+</button>
		<button @click="decrement(n)">-</button>
		<button @click="incrementOdd(n)">当前求和为奇数再加</button>
		<button @click="incrementWait(n)">等一等再加</button>
	</div>
</template>

<script>
	import mapState,mapGetters,mapMutations,mapActions from 'vuex'

	export default 
		name:'Count',
		data() 
			return 
				n:1, //用户选择的数字
			
		,
		methods: 
			...mapMutations(increment:'ADD',decrement:'SUBTRACT'),
			...mapActions(incrementOdd:'addOdd',incrementWait:'addWait')
		,
		computed:
			...mapState(['sum','school','name','personList']),
			...mapGetters(['bigSum'])
		
	
</script>

<style>
	button
		margin-left: 5px;
	
</style>

Person.vue

<template>
	<div>
		<h1>人员列表</h1>
		<h3 style="color:red">Count组件求和为:sum</h3>
		<input type="text" placeholder="请输入名字" v-model="name">
		<button @click="add">添加</button>
		<ul>
			<li v-for="p in personList" :key="p.id">p.name</li>
		</ul>
	</div>
</template>

<script>
	import nanoid from 'nanoid'
	export default 
		name:'Person',
		data() 
			return 
				name:''
			
		,
		computed:
			personList()
				return this.$store.state.personList
			,
			sum()
				return this.$store.state.sum
			
		,
		methods: 
			add()
				const personObj = id:nanoid(),name:this.name
				this.$store.commit('ADD_PERSON',personObj)
				this.name = ''
			
		
	
</script>

index.js

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
   
//准备actions对象——响应组件中用户的动作
const actions = 
    addOdd(context,value)
        console.log("actions中的addOdd被调用了")
        if(context.state.sum % 2)
            context.commit('ADD',value)
        
    ,
    addWait(context,value)
        console.log("actions中的addWait被调用了")
        setTimeout(()=>
			context.commit('ADD',value)
		,500)
    ,

//准备mutations对象——修改state中的数据
const mutations = 
    ADD(state,value)
        state.sum += value
    ,
    SUBTRACT(state,value)
        state.sum -= value
    ,
	ADD_PERSON(state,value)

vuex

 


  1. 下载 vuex
  • vue init webpack vue-vuex 创建vuex项目
  • cnpm install 安装依赖
  • cnpm install vuex --save 安装vuex包

  1. 引入vuex
  • import Vuex from ‘vuex‘ 引入vuex插件
  • Vue.use(Vuex) 使用vuex插件

  1. 使用
  • 在scr文件夹下 --> 新建store文件夹 --> 新建index.js文件
  • import Vue from ‘vue‘
  • import Vuex from ‘vuex‘
  • Vue.use(Vuex)
  • export default new Vuex.Store({ }) 暴露出一根vuex对象
  • import store from ‘./store‘ 必须在main.js中引入store,系统会自动寻找index.js文件
  • 在main.js中的 new vue({store})实例中加入store

  1. export default new Vuex.Store({ });store的构成
  • state 状态(数据)
  • mutations 定义方法,(同步的)改变 state 中的值
  • actions 行为,(异步的)触发 mutations 中的事件,从而改变 state 的值
  • getters 在state基础上派生出来的值
  • modules 模块(state的缩小版)

(1)STATE

  • this.$store.state.val

在main.js引入store并且在new Vue({})实例中添加store后,在全局都可以调用store

eg:

  • 在index中引入vuex、store
    import Vue from ‘vue‘
    import Vuex from ‘vuex‘
    Vue.use(Vuex)
    
    const state = {  // 
        val: ‘1234‘
    }
    
    export default new Vuex.Store({
        state
    })

 

  • 在子组件中调用store中的state
    <template>
        <div>
            <div>组件D --> 接收B数据 {{value}}</div>
        </div>
    </template>
    
    <script>
    export default {
        computed: {
            value() {
                return this.$store.state.val  // 调用store中的state
            }
        }
    }
    </script>

 

(1.2) mapMutations 辅助函数

  • 通过mapMutations来获得state的值
    <template>
        <div>
            <div>组件D --> 接收state数据 {{value}}</div>
        </div>
    </template>
    
    <script>
    import {mapState} from ‘Vuex‘
    export default {
        computed: {
            ...mapState({
                value: state => state.val
            })
        }
    }
    </script>

 


(2)MUTATION改变store中状态的唯一方法

  • 通过 commit 来触发 mutation 中定义的函数
  • 注意 mutation 中只能定义同步函数
  • this.$store.commit(‘setVal‘,value)

eg:

  • 在index.js中定义setVal方法
    import Vue from ‘vue‘
    import Vuex from ‘vuex‘
    Vue.use(Vuex)
    
    // console.log(Vuex)
    const state = {
        val: ‘1234‘
    }
    const mutations = {
        setVal(state,value) {
            state.val = value;
        }
    }
    
    export default new Vuex.Store({
        state,
        mutations
    })

 

  • 在组件中调用setVal方法,改变state的数据
    <template>
        <div>
            <div>组件E数据{{value}}</div>
            <input type="text" v-model=‘value‘>
        </div>
    </template>
    <script>
    export default {
        data() {
            return {
                value:‘‘
            }
        },
        watch: {
            value() {
                this.$store.commit(‘setVal‘,this.value) // 通过commit触发setVal来改变state的数据
            }
        }
    }
    </script>

 

**(2.2)**mapMutations 辅助函数

  • 通过mapMutations来获取mutations中的方法
    <template>
        <div>
            <div>组件E数据{{value}}</div>
            <input type="text" v-model=‘value‘>
        </div>
    </template>
    <script>
    import {mapMutations} from ‘vuex‘
    export default {
        data() {
            return {
                value:‘‘
            }
        },
        methods: {
            ...mapMutations([‘setVal‘])
        },
        watch: {
            value() {
                this.setVal(this.value)
            }
        }
    }
    </script>

 

  • 如果想给函数起个别名
    methods: {
        ...mapMutations({
            setValue: ‘setVal‘
        })
    }

 


(3)ACTIONS 通过异步的触发mutation中的函数来改变state中的值

  • 通过dispatch来触发actions
  • this.$store.dispatch(‘asynSetValue‘,value)

eg:

    import Vue from ‘vue‘
    import Vuex from ‘vuex‘
    Vue.use(Vuex)
    
    const state = {
        val: ‘1234‘
    }
    const mutations = {
        setVal(state,value) {
            state.val = value;
        }
    }
    const actions = {
        asynSetValue(ctx,value) { // ctx
            setTimeout(function () {
                ctx.commit(‘setVal‘,value)  // ctx可以看作为store的镜像
            }, Math.random()*500)
        }
    }
    
    export default new Vuex.Store({
        state,
        mutations,
        actions
    })
    <template>
        <div>
            <div>组件E数据{{value}}</div>
            <input type="text" v-model=‘value‘>
        </div>
    </template>
    <script>
    export default {
        data() {
            return {
                value:‘‘
            }
        },
        watch: {
            value() {
                this.$store.dispatch(‘asynSetValue‘,this.value)
            }
        }
    }
    </script>

 

  • 解构的方式
    const actions = {
        asynSetValue({commit},value) { // ctx
            setTimeout(function () {
                commit(‘setVal‘,value)
            }, Math.random()*500)
        }
    }

 


(4)GETTERS

  • 对state的值进行处理
  • 取派生值 this.$store.getters.newVal
    import Vue from ‘vue‘
    import Vuex from ‘vuex‘
    Vue.use(Vuex)
    
    const state = {
        val: ‘1234‘
    }
    const mutations = {
        setVal(state,value) {
            state.val = value;
        }
    }
    const getters = {
        newVal(state) {
            return state.val.split(‘‘).join(‘,‘)
        }
    }
    
    export default new Vuex.Store({
        state,
        mutations,
        getters
    })
    <template>
        <div class="wrapper">
            <div>{{value}}</div>
        </div>
    </template>
    <script>
    export default {
        components: {
            componentE
        },
        computed: {
            value() {
                return this.$store.getters.newVal
            }
        }
    }
    </script>

 

(4.1) mapGetters 辅助函数

  • 获取getters
    <template>
        <div class="wrapper">
            <div>组件C --> 接收getter数据 {{newVal}}</div>
            <component-e></component-e>
        </div>
    </template>
    <script>
    import componentE from ‘./componentE‘
    import {mapGetters} from ‘Vuex‘
    export default {
        components: {
            componentE
        },
        computed: {
            ...mapGetters([‘newVal‘])
        }
    }
    </script>

 


使用vuex

1. 部署Vuex

  • 在 src 文件夹中新建 store 文件夹,新建 index.js 文件
  • import Vue from ‘vue‘
  • import Vuex from ‘vuex‘
  • Vue.use(Vuex)
  • 在 main.js 中引入 store (import store from ‘./store‘)
  • 在 vue 实例中加入 store

2. Vuex.Store 的构成

export default new Vuex.Store({ <br>
    state, ==》 数据    <br> 
    mutations,  ==》 定义方法,(同步的)改变 state 中的值 <br>
    actions,    ==》行为,(异步的)触发 mutations 中的事件,从而改变 state 的值 <br>
    getters,    ==》 派生值, <br>
    modules: {    ==》 模块 <br>
        a: { <br>
            state, <br>
            mutations, <br>
            actions, <br>
            getters, <br>
            modules <br>
        } <br>
    } <br>
})

 


state

1. 在组件中获得 Vuex 状态 store.state

在组件中,通过 this.$store.state 获得数据
先要在 index.js 中声明一个 state
    const state = {
        val:‘1234‘   
    }
    computed: {
        val() {
            console.log(this.$store)
            return this.$store.state.val
        }
    }

 

mutation (将值放入到 state 中)

  • 改变 store 中的状态的唯一方法 mutation
  • 通过 commit 来触发 mutation 中定义的函数
  • 注意 mutation 中只能定义同步函数
  • 辅助函数 mapMutations
先定义 mutations 函数
    const mutations = {
        setVal(state, value) {
            state.val = value;
        }
    }

 

在监听函数中
    watch:{
        value(){
            this.$store.commit(‘setVal‘,this.value)
        }
    }

 

actions 异步触发 mutation

ctx 可以看成是 store 的镜像,但又不完全一样

    const actions = {
        asynSetValue(ctx, value) {
            setTimeout(()=>{
                ctx.commit(‘setVal‘,value)
            }, Math.random() * 3000)
        }
    }
    watch:{
        value(){
            this.$store.dispatch(‘asynSetValue‘,this.value)
        }
    }

 


getters 派生值

方法定义
   const getters = {
        newVal(state) {
            return state.val.split(‘‘).join(‘,‘)
        }
    }

 

输出
  computed:{
        value() {
            return this.$store.getters.newVal
        }
    }

 

取值
    watch:{
        value(){
            this.$store.commit(‘setVal‘,this.value)
        }
    }

 


取值: this.$store.state.val

取派生值: this.$store.getters.newVal

触发commit方法来触发setVal函数: this.$store.commit(‘setVal‘,value)

触发dispatch方法来触发asynSetValue函数: this.$store.dispatch(‘asynSetValue‘,value)

mapState,mapMutations,mapActions,mapGetters 这4中方法对应了上面4中扩展形式


mapState 辅助函数

  • 获取 state 的一种方式

使用之前要在组件中先引入

    import {mapState} from ‘Vuex‘ // 解构的方式引入
    computed: {
        ...mapState({
            val: state => state.val
        })
    }

 

  • 上面的 val 是在 index.js 中定义好的
    const state = {
        val:‘1234‘   
    }

 


mapMutations

在组件中引入

    import {mapMutations} from ‘vuex‘
    methods:{
        ...mapMutations([‘setVal‘])
    },
    watch:{
        value(){
            this.setVal(this.value)
        }
    }

 

mapGetters

  • 引入
import {mapGetters} from ‘vuex‘

    computed:{
        ...mapGetters({
            newV:‘newVal‘
        })
    }

 


modules

    modules: {
        map: {
            namespaced: true,
            state: {
                title: ‘地图‘,
                url: ‘map.baidu.com‘
            },
            mutations: {
                updateVal(state, val) {
                    console.log(‘map‘);
                    state.title = val
                }
            },
            actions: {
                _updateVal({commit}, val) {
                    commit(‘updateVal‘, val) // 这里默认触发的是当前的updateVal, 如果想要触发外面的updateVal需要加上{root:true}字段 commit(‘updateVal‘, val{root:true})
                }
            }
        },
        new: {
            state: {
                title: ‘新闻‘,
                url: ‘new.baidu.com‘
            }
        }
    }

 

在 modules 中定义的方法如果跟外面的同名,就会合并(低版本vue会报错);可以使用命名空间,

    methods: {
        ...mapMutations([‘updateVal‘]),
        ...mapActions(‘map‘,[‘_updateVal‘]) // 使用命名空间之后就要在方法前写上模块名
    }

 

以上是关于Vuex的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js高效前端开发知识 • 目录

Vue.js高效前端开发 • 初识Vue.js

Vue.js高效前端开发 • 初识Vue.js

前端开发之走进Vue.js

前端开发之走进Vue.js

前端框架:Vue.js 框架全面总结!目前最完整的前端框架你用过吗?