Vue2-Vuex概念及使用场景、Vuex环境搭建、Vuex工作原理、Vuex配置项、Vuex模块化及命名空间

news2025/1/16 7:49:51

🥔:山不向我走来,我便向它走去

更多Vue知识请点击——Vue.js

VUE2-Day11

    • 理解Vuex
      • 1、Vuex是什么
      • 2、什么时候使用Vuex
    • Vuex环境搭建
      • 1、安装vuex
      • 2、创建store文件
      • 3、main.js引入store
    • Vuex的工作原理
      • 1、原理图
      • 2、用案例解释工作原理
      • 3、注意点
    • Vuex配置项
      • 1、getters配置项
      • 2、mapstate与mapGetters
      • 3、mapActions与mapMutations
    • 多组件共享数据
    • Vuex模块化+命名空间(项目常用)
      • 1、模块化的概念及作用
      • 2、使用方式
      • 3、综合案例

理解Vuex

1、Vuex是什么

概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件对Vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信

  • 我们之前使用全局事件总线实现多组件共享数据,看起来挺好的问题不大,但是组件一多的话就会变得很麻烦:

请添加图片描述

  • 我们现在使用Vuex实现多组件共享数据:

请添加图片描述

2、什么时候使用Vuex

  1. 多个组件依赖于同一状态
  2. 来自不同组件的行为需要变更同一状态

其实就是——共享

Vuex环境搭建

1、安装vuex

安装:npm i vuex@3
注意Vue2一定要安装vuex3,如果是vue3可以直接npm i vuex安装的是vuex4,可以去package.json文件里看下vue的版本是啥,千万别输错了,不然会陷入痛苦的报错……

2、创建store文件

创建文件路径:src/store/index.js
在此文件中引入插件并使用vuex插件,使用vuex插件必须在引入store之前,如果在main.js中引入和使用vuex的话,由于js文件里所有的import语句都会提升到最开始执行,所以会报错。总结:引入store必须在Vue.use(Vuex)之后

//该文件用于创建Vuex中最为核心的store

//引入Vue
import Vue from 'vue';
//引入Vuex
import Vuex from 'vuex';//引入插件并使用插件
Vue.use(Vuex); //使用插件后就可以在vm,vc里使用store配置项

//准备actions,用于响应组件中的动作
const actions = {};

//准备mutations,用于操作数据(state)
const mutations = {};

//准备state,用于存储数据
const state = {};

//创建store
const store = new Vuex.Store({
    actions: actions,
    mutations, //简写
    state //简写
});

//导出store
export default store;

3、main.js引入store

JS执行的时候会把import提升到顶部,与摆放顺序无关,如果放在main.jsimport store from './store' 无论放到哪里都会比Vue.use(Vuex)先执行,要想把 Vue.use(Vuex) 要放到实例化之前只有放进index.js

//js文件里所有的import语句都会提升到最开始执行
// 引入Vue
import Vue from 'vue';
// 引入App
import App from './App.vue';
Vue.config.productionTip = false;

//引入store
import store from './store/index.js';

// 创建一个Vue实例
new Vue({
    el: '#app',
    store: store,  //或者直接写store
    render: h => h(App),
    beforeCreate() {
        Vue.prototype.$bus = this; //创建全局事件总线
    }
});

这样的话,vm和所有vc就都能碰到$store

Vuex的工作原理

1、原理图

请添加图片描述

这个工作流程用一个通俗的例子来解释:VC就是顾客,actions就是服务员,mutations就是厨师,state就是菜的原料。顾客(VC)来到店里,先告诉(dispatch)服务员(actions)要吃啥菜,然后服务员把菜单给(commit)厨师(mutations),完了之后厨师对菜的原料(state)来个加工(mutate),最后再给(render)顾客(VC)。

2、用案例解释工作原理

使用vuex实现求和案例:

下拉框能选择要操作的数字,分别用总数对这个数字进行加减等操作。

请添加图片描述

下面的操作不懂的时候可以翻到前面的原理图,结合图更容易理解哦~

1、首先数据应该放在state里面,所以把求和数据给 vuex的state对象

