Vuex
- 安装插件 Vue use(Vuex)
- 创建对象
// index.js 笔记:
import * as types './mutations-types'
const store = new Vuex.Store({
/**
* 所有的数据响应式必须定义在state中
*/
state: {
count:0,
students:[],
info:{
name:'xwg',
age:18
}
},
/**
* mutations下的函数接收 state作为参数,接收一个叫做payload的(载荷)作为第二个参数,payload记录开发者使用该函数的一些信息
* mutations方法必须是同步方法 不要在mutation中进行异步的操作
* mutations中定义的函数可以看成两部分
* 1、字符串的事件类型(type)
* 2、一个回调函数(handler),该回调函数的第一个参数就是state
*/
mutations: {
//addStudent 事件类型
//(state) {} 回调函数
/**
* 在页面中通过mutation更新 commit传入的第一个参数为事件类型
* this.$store.commit('addStudent',stu) //第一种写法
* this.$store.commit({ //第二种写法
* type:'addStudent',
* stu
* })
*/
addStudent(state,stu) {
//第一种写法更新 这里的stu是一个学生对象
state.students.push(stu)
//第二种写法更新 (stu更名为payload)这里的payload是包含事件类型的一个对象
//payload.stu为学生对象
state.students.push(payload.stu)
},
updateInfo(state){
//非响应式
state.info['address'] = '中国北京'
//通过Vue.set实现响应式
//Vue.set(state.info,'address','中国北京')
//该删除对象属性方式做不到响应式
//delete state.info.age
//通过Vue.delete()实现响应式删除
//Vue.delete(state.info,'age')
},
/**
* 通过定义常量 避免mutations中定义的事件类型&页面commit提交时使用定义的常量不一致
* 例:(前提先引入定义常量的js文件 import * as types './mutations-types')
* mutations:(index.js)
* [types.INCREMENT](state) {
* state.count++
* },
* 页面中使用:(Home.vue)
* this.$store.commit(types.INCREMENT)
*/
[types.INCREMENT](state){
state.count++
}
},
/**
* 异步代码写在actions中
*/
actions: {
//context: 上下文 这里的context就是 store
actUpdateInfo(context) {
//模拟异步操作
setTimeout(() => {
//错误
//context.state.info['age'] = 26
//正确
context.commit('updateInfo')
//在这里commit之后 页面(Home.vue)调用就不能够使用commit了,
//应使用 this.$store.dispatch('actUpdateInfo') //通过dispatch调用actions中的方法
})
}
},
//模块
modules: {
moduleA
}
})
module是模块的意思,为什么在Vuex中我们要使用模块呢?
- Vue使用单一状态树,那么也意味着很多状态都会交给Vuex来管理
- 当应用变得非常复杂时,store对象就有可能变得相当臃肿
- 为了解决这个问题,Vuex允许我们将store分割成模块(module),而每个模块拥有自己的state、mutations、actions、getters等
const moduleA = {
state: {
name:'张三'
//页面中渲染 通过$store.state.moduleA.name实现,module中定义的state会放在store中的state
},
mutations: {
updateName(state,payload) {
state.name = payload
}
//正常调用(this.$stoer.commit('updateName','李四')) 如果store中的mutaions中找不到该方法则会到模块中(modules)查找
},
getters: {
//页面正常调用 $store.getters.fullName
fullName(state) {
return state.name + '与李四的故事'
},
//第三个参数为store下的state
fullName1(state,getters,rootState) {
return getters.fullName + rootState.count
}
},
actions: {
//这里的context上下文 指的是当前模块
//页面通过this.$store.dispatch('actUpdateName') 调用异步
//另一种写法 利用对象的解构 actUpdateName({state,commit,rootState}){}
actUpdateName(context) {
console.log(context) //state,commit,dispatch,rootGetters,rootState...
setTimeout(() => {
context.commit('updateName','王五')
},1000)
}
}
}
store中的每一项(mutations、getters、actions、modules)都可以单独拿出来放在单个js文件中
//mutations-type.js
// 通过定义常量 避免mutations中定义的事件类型&页面commit提交时使用定义的常量不一致
/**
* 例:(前提先引入当前的js文件 import * as types './mutations-types')
* mutations:(index.js)
* [types.INCREMENT](state) {
state.counter++
},
页面中使用:(Home.vue)
this.$store.commit(types.INCREMENT)
*/
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'
export const CREMENTCOUNT = 'crementCount'
export const ADDSTUDENT = 'addStudent'
export const UPDATEINFO = 'updateInfo'
//mutations.js
import * as types from './mutations-type'
export default {
[types.INCREMENT](state) {
state.counter++
},
[types.DECREMENT](state) {
state.counter--
},
// mutations的(count) 参数被称为是mutation的载荷(payload)
[types.CREMENTCOUNT](state,payload){
console.log(payload)
// state.counter += count
state.counter += payload.count
},
[types.ADDSTUDENT](state,stu) {
state.students.push(stu)
},
[types.UPDATEINFO](state) {
state.info['name'] = '被改变的name值'
}
}
//getters.js
export default {
// 基本使用
// 平方
powerCounter(state) {
return state.counter * state.counter
},
// 筛选年龄大于20的学生
getStuToAge(state) {
return state.students.filter(val => val.age > 20)
},
// 年龄大于20的学生个数 第二个参数固定就是getters 名称可自定义
getStuToAgeNum(state, getrs) {
return getrs.getStuToAge.length
},
moreAgeStu(state) {
// 接收页面调用传过来的参数 返回一个function
return age => {
return state.students.filter(s => s.age > age)
}
}
}
//actions.js
export default {
// 异步操作
// 页面中(Home.vue)调用actions中的方法通过 this.$store.dispatch('actUpdateInfo','参数')
actUpdateInfo(context, payload) {
return new Promise((resolve, reject) => {
setTimeout(() => {
context.commit(types.UPDATEINFO)
console.log(payload)
resolve('修改完成')
}, 1000)
})
}
}
单独拿出来之后 最新的index.js
import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations'
import actions from './actions'
import getters from './getters'
import moduleA from './modules/moduleA'
// 安装插件
Vue.use(Vuex)
const state = {
counter:1000,
students: [
{id:101,name:'xwg',age:18},
{id:102,name:'wpq',age:22},
{id:103,name:'dyh',age:1},
{id:104,name:'ddd',age:26}
],
info:{
name:'fexwg',
age:18
}
}
// 创建对象
const store = new Vuex.Store({
state,
mutations,
actions,
getters,
modules:{
moduleA
}
})
// 导出对象
export default store
- 导出store对象 export default store
在Test.vue中使用vuex
<template>
<div>
<h1>主页</h1>
<h2>module中的内容</h2>
<p>{{$store.state.moduleA.name}}</p>
<button @click="changeModuleAname">改变module中的name值</button>
<h3>{{$store.state.counter}}</h3>
<button @click="add">加</button>
<button @click="subtraction">减</button>
<button @click="addCount(5)">加5</button>
<button @click="addCount(10)">加10</button>
<button @click="addStu">添加学生</button>
<h2>getters相关信息</h2>
<p>平方:{{$store.getters.powerCounter}}</p>
<pre>
<p>年龄大于20的学生对象:{{$store.getters.getStuToAge}}</p>
</pre>
<span>年龄大于20的学生个数:{{$store.getters.getStuToAgeNum}}</span>
<pre>
<p>根据页面传参返回学生对象:{{$store.getters.moreAgeStu(10)}}</p>
</pre>
<pre>
<p>vuex中的info信息:{{$store.state.info}}</p>
</pre>
<button @click="updateInfo">改变info中的name值</button>
</div>
</template>
<script>
import * as types from '../../store/mutations-types'
export default {
//import引入的组件需要注入到对象中才能使用
components: {},
data() {
//这里存放数据
return {};
},
//监听属性 类似于data概念
computed: {},
//监控data中的数据变化
watch: {},
//方法集合
methods: {
add() {
this.$store.commit(types.INCREMENT)
},
subtraction() {
this.$store.commit(types.DECREMENT)
},
addCount(count) {
let obj = {
count,
name:'jack',
sex:'man'
}
// this.$store.commit('crementCount',count)
this.$store.commit({
type:types.CREMENTCOUNT,
...obj
})
},
addStu() {
const stu = {
id:105,
name:'test',
age:36
}
this.$store.commit(types.ADDSTUDENT,stu)
},
updateInfo(){
// 同步操作
// this.$store.commit(types.UPDATEINFO)
// 异步操作
// 调用mutation中的actions 通过dispatch
this.$store.dispatch('actUpdateInfo','name值被异步操作改变了').then((ret) => {
console.log(ret)
})
},
changeModuleAname(){
// 同步
// this.$store.commit('updateName','李四')
// 异步
this.$store.dispatch('actUpdateName')
}
},
//生命周期 - 创建完成(可以访问当前this实例)
created() {},
//生命周期 - 挂载完成(可以访问DOM元素)
mounted() {},
};
</script>
<style scoped>
</style>
网友评论