vuex简介
vuex是一个vue自带的状态管理工具,可以实现对数据的储存和管理,方便在项目中各个组建中进行应用
1 起步
1.1 项目中安装vuex:
执行:npm install vuex --save
1.2 创建store文件夹生成index.js文件用于创建vuex实例
1.3 在index中执行如下代码创建vuex实例
APP.vue
// 引入vue模块
import Vue from 'vue'
// 引入vuex模块
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
user: 'admin',
count: "100"
},
mutations: {
increment(state, payload) {
state.count += payload
},
decrement(state) {
state.count -= 10
}
},
actions: {
},
modules: {
}
})
1.4 将创建好vue实例的index.js引入到main.js,并且在vue实例中注册store
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
现在就可以在全局中使用 vuex
2 创建和使用store里面的数据(存放和修改)
2.1 在store里存放数据和在其他组件中使用数据(state)
在home.vue里面使用
template>
<div class="home">
<h1>我是首页</h1>
<button @click="demo">点击显示des</button>
<button @click="demo1">点击显示dadcount</button>
<h1>
<!-- 方式一: -->
显示store里信息1 :{{ $store.state.user }}
点击显示des :{{ des }}
</h1>
<h1>
<!-- 方式二:辅助函数 -->
显示store里信息2 :{{ user }}
</h1>
<h1>
<!-- 方式二:辅助函数 -->
显示store里信息3 :{{ count }}
点击显示dadcount :{{ dadcount }}
</h1>
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
computed: {
...mapState(['user', 'count'])
},
data() {
return {
des: '',
dadcount: ''
}
},
methods: {
demo() {
this.des = this.$store.state.user
},
demo1() {
this.dadcount = this.count
}
}
}
</script>
总结 :储存和获取数据
方式一:通过this.$store.state.数据
方式二 : mapState辅助函数获取属性步骤如下:
(1)import { mapState } from "vuex";
(2) computed中通过 ...mapState(['数据1', '数据2'])引入
(3) {{ 数据1 }}
2.2 在store里存放数据和修改state数据(Mutations)
template>
<div>
// 方式一 :通过commit路径去触发store里Mutations里的方法
<h1>我是关于页</h1>
<button @click="add">+</button>
<button @click="dec">-</button>
{{ count }}
// 方式二 :引入辅助函数mapMutations
<button @click="add2">辅助函数+</button>
<button @click="dec2">辅助函数-</button>
</div>
</template>
<script>
import { mapState, mapMutations } from "vuex";
export default {
computed: {
...mapState(['count'])
},
methods: {
...mapMutations(['increment', 'decrement']),
add() {
this.$store.commit('increment', 5)
},
dec() {
this.$store.commit('decrement')
},
add2() {
this.increment(5)
},
dec2() {
this.decrement()
},
}
}
</script>
总结 :修改state数据
唯一方式 :只要是储存在state数据必须通过 mutations里的方法修改,这是必须的
但是在其他组件中使用的 mutations方法的时候有两种方法。
方法一:直接 this.$store.commit("increment")即通过commit路径
方法二 :使用mapMutations辅助函数
Mutation 需遵守 Vue 的响应规则
a:最好提前在你的 store 中初始化好所有所需属性。
b:当需要在对象上添加新属性时,你应该使用 Vue.set(obj, 'newProp', 123), 或者以新对象替换老对象
注意:在Vue中,对象属性的增加或减少,必须通过Vue.set去改变!!!
使用常量替代 Mutation 事件类型 Mutation 必须是同步函数
2.3 vuex里的异步处理(actions)
actions: {
//actions不仅可以做异步操作,也可以做同步操作
actionsincrement(context, payload) {
context.commit('increment', payload)
},
actionsDecrement(context) {
context.commit('decrement')
}
},
<template>
<div>
<h1>我是关于页</h1>
<h1>直接修改</h1>
<button @click="add">+</button>
<button @click="dec">-</button>
{{ count }}
<h1>Mutation修改</h1>
<button @click="add2">辅助函数+</button>
<button @click="dec2">辅助函数-</button>
<h1>actions修改</h1>
<button @click="add3">actions直接修改+</button>
<button @click="dec3">actions辅助函数-</button>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from "vuex";
export default {
computed: {
...mapState(['count'])
},
methods: {
...mapMutations(['increment', 'decrement']),
...mapActions(['actionsDecrement']),
add() {
this.$store.commit('increment', 5)
},
dec() {
this.$store.commit('decrement')
},
add2() {
this.increment(5)
},
dec2() {
this.decrement()
},
add3() {
this.$store.dispatch('actionsincrement', 8)
},
dec3() {
this.actionsDecrement()
},
}
}
</script>
总结:actions里面可以做异步操作也可以同步
但是在改变state里面的值得时候还是通过mutation来修改的通过context里面的commit先进入mutation,再修改数据
2.3 vuex数据在加工(actions)
getters: {
userName: state => {
return state.user + '--vip用户'
}
},
<template>
<div>
<h1>我是关于页</h1>
<h1>直接修改</h1>
<button @click="add">+</button>
<button @click="dec">-</button>
{{ count }}
<h1>Mutation修改</h1>
<button @click="add2">辅助函数+</button>
<button @click="dec2">辅助函数-</button>
<h1>actions修改</h1>
<button @click="add3">actions直接修改+</button>
<button @click="dec3">actions辅助函数-</button>
<h1>getters操作</h1>
{{ $store.getters.userName }}
{{ userName }}
</div>
</template>
<script>
import { mapState, mapMutations, mapActions, mapGetters } from "vuex";
export default {
computed: {
...mapState(['count']),
...mapGetters(['userName'])
},
methods: {
...mapMutations(['increment', 'decrement']),
...mapActions(['actionsDecrement']),
add() {
this.$store.commit('increment', 5)
},
dec() {
this.$store.commit('decrement')
},
add2() {
this.increment(5)
},
dec2() {
this.decrement()
},
add3() {
this.$store.dispatch('actionsincrement', 8)
},
dec3() {
this.actionsDecrement()
},
}
}
</script>
总结:有时候我们需要从 store 中的 state 中派生出一些状态,或者对state里面的数据过滤在加工,可以使用getters,其实相当于vuex里面的一个计算属性
3 vuex的模块化
modules: {
cityMoudle: {
namespaced: true,
state: {
city: '上海'
}
},
loginMoudle: {
namespaced: true,
state: {
name: 'zhangsan'
},
mutations: {
changeName(state, payload) {
state.name = payload
}
}
}
}
<template>
<div>
<button @click="btnclick">点击打印</button>
<h1>城市模块化使用</h1>
<!-- 直接使用 -->
<p>直接使用当前城市:{{ $store.state.cityMoudle.city }}</p>
<!-- 辅助函数使用 -->
<p>辅助函数使用当前城市:{{ city }}</p>
<hr>
<h1>登录模块化使用</h1>
<!-- 直接使用 -->
<p>直接使用当前登录用户名:{{ $store.state.loginMoudle.name }}</p>
<!-- 辅助函数使用 -->
<p>辅助函数使用当前登录用户名:{{ $store.state.loginMoudle.name }}</p>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: {
...mapState('cityMoudle', ['city']),
...mapState('loginMoudle', ['name'])
},
methods: {
btnclick() {
console.log(this);
},
}
}
</script>
总结 :由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
1. 命名空间
2. 模块的局部状态
3. 快捷读取方案
读取和改变模式都和根组件一样,只不过要加上具体的模块名
最后各个模块和根模块之间的数据传输可以看官网有详细教程