const state = {
    sum: 0,  //初始化数据
};

2、页面上插值语法就该用

<h1>当前求和为:{{  $store.state.sum  }}</h1>

3、在组件中的回调就可以用dispatch发给actionscommitmutations。注意如果没有业务逻辑,直接commit可以跳过actions直接给mutations(也就是上面原理图粉红色那条线)。

  • 此处加和减都没啥业务逻辑,直接跳过actions然后commit给mutations
  • 而奇数加和等一等再加存在业务逻辑,不能直接“加工”,所以要先用dispatch发给actionscommit给mutations

代码文件如下:

  • Count.vue:
<template>
  <div>
    <h1>当前求和为:{{ $store.state.sum }}</h1>
    <select v-model.number="addnum">
      <option value="1" checked>1</option>
      <!-- 不写冒号就是字符串但可以v-model.number -->
      <option value="2">2</option>
      <!-- 不写冒号就是字符串但可以v-model.number -->
      <option value="3">3</option>
      <!-- 不写冒号就是字符串但可以v-model.number -->
    </select>
    <button @click="add">+</button>
    <button @click="subtract">-</button>
    <button @click="oddAdd">当前求和为奇数再加</button>
    <button @click="waitAdd">等1秒再加</button>
  </div>
</template>

<script>
export default {
  name: 'Count',
  methods: {
    add() {
      //如果没有业务逻辑,直接commit给mutations
      this.$store.commit('JIA', this.addnum)
    },
    subtract() {
      this.$store.commit('JIAN', this.addnum)
    },
    oddAdd() {
      //如果有业务逻辑,先dispatch给actions,再commit给mutations
      this.$store.dispatch('oddAdd', this.addnum)
    },
    waitAdd() {
      this.$store.dispatch('waitAdd', this.addnum)
    },
  },
}
</script>

<style>
button {
  margin-left: 5px;
}
</style>
  • index.js
//该文件用于创建vuex中最核心的store
// 引入Vue
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
//准备actions:用于响应组件中的动作
const actions = {
  //是奇数就加
  //第一个参数是浓缩版的$store,方便你在这里调用commit把东西给mutations
  //第二个参数是传过来的数据
  oddAdd(context, value) {
    // console.log('actions中的oddadd被调用了')
    if (context.state.sum % 2) {
      context.commit('JIA', value)
    }
  },
  //等一等再加
  waitAdd(context, value) {
    // console.log('actions中的waitadd被调用了')
    setTimeout(() => {
      context.commit('JIA', value)
    }, 1000)
  },
}
//准备mutations:用于操作数据(state)
const mutations = {
  //加
  //第一个参数是state对象,第二个参数是传过来的数据  
  JIA(state, value) {
    // console.log('mutations中的JIA被调用了', state, value)
    state.sum += value
  },
  //减
  JIAN(state, value) {
    // console.log('mutations中的JIAN被调用了', state, value)
    state.sum -= value
  },
}
//准备state:用于存储数据
const state = {
  sum: 0, //初始化数据,当前的和
}

//创建store并暴露store
export default new Vuex.Store({
  actions,
  mutations,
  state,
})

3、注意点

  1. 一般来说都会把网络请求或其他业务逻辑写到actions里面
  2. 其实actions里面也可以操作数据,但是如果不在mutations里操作数据,而在actions里操作数据,vuex开发者工具会失效的
  3. 组件中也可以越过actions,即不写dispatch,直接编写commit把数据传给mutations

Vuex配置项

1、getters配置项

1、概念:当state中的数据需要经过加工后再使用时,可以使用getters加工,类似Vue中的计算属性computed。
2、使用:在store\index.js中追加getters配置,写函数,页面读的时候读的是返回值,这点其实也和计算属性很像。

......
//准备 getters ---用于将state中的数据进行加工
const getters = {
	bigSum(state){
		return state.sum * 10
	}
}

//创建并暴露store
export default new Vuex.Store({
	......
	getters
})

3、组件中读取数据:$store.getters.bigSum

<h1>当前求和放大十倍后为:{{ $store.getters.bigSum }}</h1>

4、其实state就类似于datagetters就类似computed

