一、概览
1、Vuex是什么
专为Vue.js应用程序开发的状态管理模式(状态即数据,即数据管理)
采用集中式存储管理应用的所有组件的状态
以相应的规则保证状态以一种可预测的方式发生变化
2、状态
组件内部状态:仅在一个组件内使用的状态( 即data字段里的数据,不能共享,只在本组件使用 )
应用级别状态:多个组件共用的状态
3、什么情况下使用Vuex
多个视图依赖同一状态
来自不同视图的行为需要变更同一状态
二、使用Vuex
1、安装Vuex模块
npm install vuex --save-dev
2、作为插件使用
Vuex.use(Vuex)
3、定义一个容器
new Vuex.Store()
4、注入根实例
new vue({
store
})
具体步骤:
1、在src目录下新建store文件夹,里面创建index.js文件
在index.js文件:
import Vue from 'vue'
import Vuex from 'vuex'
Vuex.use(Vuex)
三、Vuex核心概念
1、store:类似容器,包含应用的大部分状态
一个页面只能有一个容器
状态存储是响应式的
不能直接改变store中的状态,唯一途径显示地提交mutations
2、State:包含所有应用级别状态的对象
3、Getters:在组件内部获取store中状态的函数
4、Mutations:唯一修改状态的事件回调函数,默认是同步的,如果要异步就使用Actions
5、Actions:包含异步操作、提交mutations改变状态
6、Modules:将store分割成不同的模块
四、案例
**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.commit('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
2、在main.js下面
import store from './store'
new vue({
router,
store
})
五、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.js
import 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'
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
}
})
©著作权归作者所有:来自51CTO博客作者xxxpjgl的原创作品,如需转载,请注明出处,否则将追究法律责任
共同学习,写下你的评论
评论加载中...
作者其他优质文章