概念:vuex,相当于一个公共仓库,保存所有组件都能共用的数据,存放的数据是响应式的,保持页面和数据的同步。
好处:想要在子组件使用祖先的数据,就不用一层层传值,也解决了兄弟组件之间不能直接传值的问题。
具体点:
-
能够在vuex中集中管理共享的数据,便于开发和后期进行维护
-
能够高效的实现组件之间的数据共享,提高开发效率
-
存储在vuex中的数据是响应式的,当数据发生改变时,页面中的数据也会同步更新
目录
方式一:直接标签内使用:{ {this.$store.state.name}}
方式三:计算属性(return this.$store.state.count)
方式二:mapMutations 辅助函数(映射在methods)
方式一:通过 this.$store.dispatch() 方法触发 actions
方式二:mapActions 辅助函数(映射在methods)
方式一:通过属性访问{ {this.$store.getters.showCount}
Vuex 安装
$ npm install vuex --save
在模块化的打包系统中,必须显式地通过 Vue.use()
来安装 Vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
一、State
State 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 中的 State 中存储
const store= new Vuex.Store({
//数据,相当于data
state: {
name:"张三",
count:0}
//可以拿到state里的数据,操作state数据的方法
mutation:{
add(state){
state.count=state.count+1}
}
具体用法:
1、新建 src/store/index.js 文件
// 新建 src/store/index.js 文件
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
mutations: {},
actions: {},
getters: {}
})
2、在入口main.js中引入
import Vue from 'vue'
import App from './App.vue'
// 引入
import store from './store'
Vue.config.productionTip = false
new Vue({
// 挂载,把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
store: store,
render: h => h(App)
}).$mount('#app')
通过在根实例中注册 store 选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store 访问到。
只要在祖先中保存了vuex对象(store:store),祖先和后代就都能使用共享数据
state使用方式:
方式一:直接标签内使用:<p>{
{this.$store.state.name}}</p>
<p>{
{this.$store.state.name}}</p>
方式二:this.$store.state.全局数据名称
{
{$store.state.全局数据名称}}
<template>
<div>
<h3>当前最新的count值为:{
{ $store.state.count }}</h3>
<button>++</button>
</div>
</template>
方式三:计算属性(return this.$store.state.count)
从 store 实例中读取状态最简单的方法就是在 计算属性 中返回某个状态:
大家看!为了更好理解下面即将说的辅助函数mapState,我在这个代码里写了两种写法。
<template>
<div>{
{ count }}</div>
</template>
<script>
export default {
computed: {
count () {
return this.$store.state.count;//这么写太麻烦啦,看下面我的语法糖,我的简化写法
...mapState(['count'])//我是上面那行的简化写法!我用了辅助函数mapState,映射在computed中
}
}
}
</script>
然而,这种模式导致组件依赖全局状态单例。在模块化的构建系统中,在每个需要使用 state 的组件中需要频繁地导入。
方式四:mapState
辅助函数(映射在计算属性中)
数据映射为计算属性: computed:{ ...mapState(['全局数据名称']) }
当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题, mapState
辅助函数帮助我们生成计算属性,让你少按几次键:
<template>
<div>
<h3>当前最新的count值为:{
{ count }}</h3>
<button>--</button>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
data() {
return {}
},
computed: {...mapState(['count'])}
}
</script>
二、mutations
简单说:存放操作state的方法,提交更新state的方法,也就是修改值用的。
注意:在 Vuex 中,mutation 都是同步的。
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation 。
Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
mutations: {
//第一个形参永远都是state, 第二个形参是调用add时传递的参数
add(state, step) {
state.count += step
}
}
mutations使用方式:
方式一:this.$store.commit('xxx')
<template>
<div>
<h3>当前最新的count值为:{
{ $store.state.count }}</h3>
<button @click="add">++</button>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {
//第二种方式,两种达到的目的一致,用辅助函数可以简化写法。映射在method中。
...mapMutations(['add'])
add() {
//第一种方式:commit就是调用某个mutation函数
this.$store.commit('add', 1)
this.add(1)//第二种方式
}
}
}
</script>
<style lang="less" scoped></style>
为了更好理解下面的辅助函数,我也在上面对比着写了辅助函数写法。
方式二:mapMutations
辅助函数(映射在methods)
使用 mapMutations
辅助函数映射在methods 中
<template>
<div>
<h3>当前最新的count值为:{
{ count }}</h3>
<button @click="btn">--</button>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
data() {
return {}
},
methods: {
// 第二种方式
// 将 this.sub() 映射为 this.$store.commit('sub')
...mapMutations(['sub']),
btn() {
this.sub(2)
}
},
computed: mapState(['count'])
}
</script>
<style lang="less" scoped></style>
三、actions
Action 类似于 mutation,专门处理异步,不同在于:
-
Action 提交的是 mutation,而不是直接变更state,真正修改值的还是mutation。
-
Action 可以包含任意异步操作。mutation只能包含同步操作
actions使用方式:
方式一:通过 this.$store.dispatch()
方法触发 actions
注:store文件夹下的index.js
export default new Vuex.Store({
state:{
count:111,
name:'笛子兔'
},
mutations:{
add(state,s){
state.count+=s
}
},
actions:{
addlow(c,step){
setTimeout(()=>{
//Action 提交的是 mutation,而不是直接变更state,真正修改值的还是mutation。
c.commit('add',step)//mutation中的add
},2000)
}
},
getters:{},
})
注:在使用vuex的组件中
<template>
<div class="hello">
{
{count}}
<input type="button" @click='adds' value='点我加'>
<input type="button" @click='addAction' value='点我慢加'>
</div>
</template>
<script>
import { mapActions, mapMutations, mapState } from 'vuex'
export default {
name: 'HelloWorld',
computed:{
...mapState(['count'])
},
methods:{
//mutation语法糖--map辅助寒素
...mapMutations(['add']),
//actions语法糖--map辅助函数
...mapActions(['addlow']),
adds(){
//commit调用某个mutation的函数
// this.$store.commit('add',100)
this.add(100)
},
addAction(){
// dispatch专门用来触发action
// this.$store.dispatch('addlow',333)
this.addlow(444)
}
}
}
</script>
方式二:mapActions
辅助函数(映射在methods)
使用 mapActions
辅助函数映射在methods 中,写法跟mutation差不多,对比在上面的代码中啦
四、getters
跟computed作用一致。
它只会包装Store中保存的数据, 并不会修改Store中保存的数据。
当Store中的数据发生变化时, Getter生成的内容也会随之变化。
补充计算属性和监听属性的不同:
①computed设计初衷:存放模板中复杂的表达式。基于响应式缓存,只有变化时,才会重新求值。变化之前调用多次只执行一次。
②监听属性初衷:用来监听data变化。
如果数据是组件的用计算属性缓存。如果数据是vuex中的,用getters缓存。
getters: {
// 添加了一个 showCount
showCount: state => {
return '最新的count值: ' + state.count
}
}
getters使用方法
方式一:通过属性访问{ {this.$store.getters.showCount}
方式二:mapGetters
辅助函数(映射在计算属性)
下面是四种辅助函数的用法汇总,已做标注
<template>
<div>
<h3>{
{ showCount }}</h3>
<button @click="btn">--</button>
<button @click="btn2">-- Async</button>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
export default {
data() {
return {}
},
methods: {
//mutations语法糖--映射在methods
// 将 this.sub() 映射为 this.$store.commit('sub')
...mapMutations(['sub']),
btn() {
this.sub(2)
},
// actions语法糖--映射在methods
// 将this.subAsync() 映射为 this.$store.dispatch('subAsync')
...mapActions(['subAsync']),
btn2() {
this.subAsync(5)
}
},
computed: {
//state语法糖--映射在computed
...mapState(['count']),
//getters语法糖--映射在computed
...mapGetters(['showCount'])
}
}
</script>
看了这么多,累了吧~来总结下吧~
vuex,相当于一个公共仓库,保存所有组件都能共用的数据,存放的数据是响应式的,保持页面和数据的同步。组件之间数据共享,开发十分高效。
一、State---用来存放数据,唯一公共数据源
state使用方式:
方式一:直接标签内使用:{ {this.$store.state.name}}
方式二:this.$store.state.全局数据名称
方式三:计算属性(return this.$store.state.count)
方式四:mapState 辅助函数(映射在计算属性中)computed:{ ...mapState(['全局数据名称']) }
二、mutations---提交更新state的方法,在 Vuex 中,mutation 都是同步的。
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation 。
//第一个形参永远都是state, 第二个形参是调用方法时传递的参数
mutations使用方式:
方式一:this.$store.commit('xxx')
方式二:mapMutations 辅助函数(映射在methods)...mapMutations(['mutation的方法名'])
三、actions---类似于 mutation,专门处理异步,不同在于:Action 提交的是 mutation,而不是直接变更state,真正修改值的还是mutation。mutation只能包含同步操作
actions使用方式:
方式一:通过 this.$store.dispatch() 方法触发 actions
方式二:mapActions 辅助函数(映射在methods)...mapActions(['Actions的方法名'])
四、getters---类似于计算属性,用于缓存,储存表达式,如果数据是组件的用计算属性缓存。如果数据是vuex中的,用getters缓存。
getters使用方式:
方式一:通过属性访问{ {this.$store.getters.showCount}
方式二:mapGetters 辅助函数(映射在计算属性) ...mapGetters(['showCount'])
对于辅助函数:getters和state映射在计算属性,mutations和actions映射在methods
后面还有模块化,适合把这些吃透了的小伙伴,后面可能还会出