2、mapstate与mapGetters

我们之前要往页面上放state中的数据,还得$store.state.xxx,或者 $store.getters.xxx

<h1>当前求和为:{{  $store.state.sum  }}</h1>
<h1>当前求和放大十倍后为:{{  $store.getters.bigSum  }}</h1>
<h1>我在{{  $store.state.school  }}学习{{  $store.state.subject  }}</h1>

真的是非常麻烦啊,想简单点写,写成下面这样:

<h1>当前求和为:{{  sum  }}</h1>
<h1>当前求和放大十倍后为:{{  bigSum  }}</h1>
<h1>我在{{  school  }}学习{{  subject  }}</h1>
  • 可以用计算属性:
computed: {
    //靠程序员亲自写计算属性来实现state插值语法编码方便
    sum() {
          return this.$store.state.sum;
      },
      school() {
          return this.$store.state.school;
      },
      subject() {
          return this.$store.state.subject;
      },
      bigSum() {
         return this.$store.getters.bigSum;
     }
},

但是实际上亲自写计算属性来实现state插值语法computed这些东西复用性很差,vuex给我们提供了一个mapStatemapGetters方法:用于帮助我们把stategetters中的数据映射为计算属性

  • 用mapState和mapGetters方法

先引入这两个map方法: import {mapState,mapGetters} from 'vuex'
mapstatemapGetters用到computed里。

然后写法如下:

computed: {
    //截取mapState生成计算属性,从state读取数据。(对象写法)
    ...mapState({ sum: 'sum', school: 'school', subject: 'subject' }),
    //截取mapState生成计算属性,从state读取数据。(数组写法:生成的计算属性名和读取的属性名一样才能用)
    // ...mapState([sum, school, subject]),

    //截取mapGetters生成计算属性,从getters读取数据。(对象写法)
    ...mapGetters({ bigSum: 'bigSum' }),
    //截取mapGetters生成计算属性,从getters读取数据。(数组写法:生成的计算属性名和读取的属性名一样才能用)
    // ...mapGetters([bigSum]),
  },

注意:对象写法可以任意起名,键对应计算属性方法名,值对应state中的数据名,如果方法名和数据名一样,就可以用数组形式简写

3、mapActions与mapMutations

之前我们这个要从组件直接用commit传数据给mutations,或者用dispatch传给actions,都需要在methods里配置:

methods: {
    //程序员费老大劲写的传mutations代码
     add() {
          //如果没有业务逻辑,直接commit给mutations
          this.$store.commit('JIA', this.addnum);
      },
      subtract() {
          this.$store.commit('JIAN', this.addnum);
      },

    //程序员费老大劲写的传actions代码
      oddAdd() {
          //如果有业务逻辑,先dispatch给actions,再commit给mutations
          this.$store.dispatch('oddAdd', this.addnum);
      },
      waitAdd() {
          this.$store.dispatch('waitAdd', this.addnum);
      },
},

Vuex给我们提供了mapMutationsmapActions方法

mapMutations方法:用于帮助我们生成与mutations对话的方法,即:包含$store.commit(xxx)的函数。

mapActions方法:用于帮助我们生成与actions对话的方法,即:包含$store.dispatch(xxx)的函数。

先引入这两个map方法: import {mapMutations,mapActions} from 'vuex'
mapMutationsmapActions用到methods里。

写法如下:

methods: {
    //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
    ...mapMutations({ add: 'JIA', subtract: 'JIAN' }),
    //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(数组写法)
    // ...mapMutations(['JIA','JIAN']),

    //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
    ...mapActions({ oddAdd: 'oddAdd', waitAdd: 'waitAdd' }),
    //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组写法)
    // ...mapMutations(['oddAdd','waitAdd']),
  },

注意:mapActionsmapMutations使用时,其实创建的程序员费老大劲写的代码是不一样的,这两个玩意儿创建的东西是不带数据的,它创建的是这个:

 add(value) {
     this.$store.commit('JIA', value);
 },

若需要传递参数value,需要:在模板中绑定事件时传递好参数,否则参数value是事件对象。

