项目当中引入 vuex
-
下载包 npm i vuex@3
-
配置项目 main.js 一般项目创建都会配置好 一般会在src/store/index.js文件中配置
import Vue from 'vue' import App from './App.vue' Vue.config.productionTip = false // 引入 vuex 的写法 // 1. 引入库 import Vuex from 'vuex' // 2. 安装 Vue.use(Vuex) // 3. 创建仓库示例 const store = new Vuex.Store() new Vue({ // 4. 挂载new Vue 示例上 store: store, render: h => h(App), }).$mount('#app')
概念一 state
创建
// 3. 创建仓库示例
const store = new Vuex.Store({
// 配置对象
// state 储存数据
state: {
count: 0,
name: '小明',
token: '1axcassdasd'
}
})
基本使用
<div>
插值表达式:
{{$store.state.count}}
{{$store.state.name}}
{{$store.state.token}}
</div>
优化方案
<template>
<div>
<div>
计算属性封装 {{name}}
</div>
</div>
</template>
<script>
export default {
// 如果觉得模板中每次都写完整的state路径非常麻烦
// 可以封装到计算属性当中,
// 1. 它本身是作为数据渲染
// 2. 他可能后续会改变
computed: {
name() {
return this.$store.state.name
}
}
}
</script>
<style>
</style>
vuex 自带辅助函数(mapState)
<template>
<div>
<div>
计算属性封装 {{name}} {{count}} {{token}}
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
// console.log(mapState(['count', 'name', 'token']));
export default {
// 如果觉得模板中每次都写完整的state路径非常麻烦
// 可以封装到计算属性当中,
// 1. 它本身是作为数据渲染
// 2. 他可能后续会改变
computed: {
...mapState(['count', 'name', 'token']),
// 相当于生成了以下三个函数
// ...{count: ƒ, name: ƒ, token: ƒ},
// name() {
// return this.$store.state.name
// },
// count() {
// return this.$store.state.count
// },
// token() {
// return this.$store.state.token
// }
}
}
</script>
<style>
</style>
概念二 mutations
注意如何要修改state里的数据必须通过mutations进行修改,不通过mutations改state的数据不会生成数据快照,页面数据可以修改但是state里的数据不会改变
数据快照:浏览器vue调试工具的功能
创建
const store = new Vuex.Store({
strict: true,
// 配置对象
// state 储存数据
state: {
count: 0,
name: '小明',
token: '123abc'
},
// 所有的变更都需要放在 mutations 里面
mutations: {
addCount(state) {
// 这个函数被调用时默认会自动带上当前state对象
state.count++
}
}
})
使用
<template>
<div>
<div>
计算属性封装 {{name}} {{count}} {{token}}
</div>
<!-- <button @click="$store.state.count ++">直接增加</button> -->
<button @click="$store.commit('addCount')">mutations增加</button>
</div>
</template>
传参的用法 // mutations中的函数的第一个参数为state,第二个为传入的值,只有一个接收值,使用当你想要传多个值的时候,可以传入数组和对象,在把要的值一一提取出来
mutations: {
addCount(state, payload) {
// 第二个参数可以用来传参, 调用commit时也在第二个参数放入即可
// 这个函数被调用时默认会自动带上当前state对象
state.count += payload
}
}
优化
注意, 由于mutations是要被执行的函数所以封装在 methods 里面
<template>
<div>
<!-- <button @click="$store.state.count ++">直接增加</button> -->
<button @click="addCount(666)">mutations增加666</button>
<button @click="addCount(888)">mutations增加888</button>
<button @click="addCount(10)">mutations增加10</button>
</div>
</template>
<script>
import { mapState } from 'vuex'
// console.log(mapState(['count', 'name', 'token']));
export default {
methods: {
addCount(data) {
this.$store.commit('addCount', data)
}
}
}
</script>
辅助函数
<template>
<div>
<div>
计算属性封装 {{name}} {{count}} {{token}}
</div>
<!-- <button @click="$store.state.count ++">直接增加</button> -->
<button @click="addCount(666)">mutations增加666</button>
<button @click="addCount(888)">mutations增加888</button>
<button @click="addCount(10)">mutations增加10</button>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
computed: {
...mapState(['count', 'name', 'token'])
},
methods: {
...mapMutations(['addCount'])
// 他可以自动生成以下的函数
// addCount(data) {
// this.$store.commit('addCount', data)
// }
}
}
</script>
<style>
</style>
概念三 actions
主要用于异步操作:如发起请求
和mutations一样,里的函数的第一个参数为state,第二个为传入的值,只有一个接收值,使用当你想要传多个值的时候,可以传入数组和对象,在把要的值一一提取出来
创建
const store = new Vuex.Store({
strict: true,
// 配置对象
// state 储存数据
state: {
//...
},
// 所有的变更都需要放在 mutations 里面
mutations: {
//...
},
actions: {
asyncAddCount(store, payload) {
// actions 的函数由于默认不能直接修改state
// 需要调用 mutations 所以第一个接到的参数是当前仓库的 store 本身
// 可以直接当做组件内 的 this.$store 来使用
setTimeout(() => {
store.commit('addCount', payload)
}, 2000);
}
}
})
使用
<template>
<div>
<button @click="$store.dispatch('asyncAddCount', 10)">异步修改state</button>
</div>
</template>
封装
<template>
<div>
<button @click="asyncAddCount(10)">异步修改state</button>
</div>
</template>
<script>
export default {
methods: {
asyncAddCount(data) {
this.$store.dispatch('asyncAddCount', data)
}
}
}
</script>
<style>
</style>
辅助函数
<template>
<div>
<button @click="asyncAddCount(10)">异步修改state</button>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex'
export default {
computed: {
...mapState(['count', 'name', 'token']),
},
methods: {
...mapMutations(['addCount']),
...mapActions(['asyncAddCount'])
}
}
</script>
<style>
</style>
getters
主要使用场景:后期项目中的state数据比较复杂,使用一般使用getters把state里要的数据提取出来,方便使用
创建
const store = new Vuex.Store({
strict: true,
state: {
count: 0,
list: [1,2,3,4,5,6,7,8,9,10,666,777,888]
},
// 能够派生出一个数据是list经过过滤返回所有大于5的数据
getters: {
// 每个属性都是一个函数
// 默认第一个接收到的就是当前的 state 对象供我们进行数据的计算
// filterList(state) {
// return state.list.filter(item=>item>5)
// }
filterList: state => state.list.filter(item=>item>5)
}
})
使用
<template>
<div>
<!-- 基本用法 {{$store.getters.filterList}} -->
{{filterList}}
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['filterList'])
// 也可以手动封装函数
// filterList() {
// return this.$store.getters.filterList
// }
}
}
</script>
<style>
</style>
常见用途(简化数据获取)
const store = new Vuex.Store({
strict: true,
state: {
student: {
name: '小明',
school: {
name: '北京大学',
address: '北京'
}
}
},
// 能够派生出一个数据是list经过过滤返回所有大于5的数据
getters: {
address: state => state.student.school.address
}
})
<template>
<dv>
学校地址: {{$store.getters.address}}
</div>
</template>