Vuex的核心是Store(仓库),Store它就相当于一个容器,包含应用中大部分的状态
npm 使用
npm install vuex@next --save
1、下载以后去定义一个简单的 JS
import {createStore} from "vuex";
//创建新的store实列
export const store=createStore({
//类似Vue的data
state(){
return{
count:0,
redcount:0,
}
},
//相当于Vue里面的methods
mutations:{
add(state){
state.count++
},
reduce(state){
state.count--
state.redcount=state.count
}
}
})
2、需要把我们定义的 JS 选择Vue的全局注册也可以局部注册也可以
全局注册的话我们到哪里都可以直接调用
局部注册的话使用起来就不是那么方便 但是它可以减少Vue的负载吧!!(不是很明确)
本人使用全局注册
import { createApp } from 'vue'
import App from './App.vue'
//注册过来的Vuex核心
import {store} from "@/Store/Store";
let app=createApp(App);
//注册vuex到Vue上
app.use(store);
app.mount('#app');
3、到使用的组件中调用
<template>
<div class="hello">
<h1>{{ msg }}h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentationa>.
p>
<h3>Installed CLI Pluginsh3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babela>li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslinta>li>
ul>
<h3>Essential Linksh3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docsa>li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Foruma>li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chata>li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twittera>li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">Newsa>li>
ul>
<h3>Ecosystemh3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-routera>li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuexa>li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtoolsa>li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loadera>li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vuea>li>
ul>
<h1 @click="AAA">打印Vuex的值{{AA}}h1>
<h1 @click="BBB">减小Counth1>
<h2>Store状态值:{{StoreCount}}h2>
<h2>mapState控制的Store{{redCount}}h2>
div>
template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
},
data(){
return{
AA:'点击变化'
}
},
computed:{
//调用我前面JS定义的count
StoreCount(){
return this.$store.state.count
},
redCount(){
//调用我前面JS定义的redcount
return this.$store.state.redcount
}
},
methods:{
AAA(){
//调用我们定义的Vuex里面mutations下面的add方法来控制count的值
this.$store.commit('add');
this.AA= this.$store.state.count;
console.log(this.$store.state.count,'Vuex设置的状态值');
},
BBB(){
this.$store.commit('reduce');
}
}
}
script>
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
style>
注意如果我们定义的状态太多我们一个一个的去通过computed一个个的生成感觉代码就太多重复和冗余所以就注意到Vuex提供的mapState
getter和Vue的computed 十分相似 那么getter就相当于store做计算属性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sgjdN2QR-1681094380670)(…/其他/testimg/image-20230407145614226.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tCDx4aco-1681094380672)(…/其他/testimg/image-20230407145730411.png)]
Store.js
import {createStore} from "vuex";
//创建新的store实列
export const store=createStore({
//类似Vue的data
state(){
return{
count:9,
redcount:5,
}
},
getters:{
allcoured(state){
return state.count + state.redcount
},
gettersTwo(state){
return state.count+'是getterTwo缓存!'
}
},
//相当于Vue里面的methods
mutations:{
add(state){
state.count++
},
reduce(state){
state.count--
state.redcount=state.count
}
}
})
组件Vue
{{ msg }}
获取Vuex getters里面的AllCoRe{{allcoured}}
普通获取 getters {{gettertwo}}
效果图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OdllonPj-1681094380673)(…/其他/testimg/image-20230407145815332.png)]
mapState它是一个辅助函数它可以帮助我们生成计算属性
在需要的组件JS里面导入 mapState
import {mapState} from 'vuex'
<template>
<div class="hello">
<h1>{{ msg }}h1>
<h1 @click="AAA">加大Counth1>
<h1 @click="BBB">减小Counth1>
<h2>count:{{count}}h2>
<h2>redcount:{{redcount}}h2>
div>
template>
<script>
import {mapState} from 'vuex'
export default {
name: 'HelloWorld',
props: {
msg: String
},
data() {
return {
AA: '点击变化'
}
},
//使用的mapState帮我们生成计算属性但是它的值都是我们Vuex State里面我们定义好的值
computed: mapState({
count: state => state.count,
redcount:'redcount'
}),
methods: {
AAA() {
//调用我们定义的Vuex里面mutations下面的add方法来控制count的值
this.$store.commit('add');
this.AA = this.$store.state.count;
console.log(this.$store.state.count, 'Vuex设置的状态值');
},
BBB() {
this.$store.commit('reduce');
}
}
}
script>
<style scoped>
h3 {
margin: 40px 0 0;
}
style>
通过查看使用mapState的computed的前后对比
使用前:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jh4qaQ4E-1681094380674)(D:\notes\其他\testimg_`ZFZ0N0Q13V[X[N{FI$E0.png)]
使用后:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nbLnxmDO-1681094380675)(D:\notes\其他\testimg\image-20230404160111836.png)]
代码已经减少了许多
效果图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nK2rZJx4-1681094380676)(D:\notes\其他\testimg\image-20230404160225051.png)]
Vuex里面的Mutation类似于Vue里面的methods方法
注意:Mutation里面的方法它们会接受State为第一个参数
用法:
//相当于Vue里面的methods
mutations:{
add(state){
state.count++
},
当我们需要调用 Vuex里面的mutations的时候调用方法和Vue不同
我们需要通过 store.commit(‘定义的名字【add】’)
我们还可以想store.commit(‘A’,‘B’)里面而外传入参数B 称之为 提交载荷
import {createStore} from "vuex";
//创建新的store实列
export const store=createStore({
//类似Vue的data
state(){
return{
count:9,
}
},
//相当于Vue里面的methods
//传入载荷n
mutations:{
add(state,n){
state.count=state.count+n;
}
}
})
{{ msg }}
{{useVuexmutations}}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lnUnTgZl-1681094380678)(…/其他/testimg/image-20230408153722700.png)]
js:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QNLMAOG5-1681094380678)(…/其他/testimg/image-20230408153845112.png)]
Vue:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wjWulCva-1681094380679)(…/其他/testimg/image-20230408154127303.png)]
注意:大多数情况下提交载荷是一个对象形式这种情况包含多个字段可以复杂处理
store.commit('add', {
n: 10
})
注意:触发Vuex mutations还有一种写法
store.commit({
type: 'add',
n: 10
})
type :就是我们在mutations里面定义的 名称
n : 是我们提交过去的提交载荷
如果我们mutations的数量较多我们可以通过创建一个mutation-types.js文件来事先定义好它的名字
例如
mutations-types.js
//定义一个Vuex里面的mutations方法的 方法名为SOME_MUTATION
export const SOME_MUTATION='SOME_MUTATION';
Store.js
import {createStore} from "vuex";
//引入我们定义的mutations方法名的js文件
import {SOME_MUTATION} from "@/Store/mutation-types";
//创建新的store实列
export const store=createStore({
//类似Vue的data
state(){
return{
count:9,
}
},
//相当于Vue里面的methods
//传入载荷n
mutations:{
add(state,n){
state.count=state.count+n;
},
//使用我们定义的SOME_MUTATION来作为方法名
[SOME_MUTATION](state){
state.count=state.count+5
}
}
})
组件模板
{{ msg }}
{{useVuexmutations}}
效果图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lbuLoBKe-1681094380680)(…/其他/testimg/image-20230408161215077.png)]
注意注意注意!!! Mutations必须是同步函数
和之前的mapGetters和mapState大同小异
注意注意!!mapMutations它是在Vue methods里面触发的并不是在Vue的缓存computed直接调用
下面请看代码吧:
Store.js
import {createStore} from "vuex";
//引入我们定义的mutations方法名的js文件
import {SOME_MUTATION} from "@/Store/mutation-types";
//创建新的store实列
export const store=createStore({
//类似Vue的data
state(){
return{
count:9,
}
},
//相当于Vue里面的methods
//传入载荷n
mutations:{
add(state,n){
state.count=state.count+n;
},
//使用我们定义的SOME_MUTATION来作为方法名
[SOME_MUTATION](state){
state.count=state.count+5
}
}
})
组件调用部分代码
{{ msg }}
{{count}}
自己之前在使用时候不够细心就一种写错 把mapMutations使用到缓存computed里面了
效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mif85E6x-1681094380681)(…/其他/testimg/image-20230408163707955.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cAnVOIBF-1681094380682)(…/其他/testimg/image-20230408163720664.png)]
点击一下就触发了 给count加5
mapmutations有两种写法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dz6GaupC-1681094380682)(…/其他/testimg/image-20230408164336606.png)]
Action类似于mutation
注意注意:
Action函数接收一个与store实列具有相同方法和属性的context对象,所以可以调用context.commit提交一个mutation,或者通过context.state和context.getters来获取state和getters
问题 :属性和方法都是和stores一样问什么不是stores呢?
触发使用store.dispatch(‘定义的actions方法名’)
Store.js
import {createStore} from "vuex";
//创建新的store实列
export const store=createStore({
//类似Vue的data
state(){
return{
count:9,
act:2
}
},
mutations:{
actinfo(state){
state.act=state.act+6
}
},
actions:{
vuexact(context){
console.log('执行了vuexact')
setInterval(function () {
console.log('两秒以后执行了setInterval')
context.commit('actinfo')
},2000)
}
}
})
组件
{{ getact }}
效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nJITJfJ5-1681094380683)(…/其他/testimg/image-20230408173552086.png)]
个人理解:
Vuex里面的mutations它必定是同步的并且它是直接的去改变状态而当我们需要执行一些异步操作就需要用到actions它里面通过操作类似state的对象context去控制到state中的方法 也就是是actions它是一个外部的方法它包含了mutations里面的方法也就是(外部函数是可异步操作,内部函数的同步函数)
使用解构cont
actions: {
vuexact ({ commit }) {
console.log('执行了vuexact')
setInterval(function () {
console.log('两秒以后执行了setInterval')
commit('actinfo')
},2000)
}
}
}
注意:Action也可以使用 载荷方式和mutation一样这里我们定义context,后再定义载荷参数名即可
用法
// 以载荷形式分发
store.dispatch('incrementAsync', {
amount: 10
})
// 以对象形式分发
store.dispatch({
type: 'incrementAsync',
amount: 10
})
注意也是在vue 方法methods调用
import { mapActions } from 'vuex'
export default {
// ...
methods: {
...mapActions([
'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
// `mapActions` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
]),
...mapActions({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
})
}
}
在action中使用Promise
commit('actinfo')
},2000)
}
}
}
注意:Action也可以使用 ==载荷方式==和mutation一样这里我们定义context,后再定义载荷参数名即可
用法
```js
// 以载荷形式分发
store.dispatch('incrementAsync', {
amount: 10
})
// 以对象形式分发
store.dispatch({
type: 'incrementAsync',
amount: 10
})
注意也是在vue 方法methods调用
import { mapActions } from 'vuex'
export default {
// ...
methods: {
...mapActions([
'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
// `mapActions` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
]),
...mapActions({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
})
}
}
在action中使用Promise