<button @click="JIA(addnum)">+</button>
<button @click="JIAN(addnum)">-</button>
<button @click="oddAdd(addnum)">当前求和为奇数再加</button>
<button @click="waitAdd(addnum)">1秒再加</button>

注意:对象写法中,键是方法名,值是传给mutations或者actions方法名,如果方法名和传的方法名一样可以简写为数组形式

多组件共享数据

  • index.js
//该文件用于创建vuex中最核心的store
// 引入Vue
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
//准备actions:用于响应组件中的动作
const actions = {
  //是奇数就加
  oddAdd(context, value) {
    // console.log('actions中的oddadd被调用了')
    if (context.state.sum % 2) {
      context.commit('JIA', value)
    }
  },
  //等一等再加
  waitAdd(context, value) {
    // console.log('actions中的waitadd被调用了')
    setTimeout(() => {
      context.commit('JIA', value)
    }, 1000)
  },
}
//准备mutations:用于操作数据(state)
const mutations = {
  //加
  JIA(state, value) {
    // console.log('mutations中的JIA被调用了', state, value)
    state.sum += value
  },
  //减
  JIAN(state, value) {
    // console.log('mutations中的JIAN被调用了', state, value)
    state.sum -= value
  },
  ADD_PERSON(state, value) {
    state.personList.unshift(value)
  },
}
//准备state:用于存储数据
const state = {
  sum: 0, //初始化数据,当前的和
  school: 'potato',
  subject: '前端',
  personList: [{ id: '001', name: '张三' }],
}
//准备getters:用于将state中的数据进行加工
const getters = {
  bigSum(state) {
    return state.sum * 10
  },
}

//创建store并暴露store
export default new Vuex.Store({
  actions,
  mutations,
  state,
  getters,
})
  • Count.vue
<template>
  <div>
    <h1>当前求和为:{{ sum }}</h1>
    <h3>当前求和放大10倍:{{ bigSum }}</h3>
    <h3>我在{{ school }}学习{{ subject }}</h3>
    <h3 style="color: red">下方组件的总人数是:{{ personList.length }}</h3>
    <select v-model.number="addnum">
      <option value="1" checked>1</option>
      <!-- 不写冒号就是字符串但可以v-model.number -->
      <option value="2">2</option>
      <!-- 不写冒号就是字符串但可以v-model.number -->
      <option value="3">3</option>
      <!-- 不写冒号就是字符串但可以v-model.number -->
    </select>
    <button @click="add(addnum)">+</button>
    <button @click="subtract(addnum)">-</button>
    <button @click="oddAdd(addnum)">当前求和为奇数再加</button>
    <button @click="waitAdd(addnum)">等1秒再加</button>
  </div>
</template>

<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
  name: 'Count',
  computed: {
    //截取mapState生成计算属性,从state读取数据。(对象写法)
    ...mapState({
      sum: 'sum',
      school: 'school',
      subject: 'subject',
      personList: 'personList',
    }),
    //截取mapState生成计算属性,从state读取数据。(数组写法:生成的计算属性名和读取的属性名一样才能用)
    // ...mapState([sum, school, subject]),

    //截取mapGetters生成计算属性,从getters读取数据。(对象写法)
    ...mapGetters({ bigSum: 'bigSum' }),
    //截取mapGetters生成计算属性,从getters读取数据。(数组写法:生成的计算属性名和读取的属性名一样才能用)
    // ...mapGetters([bigSum]),
  },
  methods: {

    //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
    ...mapMutations({ add: 'JIA', subtract: 'JIAN' }),
    //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(数组写法)
    // ...mapMutations(['JIA','JIAN']),

    //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
    ...mapActions({ oddAdd: 'oddAdd', waitAdd: 'waitAdd' }),
    //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组写法)
    // ...mapMutations(['oddAdd','waitAdd']),
  },
}
</script>

<style>
button {
  margin-left: 5px;
}
</style>
  • Person.vue
<template>
  <div>
    <h1>人员列表</h1>
    <input type="text" placeholder="请输入名字" v-model="name" />
    <button @click="add">添加</button>
    <ul>
      <li v-for="p in personList" :key="p.id">{{ p.name }}</li>
    </ul>
  </div>
