state是什么?
定义:state(vuex) ≈ data (vue)
vuex的state和vue的data有很多相似之处,都是用于存储一些数据,或者说状态值.这些值都将被挂载 数据和dom的双向绑定事件,也就是当你改变值的时候可以触发dom的更新.
虽然state和data有很多相似之处,但state在使用的时候一般被挂载到子组件的computed计算属性上,这样有利于state的值发生改变的时候及时响应给子组件.如果你用data去接收$store.state,当然可以接收到值,但由于这只是一个简单的赋值操作,因此state中的状态改变的时候不能被vue中的data监听到,当然你也可以通过watch $store去解决这个问题,那你可以针是一个杠精
综上所述,请用computed去接收state,如下
//state.js
let state = {
count: 1,
name: 'dkr',
sex: '男',
from: 'china'
}
export default state
<template>
<div id="example">
<button @click="decrement">-</button>
{{count}}
{{dataCount}}
<button @click="increment">+</button>
</div>
</template>
<script>
export default {
data () {
return {
dataCount: this.$store.state.count //用data接收
}
},
computed:{
count(){
return this.$store.state.count //用computed接收
}
}
methods: {
increment () {
this.$store.commit('increment')
},
decrement () {
this.$store.commit('decrement')
}
}
}
</script>
mapState是什么?
表面意思:mapState是state的辅助函数.这么说可能很难理解
抽象形容:mapState是state的语法糖,这么说可能你还想骂我,因为你根本不了解什么叫做语法糖,事实上我说的语法糖有自己的定义,什么是语法糖?我对语法糖的理解就是,用之前觉得,我明明已经对一种操作很熟练了,并且这种操作也不存在什么问题,为什么要用所谓的"更好的操作",用了一段时间后,真香!
实际作用:当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键
在使用mapState之前,要导入这个辅助函数
import { mapState } from 'vuex'
store.js
// store.js
/**
vuex的核心管理对象模块:store
*/
import Vue from 'vue';
import Vuex from 'vuex';
import vuexTest from './modules/vuexTest';
Vue.use(Vuex)
// 状态对象
const state = { // 初始化状态 这里放置的状态可以被多个组件共享
count: 1,
count1: 1,
count2: 2,
count3: 3,
name: 'daming'
};
const mutations = {};
const actions = {};
const getters = {};
export default new Vuex.Store({
state, // 状态
mutations, // 包含多个更新state函数的对象
actions, // 包含多个队形事件回调函数的对象
getters, // 包含多个getter计算属性函数的对象
modules: { // 模块化
vuexTest
}
});
1、在界面或组件中不使用mapState获取vuex中state的状态
虽然将所有的状态放入Vuex,会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。如果有些状态严格属于单个组件,最好还是作为组件的局部状态,比如temp变量,hello, number作为组件的局部状态。
<!-- test.vue -->
<template>
<div id="example">
{{count}}
{{name}}
{{helloName}}
{{addNumber}}
</div>
</template>
<script>
export default {
data() {
return {
hello: 'hello',
number: 1,
}
},
computed: {
// 由于 Vuex 的状态存储是响应式的,所以可以使用计算属性来获得某个状态
// 通过下面的计算属性,就可以在当前组件中访问到count,name,helloName,addNumber 在模板中我们通过大括号符号打印出来,当然这些可以在vue中使用,比如在watch中监听,在mounted中使用
// 下面的计算属性涉及到了vuex管理的状态
count() { // 这实际上是ES6中对象的简化写法 完整写法是 count: function { return this.$store.state.count }
return this.$store.state.count
},
name() { // 这实际上是ES6中对象的简化写法 完整写法是 name: function { return this.$store.state.count }
return this.$store.state.count
},
helloName: function (state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数
return this.hello + this.$store.state.name
},
addNumber: function (state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数
return this.number + this.$store.state.count
}
// 但有一个问题
// 当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。比如上面的name(),count(),helloName(),显得重复,代码冗长
// 为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键:
},
watch: {
helloName(newVal,oldVal){
console.log(newVal);
console.log(oldVal);
}
},
mounted(){
console.log(this.helloName);
}
}
</script>
2、在组件、界面中使用mapState获取vuex中state的数据
<!-- test.vue -->
<template>
<div id="example">
{{count}}
{{count1}}
{{repeatCount}}
{{count3}}
{{name}}
{{helloName}}
{{addNumber}}
</div>
</template>
<script>
export default {
data() {
return {
hello: 'hello',
number: 1,
count2: 2
}
},
computed: {
/**
* 数组形式
* 当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组。
* */
...mapState(["count", "name"]),
/**
* 对象形式
*/
...mapState({
count, // 这种就是count:"count", 的简写
count1: "count1",
repeatCount: "count2", // 当组件中与vuex中的字符已经出现重复时,使用 repeatCount 来映射 store.state.count2
count3: (state) => { // 映射 count3 为 store.state.conut3的值
return state.count3
},
helloName: function (state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数
return this.hello + state.name
},
addNumber: function (state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数
return this.number + state.count
}
})
},
watch: {
helloName(newVal, oldVal) {
console.log(newVal);
console.log(oldVal);
}
},
mounted() {
console.log(this.helloName);
}
}
</script>
3、modules的vuexTest模块中state数据
/**
* vuexTest.js
* modules 中的数据
*/
export default {
namespaced: true,
state: {
moduleVal: 1,
moduleName: "战战兢兢"
},
getters: {
},
mutations: {
},
actions: {
}
}
4、在界面或组件中不使用mapState获取模块modules vuexTest中state的状态
<!-- module test.vue -->
<template>
<div id="example">
{{moduleVal}}
{{moduleName}}
{{moduleNameOther}}
</div>
</template>
<script>
export default {
data() {
return {
hello: 'hello',
number: 1,
}
},
computed: {
moduleVal(){
return this.$store.state.vuexTest.moduleVal
},
moduleName(){
return this.$store.state.vuexTest.moduleVal
},
moduleNameOther(){
// 当组件中与vuex中的字符已经出现重复时,使用 moduleNameOther 来映射 store.state.vuexTest.moduleName
return this.$store.state.vuexTest.moduleVal
},
},
watch: {
helloName(newVal, oldVal) {
console.log(newVal);
console.log(oldVal);
}
},
mounted() {
console.log(this.addNumber);
}
}
</script>
5、在界面或组件中使用mapState获取模块modules vuexTest中state的状态
<!-- module test.vue -->
<template>
<div id="example">
{{moduleVal}}
{{moduleName}}
{{moduleNameOther}}
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
data() {
return {
hello: 'hello',
number: 1,
}
},
computed: {
/**
* 数组形式
* 当映射的计算属性的名称与 与模块中vuexTest中state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组,
* */
...mapState("vuexTest", ["moduleVal", "moduleName"]),
// "vuexTest" 指向模块vuexTest,"moduleVal"表示store.vuexTest.moduleVal
/**
* 对象形式
*/
// 第一种对象方式
...mapState({
moduleVal: "vuexTest/moduleVal",
moduleNameOther: "vuexTest/moduleName" // 表示 moduleNameOther 映射到vuexTest模块中moduleName
}),
...mapState("vuexTest", {
moduleVal, // 这种就是moduleVal:"moduleVal", 的简写
moduleName: "moduleName",
moduleNameOther: "moduleName", // 当组件中与vuex中的字符已经出现重复时,使用 moduleNameOther 来映射 store.state.vuexTest.moduleName
moduleVal: (state) => { // 映射 moduleVal 为 store.state.vuexTest.moduleVal的值
return state.moduleVal
},
helloName: function (state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数
return this.hello + state.moduleName
},
addNumber(state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数
return this.number + state.moduleVal
}
})
},
watch: {
helloName(newVal, oldVal) {
console.log(newVal);
console.log(oldVal);
}
},
mounted() {
console.log(this.addNumber);
}
}
</script>
求关注啊!!!