Vuex教程
一、概览
1、Vuex是什么
2、状态组件内部状态:仅在一个组件内使用的状态( 即data字段里的数据,不能共享,只在本组件使用 )应用级别状态:多个组件共用的状态(将这个状态放入vuex中进行管理)
3、什么情况下使用Vuex多个视图(组件)依赖同一状态来自不同视图(组件)的行为需要变更同一状态
二、Vuex核心概念
1、store:类似容器,包含应用的大部分状态
2、State:包含所有应用级别状态的对象
3、Getters:在组件内部获取store中状态的函数,类似组件的计算属性computed
4、Mutations:唯一修改状态的事件回调函数,默认是同步的,如果要异步就使用Actions
5、Actions:包含异步操作、提交mutations改变状态
6、Modules:将store分割成不同的模块
三、使用Vuex
1、安装Vuex模块npm install vuex --save2、作为插件使用import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)3、定义容器let store = new Vuex.Store({ state:{ count:100 }, mutations:{ //对象,里面是各种更改state状态值的函数,同步立即更改状态 add( state,payload ){ //参数state就是上面的state,payload是要传递的值 state.count+=payload.n; } }, actions:{ //异步更改状态,可以是ajax请求成功之后改变状态,这里用定时器模拟,1秒钟之后提交mutations改变状态 //异步的更改状态是直接在index.js里面的actions里面定义action然后commit的(附带参数),而不是在组件内提交,注意区别,异步是在组件内dispatch这个actions(actions里面已经包含了mutations),同步是在组件内commit这个mutations(附带参数) //异步也可以在index.js里面直接dispatch这个actions(附带参数),在第一个ajax里面接着请求第二个ajax addAction( context ){ //ajax1 setTimeout(function(){ context.commit('add',{n:200}); //这里用的mutations还是上面定义的add context.dispatch('textAction',{test:'测试'}) //触发ajax2 },1000) } textAction( context,obj ){ //ajax2 console.log(obj) } //利用es6解构赋值改写上面的代码,因为context对象下面有commit和dispatch方法 addAction( {commit,dispatch} ){ setTimeout(function(){ commit('add',{n:200}); //直接可以获取到commit方法,不用是context.commit dispatch('textAction',{test:'测试'}) },1000) } textAction( context,obj ){ //ajax2 console.log(obj) } },//异步更改状态,一段时间之后再改变状态,只要是异步的改变都写在actions里面 getters:{ //类似计算属性,对状态做进一步的处理 filterCount(state){ return state.count>=120?120:state.count++; } } })export default store4、注入根实例import store from './store'new Vue({ store})
5、在state里面定义的是状态,如果在组件内部要使用这个状态,那么一般在组件内部通过计算属性来得到它
<button @click="addHandle()"></button><p>{{count}}</p><p>{{count2}}</p>computed:{ count(){ return this.$store.state.count }, count2(){ return this.$store.getters.filterCount //被getters进一步处理过的状态 }},methods:{ addHandle(){ //要动态的改变状态,就需要显示的提交一个mutations —> add //同步,写法一 this.$store.commit('add',{n:10}) //同步,写法二 this.$store.commit({ type:'add', n:5 }) //异步,写法 this.$store.dispatch('addAction') }}
6、context是一个对象,不是state实例
7、使用辅助函数
import {mapState,mapGetters,mapActions,mapMutations} from 'vuex'//这是改写state和getterscomputed:{ num(){ return this.$store.state.count }, num2(){ return this.$store.getters.filterNum }}computed:mapState({ num:state => state.count num:'count' num(state){ return state.count+100 } count:'count' //此时渲染的是count,不是num})computed:{ abc(){ return 123 }, ...mapGetters({ num2:'filterCount' //如果key值(即要渲染到页面的变量值)和vuex里面定义的是一样的,那么就可以是下面那种写法 }), ...mapState(['count']) //count:count count是要渲染到页面 state:{count:100},state里面定义的状态名也是count}//这是改写actions和mutationsmethods:{ add(){ //异步actions this.$store.dispatch('addAction') }},reduce(){ //普通mutations,参数可以直接跟在对象里 this.$store.commit({ type:'reduceMutation', n:10 })}methods:{ ...mapActions({ add:'addAction' //add是页面点击函数,addAction是vuex里面定义的action }) ...mapMutations({ //这种方法要传参,只能是在调用的时候传进去 reduce:'reduceMutation' })}<input type="button" value="-" @click="reduce({n:10})"> 参数在这里传,和普通写法不同
四、案例
**index.js**let store = new Vuex.Store({ state:{ //对象,应用所需要的状态数据都放在这里面 count:100 }, mutations:{ //对象,显示的同步提交mutations,状态是点击之后立即改变 addIncrement(state,payload){ //这里是自定义addIncrement事件 state.count+ = payload.n } }, actions:{ //异步的改变状态,比如发送请求成功之后才改变状态,不是即时的改变 addAction( context ){ //这里新加自定义事件addAction setTimeout( ()=>{ /模拟异步操作 //改变状态,提交mutations,仍然是上面mutations里面定义的事件addIncrement context.commit('addIncrement',{n:15}) context.dispatch('textAction',{test:'测试'}) //这里执行该异步操作 },1000 ) }, textAction(context,obj){ //定义第二个异步操作 console.log(obj) //{test:'测试'} }, getListAction( context ){ //这里定义了异步接口action,在子组件created里面调用 axios.get('url') .then( (data)=>{ console.log(data); //得到了接口数据 } ) } }, getters:{ //对store里面的数值进行逻辑操作 filterState(state){ return state.count>=120?120:state.count } }})export default store**increment组件:**<template> <p>{{num}}</p> <span>{{filterNewNum}}</span> <input type="button" value="+" @click="addHandle" /></template><script> computed:{ num(){ rerurn this.$store.state.count //接收原始状态值 }, filterNewNum(){ //这里面接收过滤后的,仓库里面的数据 return this.$store.getters.filterState //注意是return,不要漏了 } }, methods:{ addHandle(){ //改变状态,提交一个mutations this.$store.commit('addIncrement',{ //这里是commit addIncrement n:5 //参数 }); } //这里是异步触发一个action,注意和上面同步的不同之处 this.$store.dispatch('addAction') //这里是dispatch addAction }, created(){ this.$store.dispatch('getListAction'); //dispatch } 也可以这样写: methods:{ addHandle(){ this.$store.commit({ type:'addIncrement', //改变的状态类型 n:5 //参数 }) } }</script>//上面是同步操作数据,使用mutations,如果要异步操作数据,就用到Actions,注意,不管是同步还是异步操作,改变数据前都得先提交mutations//向后端发送ajax请求就放在Actions里面。在methods里面创建方法,通过axios获取数据,然后更新到store里面定义的变量,这一系列操作都在index.js文件里面完成
如果要对store里面的数值进行逻辑判断(数据过滤、数据的加减乘除),那么就用到getters,用法类似于计算属性computed,getters可以看做是Vuex的计算属性
在Store仓库里,state就是用来存放数据,在Vue里面若是对数据进行处理输出,比如数据要过滤,一般我们可以写到computed中。但是如果很多组件都使用这个过滤后的数据,比如饼状图组件和曲线图组件,我们是否可以把这个数据抽提出来共享?这就是getters存在的意义。我们可以认为,【getters】是store的计算属性。因为getters是对数据进行逻辑运算,而不是新添加的方法或功能,仅仅是是数据的逻辑运算,所以要始终返回一个新值,可以先在getters下面的方法里面定义一个新值变量,经过计算,然后return出这个新变量
getters比较死板,如果你的百度钱包只有在金额为100才能提现,那么你在写提现页面,它是早已固定好的,而Mutation不一样,当你点击百度钱包提现,你哪怕是一元,它只要你点击了便可以提现,而且getters它是不需要什么点击,它就存在,只要你写了,这是什么意思,就是说假设你百度钱包为0,你存在了getter它就有100元,而你如果写许多百度经验,百度再次发红包0.5元时它就是100+0.5+100五、Vuex辅助函数
使用这些辅助函数,首先需要引入vuex,这些都是vuex下面的方法,使用解构赋值
import { mapState } from 'vuex'
mapState
mapGetters
mapMutations
mapActions
改写上面的代码:
Increment.vue组件<template> <p>{{count}}</p> <span>{{filterNum}}</span> <input type="button" value="+" @click="add" /> <input type="button" value="-" @click="reduce({n:11})"/></template><script>import {mapState,mapGetters,mapActions,mapMutations} from 'vuex'export default { data(){ }, computed:{ abc(){ return 123 //普通的计算属性 }, ...mapState(['count']) //这里的count就是store里面定义的仓库里面的count ...mapGeters(['filterNum']) //从getters里面取值(经过逻辑处理的值) }, methods:{ /*reduce(){ //同步触发action this.$store.commit('reduceAction',{n:5}) //同步每次减5 }*/ ...mapMutations({ //改写mutations,要传参,参数在模板里面添加reduce({n:11}) reduce:'reduceAction' }) /*add(){ //异步触发actions this.$store.dispatch('addAction') }*/ ...mapActions({ //改写actions add:'addAction' }) }}</script>index.jsimport Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)let store = new Vuex.Store({ state:{ count:100 }, mutations:{ addHandle(state,payload){ //payload是参数 state.count+=payload.n; }, reduceAction(state,payload){ state.count-=payload.n } }, actions:{ addAction(context){ setTimeout(()=>{ context.commit('addHandle',{n:15}) //异步每次加15 },1000) } }, getters:{ filterNum(state){ return state.count>=102?102:state.count } }})export default store
六、在vue-cli里面使用Vuex
1、npm install vuex --save
2、在src目录下面新建store文件夹,里面新建index.js
3、store/index.js代码:
import Vue from 'vue'import Vuex from 'vuex'import axios from 'axios'Vue.use(Vuex)let store = new Vuex.Store({ state:{ shopCarData:[] //购物车的数据默认数据格式是数组,使用Vuex对这个数组进行操作 }, mutations:{ addShopCarData(state,data){ //do something } }, getters:{ }})export default store
4、main.js代码
import store from './store'new Vue({ el:'#app', router, store, template:'<App/>', components:{ App }})
七、vuex使用心得1、在state里面定义全局共用的状态数据,state是一个对象,里面定义键值对,在组件页面,获取state状态值,通过computed计算属性来获取
2、即时修改state状态值,通过提交mutations来进行,mutations是一个对象,里面定义各种修改state状态值的方法,方法接收state和payload两个参数
3、异步修改state状态值,通过actions来获取数据,然后也要通过提交mutations来修改state里面定义的状态值
用的较多的是通过axios来获取远程数据,然后在then方法里面commit一个mutations来修改state里面的原始状态值,mutations要先定义
在created(){}里面通过this.$store.dispatch('fetchDataAction')来执行这个actions,
定义@click方法来即时提交mutations,
br/>1、在state里面定义全局共用的状态数据,state是一个对象,里面定义键值对,在组件页面,获取state状态值,通过computed计算属性来获取
2、即时修改state状态值,通过提交mutations来进行,mutations是一个对象,里面定义各种修改state状态值的方法,方法接收state和payload两个参数
3、异步修改state状态值,通过actions来获取数据,然后也要通过提交mutations来修改state里面定义的状态值
用的较多的是通过axios来获取远程数据,然后在then方法里面commit一个mutations来修改state里面的原始状态值,mutations要先定义
在created(){}里面通过this.$store.dispatch('fetchDataAction')来执行这个actions,
定义@click方法来即时提交mutations,
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。