</template>

<script>
import { nanoid } from 'nanoid'
import { mapState } from 'vuex'
export default {
  name: 'Person',
  data() {
    return {
      name: '',
    }
  },
  computed: {
    ...mapState(['personList']),
  },
  methods: {
    add() {
      const personObj = { id: nanoid(), name: this.name }
      this.$store.commit('ADD_PERSON', personObj)
      this.name = ''
    },
  },
}
</script>

<style></style>

请添加图片描述

Vuex模块化+命名空间(项目常用)

1、模块化的概念及作用

如果我们写的state,actions什么的是服务于多个种类的,比如有管加法的,有管人员的,这样放到一起很乱,所以可以把它们拆开

作用:让代码更好维护,让多种数据分类更加明确。

2、使用方式

可以都写到index.js里,也可以每个命名空间分别拆成多个js文件

const countAbout = {
namespaced:true,//开启命名空间
state:{x:1},
mutations: { ... },
actions: { ... },
getters: {...}
}
}

const personAbout = {
namespaced:true,//开启命名空间
state:{ ... },
mutations: { ... },
actions: { ... }
}

const store = new Vuex.Store({
modules: {
 countAbout,
 personAbout
}
})

(1)开启命名空间后,组件中读取state数据

//方式一:自己直接读取
this.$store.state.personAbout.list
//方式二:借助mapState读取:
...mapState('countAbout',['sum','school','subject']), 
// 前边加个参数,意思是读取countAbout 里面的 sum,school.....

(2)开启命名空间后,组件中读取getters数据

//方式一:自己直接读取
this.$store.getters['personAbout/firstPersonName'] //注意这里的写法
//方式二:借助mapGetters读取:
...mapGetters('countAbout',['bigSum'])  

(3)开启命名空间后,组件中调用dispatch
如果不写namespaced则直接写addPersonWang就可以,但是开启了命名空间,必须要加上这个名字在前边,否则会报[vuex] unknown action type: addPersonWang的错误,而且前边这个名字必须和Vuex.Store({})配置项中的名字一致。

//方式一:自己直接dispatch
this.$store.dispatch('personAbout/addPersonWang',person)
//方式二:借助mapActions:
...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})

(4)开启命名空间后,组件中调用commit

//方式一:自己直接commit
this.$store.commit('personAbout/ADD_PERSON',person)
//方式二:借助mapMutations:
...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),

3、综合案例

相信大家看完都有点懵了,可以直接看这个综合案例,几乎囊括了上文的所有知识点。

此案例的Count.vue和Person.vue里的计算属性和方法分别采用了两种不同的写法,Count.vue引入了mapXXX方法,Person.vue没有,可以对比一下他们的区别,你就知道mapXXX有多香。

建议大家复制下来自己运行看看,然后尝试自己凭印象再写一次。
案例目录结构如下:

请添加图片描述

  • App.vue
<template>
  <div>
    <Count />
    <hr />
    <Person />
  </div>
</template>

<script>
import Count from './components/Count.vue'
import Person from './components/Person.vue'
export default {
  name: 'App',
  components: { Count, Person },
}
</script>

<style lang="css"></style>
  • main.js
// 引入Vue
import Vue from 'vue'
// 引入App
import App from './App.vue'
//引入插件
import vueResource from 'vue-resource'
//引入store
import store from './store'
// 关闭Vue的生产信息
Vue.config.productionTip = false
//使用插件
Vue.use(vueResource)
// 创建vm
new Vue({
  el: '#app',
  render: (h) => h(App),
  store,
  beforeCreate() {
    Vue.prototype.$bus = this //安装全局事件总线
  },
})
  • index.js
//该文件用于创建vuex中最核心的store
// 引入Vue
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)

import countAbout from './Count'
import personAbout from './Person'

//创建store并暴露store
export default new Vuex.Store({
  modules: {
    countAbout,
    personAbout,
  },
})
  • Count.js
