vuex是vue的一个插件,是一种组间通信的方式,整个项目可以共享数据和方法

安装:

npm i vuex@3

VueX笔记_ios

编辑

如上图所示,如果需求非常简单,我们就可以绕过dispatch方法,直接去调用commit方法

dispatch方法用于编写业务代码

vuex的配置目录:src/store/index.js

// 响应组件中的动作
const actions = {
    jian(context, val) {
        context.commit('JIAN', val)
    },
    jianOdd(context, val) {
        if (context.state.sum % 2 === 0) return
        context.commit('JIA', val)
    },
    incrWait(context, val) {
        setTimeout(() => {
            context.commit('JIA', val)
        }, 2000)
    },
}
// 用于真实操作数据
const mutations = {
    JIA(state, val) {
        state.sum += val
    },
    JIAN(state, val) {
        state.sum -= val
    },
}
// 用于存储数据
const state = {
    sum: 0,
}
import Vuex from 'vuex'
import Vue from 'vue'

Vue.use(Vuex)
// 默认暴露,这里Store要大写
export default new Vuex.Store({actions, mutations, state})

main.js引入vuex:

import Vue from 'vue'
import App from './App.vue'
// 默认会引入store目录下的index.js文件
import store from './store'
// 关闭vue生产的提示
Vue.config.productionTip = false

new Vue({
    render: h => h(App),
    // 这里要小写
    store,
}).$mount('#app')

使用案例:

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

this.$store.commit('JIA', this.n)

this.$store.dispatch('jianOdd', this.n)

getters的用法:

伪代码

// index.js
const getters = {
    bigSum(state) {
        return state.sum * 10
    }
}
export default new Vuex.Store({actions, mutations, state, getters})
// Count.vue
<h1>当前求和的数为:{{ $store.getters.bigSum }}</h1>

使用的时候用mapState的简写:

computed: {
    ...mapState({he: 'sum', xuexiao: 'school', xueke: 'subject'}),
  }

<h1>学校:{{ xuexiao}}</h1>

2、使用数组的方式引入:

...mapState(['sum','subject','school']),

通过mapState的语法格式,从而得知mapGetters语法格式

mapMutations:

methods: {
  ...mapMutations(['JIA','JIAN']),
},

<button @click="JIA(n)">+</button>

mapActions的用法也相似,这里就不赘述了

推荐前端生成随机数的插件nanoid:

推荐前端日期格式插件dayjs

import {nanoid} from "nanoid";

模块化:

使用命名空间,为了解决store里面太臃肿的问题

推荐一个很厉害了的api:一言API (uixsj.cn)

count.js:

// 求和相关配置
export default  {
    // 命名空间
    namespaced: true,
    state: {
        sum: 0,
        school: '尚硅谷',
        subject: '前端',
    },
    getters: {
        bigSum(state) {
            return state.sum * 10
        }
    },
    actions: {
        jianOdd(context, val) {
            if (context.state.sum % 2 === 0) return
            context.commit('JIA', val)
        },
        incrWait(context, val) {
            setTimeout(() => {
                context.commit('JIA', val)
            }, 2000)
        },
    },
    mutations: {
        JIA(state, val) {
            state.sum += val
        },
        JIAN(state, val) {
            state.sum -= val
        },
    }
}

person.js:

// 人员相关配置
import axios from "axios";
import {nanoid} from "nanoid";

export default {
    // 命名空间
    namespaced: true,
    state: {
        persons: [
            {id: 'VeZvrijiOTzqi7NNu6U0Q', name: 'tom'}
        ],
    },
    getters: {
        firstPersonName(state) {
            return state.persons[0].name
        },
    },
    actions: {
        addPersonWang(context, val) {
            // context上下文
            if (val.name.indexOf('王') === 0) {
                context.commit('ADD_PERSON', val)
            } else {
                alert('添加的用户必须行姓王')
            }
        },
        addPersonServer(context) {
            axios.get('https://api.uixsj.cn/hitokoto/get').then(res => {
                // commit就是调用mutations
                context.commit('ADD_PERSON', {id: nanoid(), name: res.data})
            }, err => {
                alert(err.message)
            })
        },
    },
    mutations: {
        ADD_PERSON(state, val) {
            state.persons.push(val)
        },
    },
}

main.js:

import count from "./count";
import person from "./person";

import Vuex from 'vuex'
import Vue from 'vue'

Vue.use(Vuex)
// 默认暴露
export default new Vuex.Store({
    modules: {countOptions: count, personOptions: person}
})

Count.vue:

<template>
  <div>
    <div>
      <h1>当前求和的数为:{{ sum }}</h1>
      <h1>放大十倍的数为:{{ bigSum }}</h1>
      <h1>学校:{{ school }}</h1>
      <h1>学科:{{ subject }}</h1>
      <select v-model.number="n">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
      </select>
      <button @click="JIA(n)">+</button>
      <button @click="JIAN(n)">-</button>
      <button @click="jianOdd(n)">奇数才加</button>
      <button @click="incrWait(n)">延时加</button>
    </div>

    <div>
      下方组件的总人数是:{{ persons.length }}
    </div>

    <hr/>
  </div>
</template>

<script>
import {mapActions, mapGetters, mapMutations, mapState} from 'vuex'

export default {
  name: "Count",
  data() {
    return {
      n: 1
    }
  },
  methods: {
    ...mapMutations('countOptions', ['JIA', 'JIAN']),
    ...mapActions('countOptions', ['jianOdd', 'incrWait']),
  },
  computed: {
    ...mapState('countOptions', ['sum', 'school', 'subject']),
    ...mapState('personOptions', ['persons']),
    ...mapGetters('countOptions', ['bigSum']),
  },
  mounted() {
  },
}
</script>

<style scoped>

</style>

Person.vue:

<template>
  <div>
    <div>
      上方组件的求和为:{{ sum }}
    </div>

    <div>
      <input v-model="name" type="text">
      <button @click="add">添加</button>
      <button @click="addPersonWang">添加一个姓王的用户</button>
      <button @click="addPersonServer">添加一个随机的用户</button>
    </div>

    <div>
      <ul>
        <li v-for="i in persons">{{ i.name }}</li>
      </ul>
    </div>
    <div>第一个用户的名字:{{ firstPersonName }}</div>
  </div>
</template>

<script>
import {mapState} from "vuex";
import {nanoid} from "nanoid";

export default {
  name: "Person",
  data() {
    return {
      name: '',
    }
  },
  computed: {
    sum() {
      return this.$store.state.countOptions.sum
    },
    // 1、全部导入的简写方式
    ...mapState('personOptions', ['persons']),
    firstPersonName() {
      return this.$store.getters['personOptions/firstPersonName']
    }
  },
  methods: {
    add() {
      const personObj = {id: nanoid(), name: this.name}
      // 1、导入后简写的方式
      // this.ADD_PERSON(personObj)
      // 2、单独使用一个方法的方式
      this.$store.commit('personOptions/ADD_PERSON', personObj)
      this.name = ''
    },
    //1、简写的导入
    // ...mapMutations('personOptions', ['ADD_PERSON']),
    addPersonWang() {
      const personObj = {id: nanoid(), name: this.name}
      this.$store.dispatch('personOptions/addPersonWang', personObj)
      this.name = ''
    },
    addPersonServer(){
      this.$store.dispatch('personOptions/addPersonServer')
    },
  }
}
</script>

<style scoped>

</style>