一.Vuex基本介绍
1.什么是vuex?
vuex是一个专为vue.js应用程序开发的状态管理模式。
状态即vue应用组件中的各变量
2.为什么要使用vuex?
当我们构建一个中大型的单页面应用程序时,vuex可以更好地帮助我们在组件外部统一管理状态。
例如一个应用的头部组件有显示购物车数量的功能,当在各个页面添加商品到购物车,此时购物车数量要反生改变,如果不使用vuex就需要重复使用emit传值;可以将vuex想象成windows下的一个全局变量。
3.vuex的核心概念
- State
数据源载体、唯一的数据源、组件中的状态提出来放在state中。
每一个组件中data里定义的变量都可以称之为state。
单一状态树
- Getters
通过Getters可以派生出一些新的状态
const store=new Vuex.Store({
state:{
todos:[
{id:1,text:'...',done:true},
{id:2,text:'...',done:false}
]
},
getters:{
//派生出的新状态用于某些特殊场景
doneTodos:state=>{
return state.todos.filter(todo => todo.done)
}
}
})
- Mutations
更改vuex的store中的状态的唯一方法是提交mutation
const store=new Vuex.Store({
state:{
count:1
},
mutations:{
//increment是函数名 函数名可以随便取
increment(state){
//变更状态
state.count++
}
}
})
//然后在methods中通过store.commit('increment')来提交,触发increment函数。
- Actions
Action提交的是mutations,而不是直接变更状态;
Action可以包含任意异步操作(mutations中的函数都必须是同步的)。
const store=new Vuex.Store({
state:{
count:0
},
mutations:{
increment(state){
state.count++
}
},
actions:{
increment(context){
context.commit("increment")
}
}
})
- Modules
面临复杂的应用程序,当管理的状态比较多时,我们需要将vuex的store对象分割成模块(modules)
const moduleA={
state:{...},
mutations:{...},
actions:{...},
getters:{...}
}
const moduleB={
state:{...},
mutations:{...},
actions:{...}
}
const store=new Vuex.Store({
modules:{
a:moduleA,
b:moduleB
}
})
二. Vuex的语法讲解
在.html页面中使用Vuex的demo
/*demo 1*/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vuex-state</title>
<script src="../../node_modules/vue/dist/vue.js"></script>
<script src="../../node_modules/vuex/dist/vuex.min.js"></script>
</head>
<body>
<div id="app">
<h2>{{msg}}</h2>
<counter></counter>
</div>
<script>
const counter ={
template:`<div>{{count}}</div>`,
computed:{
count(){
//拿到vuex中的值
return this.$store.state.count;
}
}
}
const store = new Vuex.Store({
state:{
count:10
}
})
new Vue({
el:'#app',
store,
data:{
msg:"Vuex 使用"
},
components:{
counter
}
})
</script>
</body>
</html>
/*demo 2*/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vuex-提交mutations</title>
<script src="../../node_modules/vue/dist/vue.js"></script>
<script src="../../node_modules/vuex/dist/vuex.min.js"></script>
</head>
<body>
<div id="app">
<h2>{{msg}}</h2>
<a href="javascript:;" @click="add">点击</a>
<counter></counter>
</div>
<script>
const counter ={
template:`
<div>
<div>数量:{{count}}</div>
<div>用户名:{{name}}</div>
</div>
`,
computed:{
count(){
return this.$store.state.count;
},
name(){
return this.$store.state.name;
}
}
}
const store = new Vuex.Store({
state:{
count:10,
name:'tom'
},
mutations:{
increment(state,num){
state.count=num;
},
updateName(state,userName){
state.name=userName;
}
}
});
new Vue({
el:'#app',
store,
data:{
msg:"Vuex 使用"
},
components:{
counter
},
methods:{
add(){
this.$store.commit("increment",100);
this.$store.commit("updateName",'jerry');
}
}
})
</script>
</body>
</html>
/*demo 3*/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vuex-action</title>
<script src="../../node_modules/vue/dist/vue.js"></script>
<script src="../../node_modules/vuex/dist/vuex.min.js"></script>
</head>
<body>
<div id="app">
<h2>{{msg}}</h2>
<a href="javascript:;" @click="add">点击</a>
<counter></counter>
</div>
<script>
const counter ={
template:`
<div>
<div>数量:{{count}}</div>
<div>用户名:{{name}}</div>
</div>
`,
computed:{
count(){
return this.$store.state.count;
},
name(){
return this.$store.state.name;
}
}
}
const store = new Vuex.Store({
state:{
count:10,
name:'tom'
},
mutations:{
increment(state,num){
state.count=num;
},
updateName(state,userName){
state.name=userName;
}
},
actions:{
incrementAction(context,num){
context.commit("increment",num)
}
}
});
new Vue({
el:'#app',
store,
data:{
msg:"Vuex 使用"
},
components:{
counter
},
methods:{
add(){
this.$store.dispatch("incrementAction",100);
//this.$store.commit("updateName",'jerry');
}
}
})
</script>
</body>
</html>
/*demo 4*/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vuex-getters</title>
<script src="../../node_modules/vue/dist/vue.js"></script>
<script src="../../node_modules/vuex/dist/vuex.min.js"></script>
</head>
<body>
<div id="app">
<h2>{{msg}}</h2>
<a href="javascript:;" @click="add">点击</a>
<counter></counter>
</div>
<script>
const counter ={
template:`
<div>
<div>数量:{{count}}</div>
<div>用户名:{{name}}</div>
</div>
`,
computed:{
count(){
return this.$store.state.count;
},
name(){
return this.$store.state.name;
},
userName(){
return this.$store.getters.userName;
}
}
}
const store = new Vuex.Store({
state:{
count:10,
name:'tom'
},
getters:{
userName(state){
return state.name+',Hi!';
}
}
mutations:{
increment(state,num){
state.count=num;
},
updateName(state,userName){
state.name=userName;
}
},
actions:{
incrementAction(context,num){
context.commit("increment",num)
}
}
});
new Vue({
el:'#app',
store,
data:{
msg:"Vuex 使用"
},
components:{
counter
},
methods:{
add(){
this.$store.dispatch("incrementAction",100);
//this.$store.commit("updateName",'jerry');
}
}
})
</script>
</body>
</html>
在单页应用程序中使用Vuex的demo
/*main.js代码片段*/
import Vuex from 'vuex';
Vue.use(Vuex);
const store=new Vuex.Store({
state:{
userName:'',
cartCount:0
},
mutations:{
updateUserName(state,userName){
state.userName=userName;
},
updateUserName(state,cartCount){
state.count+=cartCount;
}
}
})
new Vue({
el:'#app',
store,
router,
template:'<App/>',
//render:h=>h(App)
components:{ App }
});//.$mount('#app')
/*navHeader.vue代码片段*/
<span v-text="userName" v-if="userName"><span>
----------
computed:{
userName(){
return this.$store.state.userName;
}
},
mounted(){
this.checkLogin();
},
methods:{
checkLogin(){
axios.get("/user/checkLogin")
.then(response=>{
var res=response.data;
var path=this.$route.pathname;
if(res.status=='0'){
this.$store.commit('updateUserName',res.result);
}else{
....
}
}
}
}
//或者使用es6的解构语法和vuex的mapState简写
----------
//先导入mapState
import { mapState } from 'vuex'
----------
computed:{
//数组中写入各个state状态
...mapState(['userName'])
//userName(){
// return this.$store.state.userName;
//}
},
mounted(){
this.checkLogin();
},
methods:{
checkLogin(){
axios.get("/user/checkLogin")
.then(response=>{
var res=response.data;
var path=this.$route.pathname;
if(res.status=='0'){
this.$store.commit('updateUserName',res.result);
}else{
....
}
}
}
}