export default {
  namespaced: true,
  state: {
    sum: 0, //初始化数据
    school: 'potato',
    subject: '前端',
  },
  getters: {
    bigSum(state) {
      return state.sum * 10
    },
  },
  mutations: {
    JIA(state, value) {
      state.sum += value
    },
    JIAN(state, value) {
      state.sum -= value
    },
  },
  actions: {
    oddAdd(context, value) {
      context.commit('JIA', value)
    },
    waitAdd(context, value) {
      setTimeout(() => {
        context.commit('JIA', value)
      }, 1000)
    },
  },
}
  • Count.vue
<template>
  <div>
    <h1>当前求和为:{{ sum }}</h1>
    <h3>当前求和放大10倍:{{ bigSum }}</h3>
    <h3>我在{{ school }}学习{{ subject }}</h3>
    <h3 style="color: red">下方组件的总人数是:{{ personList.length }}</h3>
    <select v-model.number="addnum">
      <option value="1" checked>1</option>
      <!-- 不写冒号就是字符串但可以v-model.number -->
      <option value="2">2</option>
      <!-- 不写冒号就是字符串但可以v-model.number -->
      <option value="3">3</option>
      <!-- 不写冒号就是字符串但可以v-model.number -->
    </select>
    <button @click="add(addnum)">+</button>
    <button @click="subtract(addnum)">-</button>
    <button @click="oddAdd(addnum)">当前求和为奇数再加</button>
    <button @click="waitAdd(addnum)">等1秒再加</button>
  </div>
</template>

<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
  name: 'Count',
  data() {
    return {
      addnum: 1,
    }
  },
  computed: {
    //数组写法
    ...mapState('countAbout', ['sum', 'school', 'subject']),
    //对象写法
    ...mapState('personAbout', { personList: 'personList' }),

    ...mapGetters('countAbout', ['bigSum']),
  },
  methods: {
    ...mapMutations('countAbout', { add: 'JIA', subtract: 'JIAN' }),
    ...mapActions('countAbout', ['oddAdd', 'waitAdd']),
  },
}
</script>

<style>
button {
  margin-left: 5px;
}
</style>
  • Person.js
import axios from 'axios'
import { nanoid } from 'nanoid'
export default {
  namespaced: true,
  state: {
    personList: [{ id: '001', name: '张三' }],
  },
  mutations: {
    ADD_PERSON(state, value) {
      state.personList.unshift(value)
    },
  },
  actions: {
    addPersonWu(context, value) {
      if (value.name.indexOf('吴') === 0) {
        context.commit('ADD_PERSON', value)
      } else {
        alert('添加的人不姓吴!')
      }
    },
    //发送ajax请求拿到名字
    addPersonServer(context) {
      axios.get('http://api.uixsj.cn/hitokoto/get?type=social').then(
        (response) => {
          context.commit('ADD_PERSON', { id: nanoid(), name: response.data })
        },
        (error) => {
          console.log(error.message)
        }
      )
    },
  },
  getters: {
    firstPersonName(state) {
      return state.personList[0].name
    },
  },
}
  • Person.vue
<template>
  <div>
    <h1>人员列表</h1>
    <input type="text" placeholder="请输入名字" v-model="name" />
    <button @click="addPerson">添加</button>
    <button @click="addPersonWu">添加一个姓吴的人</button>
    <button @click="addPersonServer">借助服务器随机生成并添加一个名字</button>
    <h2>第一个人的名字:{{ firstPersonName }}</h2>
    <ul>
      <li v-for="p in personList" :key="p.id">{{ p.name }}</li>
    </ul>
    <h2 style="color: red">Person里读sum:{{ add }}</h2>
  </div>
</template>

<script>
import { nanoid } from 'nanoid'
export default {
  name: 'Person',
  data() {
    return {
      name: '',
    }
  },
  computed: {
    personList() {
      return this.$store.state.personAbout.personList
    },
    add() {
      return this.$store.state.countAbout.sum
    },
    firstPersonName() {
      return this.$store.getters['personAbout/firstPersonName']
    },
  },
  methods: {
    addPerson() {
      const personObj = { id: nanoid(), name: this.name }
      this.$store.commit('personAbout/ADD_PERSON', personObj)
      this.name = ''
    },
    addPersonWu() {
      const personObj = { id: nanoid(), name: this.name }
      this.$store.dispatch('personAbout/addPersonWu', personObj)
      this.name = ''
    },
    addPersonServer() {
      this.$store.dispatch('personAbout/addPersonServer')
      this.name = ''
    },
  },
}
</script>

