一、基本概念介绍
Vuex
解决不同组件的数据共享和数据持久化!就是H5中的 LocalStorage
和 SessionStorage
的替代品!
注意:Vuex一般用于大项目,小项目等不用就不用。
(一)运行原理
如上图所示,Vuex的核心组件分为三个:
- State:存储所有的公用数据;
- Mutations:所有对 State 中数据的操作都由 Mutations 来执行,其他必须通过该组件才能操作 State 中数据;
- Actions:在改变公共数据时,若涉及到一些异步操作,那么需要通过 dispatch()方法来调用 Actions 中的方法,再由 Actions 中的方法调用 Mutations 中的方法,再由 Mutations 操作公共数据。
二、Vuex的使用
1、src目录下面新建一个vuex的文件夹
2、vuex 文件夹里面新建一个store.js
3、安装vuex
cnpm install vuex --save
4、在刚才创建的 store.js
引入vue 引入vuex 并且use vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
5、定义数据(store.js
)
/*1.state在vuex中用于存储数据*/
var state={
count:1
}
6、定义方法 mutations里面放的是方法,方法主要用于改变state里面的数据(store.js
)
var mutations={
incCount(){
++state.count;
}
}
7、优点类似计算属性 , 改变state里面的count数据的时候会触发 getters里面的方法 获取新的值 (基本用不到)
var getters= {
computedCount: (state) => {
return state.count*2
}
}
8、 Action 基本没有用
Action 类似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。
var actions= {
incMutationsCount(context) { /*因此你可以调用 context.commit 提交一个 mutation*/
context.commit('incCount'); /*执行 mutations 里面的incCount方法 改变state里面的数据*/
}
}
9.暴露
const store = new Vuex.Store({
state,
mutations,
getters,
actions
})
export default store;
10.组建里面使用vuex:
(1)引入 store
import store from '../vuex/store.js';
(2)注册
export default{
data(){
return {
msg:'我是一个home组件',
value1: null,
}
},
//注册store
store,
methods:{
incCount(){
// 当逻辑不复杂时,可通过 commit() 调用 Mutations 中的方法
this.$store.commit('incCount'); /*触发 state里面的数据*/
}
}
}
(3)获取state里面的数据
this.$store.state.数据
//改变这种写法
import { mapState } from "vuex"
computed: {
// 把 vuex 中的数据映射到 该组件的 computed 属性里
...mapState(['city'])
}
//使用 city
<div class="header-right">
{{city}}
<span class="iconfont arrow-icon"></span>
</div>
(4)触发 mutations 改变 state里面的数据
this.$store.commit('incCount');
//改变这种写法
<script>
.....
import { ....,mapMutations } from "vuex"
export default {
....
methods: {
handleCityClick (city) {
// 当逻辑很简单时,可以直接调用 commit() 来改变数据
// this.$store.commit('changeCity', city)
this.changeCity(city)
....
},
// 把 vuex Mutations 中的changeCity()方法映射到 该组件的changeCity()方法里
...mapMutations(['changeCity'])
},
....
}
</script>
(5)触发 actions里面的方法
this.$store.dispatch('incCount');
(6)获取 getters里面方法返回的的数据
{{this.$store.getters.computedCount}}
三、完整案例
1.组件
<template>
<div>
....
<div
class="search-content"
ref="search"
v-show="keyword"
>
<ul>
<li
class="search-item border-bottom"
v-for="item of list"
:key="item.id"
@click="handleCityClick(item.name)">
{{item.name}}
</li>
<li class="search-item border-bottom" v-show="hasNoData">
没有找到匹配数据
</li>
</ul>
</div>
</div>
</template>
<script>
import { mapMutations } from "vuex"
.
export default {
name: 'CitySearch',
..
methods: {
handleCityClick (city) {
// 当需要异步操作时,可以调用 dispatch(),来通知 action 改变数据
// this.$store.dispatch('changeCity', city)
// 当逻辑很简单时,可以直接调用 commit() 来改变数据(PS:这也是一种写法)
// this.$store.commit('changeCity', city)
this.changeCity(city)
//跳转回首页
this.$router.push('/')
},
// 把 vuex Mutations 中的changeCity()方法映射到 该组件的changeCity()方法里
mapMutations(['changeCity'])
}
}
</script>
.....
2.store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
city: '北京'
},
mutations: {
changeCity (state, city) {
state.city = city
}
},
actions: {
changeCity (ctx, city) {
ctx.commit('changeCity', city)
}
}
})