<style></style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/914734.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux之《进程》

文章目录 进程基础pcb状态优先级 进程的调度常见的调度算法 进程的通信方式 进程基础 pcb 操作系统在创建进程时&#xff0c;会给进程分配一块PCB&#xff08;process control block 进程控制块&#xff09;&#xff0c;对应linux上就是task_struct结构体&#xff0c;PCB里面…

非root用户下安装OpenSSL

1.OpenSSL下载 https://www.openssl.org/source/ 2.将下载好的压缩包上传至linux 3.解压压缩包 tar -xvf openssl-3.0.7.tar.gz 4.创建openssl安装目录 mkdir /home/openssl 5.进入安装包解压后的目录 cd /home/openssl-3.0.7.tar.gz 6.安装openssl&#xff0c;注意命令是…

深度学习论文: WinCLIP: Zero-/Few-Shot Anomaly Classification and Segmentation

深度学习论文: WinCLIP: Zero-/Few-Shot Anomaly Classification and Segmentation WinCLIP: Zero-/Few-Shot Anomaly Classification and Segmentation PDF: https://arxiv.org/pdf/2303.14814.pdf PyTorch代码: https://github.com/shanglianlm0525/CvPytorch PyTorch代码: h…

hexo优化bilibili显示

首发博客地址 https://blog.zysicyj.top/ It has been 1086 days since the last update, the content of the article may be outdated. 这篇文章属于转载&#xff0c;原地址为Hexo博客引用B站视频并自动适配 在进行引用B站用iframe方式引入视频时发现&#xff0c;通过默认的方…

Python科研绘图--Task02

目录 图形元素 画布 (fifigure)。 坐标图形 (axes)&#xff0c;也称为子图。 轴 (axis) &#xff1a;数据轴对象&#xff0c;即坐标轴线。 刻度 (tick)&#xff0c;即刻度对象。 图层顺序 轴比例和刻度 轴比例 刻度位置和刻度格式 坐标系 直角坐标系 极坐标系 地理…

[oneAPI] 基于BERT预训练模型的SQuAD问答任务

[oneAPI] 基于BERT预训练模型的SQuAD问答任务 Intel Optimization for PyTorch and Intel DevCloud for oneAPI基于BERT预训练模型的SQuAD问答任务语料介绍数据下载构建 模型 结果参考资料 比赛&#xff1a;https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Int…

多维时序 | MATLAB实现SABO-CNN-GRU-Attention多变量时间序列预测

多维时序 | MATLAB实现SABO-CNN-GRU-Attention多变量时间序列预测 目录 多维时序 | MATLAB实现SABO-CNN-GRU-Attention多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 多维时序 | MATLAB实现SABO-CNN-GRU-Attention多变量时间序列预测。 模型描…

算法通关村第九关——中序遍历与搜索树

1 中序遍历和搜索树原理 二叉搜索树按照中序遍历正好是一个递增序列。其比较规范的定义是&#xff1a; 若它的左子树不为空&#xff0c;则左子树上所有节点的值均小于它的根节点的值&#xff1b;若它的右子树不为空&#xff0c;则右子树所有节点的值均大于它的根节点的值&…

17.2 【Linux】通过 systemctl 管理服务

systemd这个启动服务的机制&#xff0c;是通过一支名为systemctl的指令来处理的。跟以前 systemV 需要 service / chkconfig / setup / init 等指令来协助不同&#xff0c; systemd 就是仅有systemctl 这个指令来处理而已。 17.2.1 通过 systemctl 管理单一服务 &#xff08;s…

升级还是不升级?iPhone 15和iPhone 14 Plus性能比较

预览iPhone 15 Pro Max与三星Galaxy S23 Ultra之战是有正当理由的。显然,三星的旗舰智能手机为2023年的所有其他旗舰产品定下了基调——由于其超长的电池寿命和一流的摄像头,证明了它是最受欢迎的产品。 毫不奇怪,Galaxy S23 Ultra不仅是最好的照相手机之一,也是花钱能买到…

docker之DockerFile与网络

目录 DockerFile 构建步骤 基础知识 指令 实战&#xff1a;构建自己的centos 第一步&#xff1a;编写dockerfile文件 第二步&#xff1a;构建镜像文件 docker网络 原理 功能 网络模式 host模式 container模式 none模式 bridge模式 DockerFile dockerfile 是用来…

wireshark进行网络监听

一、实验目的&#xff1a; 1&#xff09;掌握使用CCProxy配置代理服务器&#xff1b; 2&#xff09;掌握使用wireshark抓取数据包&#xff1b; 3&#xff09;能够对数据包进行简单的分析。 二、预备知识&#xff1a; 包括监听模式、代理服务器、中间人攻击等知识点&#xf…

【广州华锐视点】VR教学课件编辑工具有哪些用处?

随着科技的不断发展&#xff0c;教育领域也在不断地进行创新。在众多的创新技术中&#xff0c;虚拟现实(VR)技术的应用为教育带来了前所未有的变革。广州华锐视点开发的VR教学课件编辑工具作为一种新型的教育工具&#xff0c;可以为我们的教学提供许多支持&#xff0c;从而提升…

redis基本介绍以及在node中使用

文章目录 引言一、什么是redis1. redis简介2. redis的特点3. redis的应用场景 二、redis在windows下安装1. 下载安装2.验证是否安装成功3. 配置环境变量 三、redis-cli常用命令介绍1. redis-cli2. keys *3. set key value4. get key5. exists key6. del key7. info8. flushdb9.…

硬件知识累计 TVS管选型 防止浪涌

1. 首先了解 浪涌 1.1 浪涌是什么 浪涌&#xff08;electrical surge&#xff09;&#xff0c;顾名思义就是瞬间出现超出稳定值的峰值&#xff0c;它包括浪涌电压和浪涌电流。 浪涌也叫突波&#xff0c;顾名思义就是超出正常工作电压的瞬间过电压。本质上讲&#xff0c;浪涌是…

数据结构--递归与分治

汉诺塔分析&#xff1a; 以三层进行分析&#xff0c;大于三层分析情况是一样的。 #include <stdio.h>void move(int n,char x,char y,char z) {if(1 n){printf("%c---------->%c\n",x,z);}else{move(n-1,x,z,y);//将第n-1个盘子从x借助z移动到y printf(&q…

HBuilderX学习--运行第一个项目

HBuilderX&#xff0c;简称HX&#xff0c;是轻如编辑器、强如IDE的合体版本&#xff0c;它及轻巧、极速&#xff0c;强大的语法提示&#xff0c;提供比其他工具更优秀的vue支持大幅提升vue开发效率于一身(具体可看官方详细解释)… 一&#xff0c;HBuilderX下载安装 官网地址 …

前端基础(ES6 模块化)

目录 前言 复习 ES6 模块化导出导入 解构赋值 导入js文件 export default 全局注册 局部注册 前言 前面学习了js&#xff0c;引入方式使用的是<script s"XXX.js">&#xff0c;今天来学习引入文件的其他方式&#xff0c;使用ES6 模块化编程&#xff0c;…

浅谈泛在电力物联网发展形态与技术挑战

安科瑞 华楠 摘 要&#xff1a;泛在电力物联网是当前智能电网发展的一个方向。首先&#xff0c;总结了泛在电力物联网的主要作用和价值体现&#xff1b;其次&#xff0c;从智能电网各个环节概述了物联网技术在电力领域的已有研究和应用基础&#xff1b;进而&#xff0c;构思并…

Java接入支付宝支付

本文只接入了支付宝中的APP支付&#xff0c;如果要拓展更多支付方式的的话&#xff0c;请看文末补充 项目支付流程 前端发起创建订单请求后端接受请求创建订单&#xff0c;并将订单参数进行支付宝对应签名并返回前端拿到签名后调起支付宝支付 本文主要写的就是2的过程 前期准…