尚硅谷 Vue2.0 + Vue3.0 入门到精通教程学习笔记 (五)

第五章:Vuex

5.1  理解 vuex

5.1.1  vuex是什么 

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

2. GitHub 地址:GitHub - vuejs/vuex: ️ Centralized State Management for Vue.js.

尚硅谷 Vue2.0 + Vue3.0 入门到精通教程学习笔记 (五)_第1张图片

 尚硅谷 Vue2.0 + Vue3.0 入门到精通教程学习笔记 (五)_第2张图片

5.1.2  什么时候使用 Vuex

1. 多个组件依赖于同一状态

2. 来自不同组件的行为需要变更同一状态

5.1.3  求和案例:纯 Vue 版

  • src/main.js
// 引入 vue
import Vue from 'vue'
// 引入App
import App from './App.vue'
//引入插件
import vueResource from 'vue-resource'
// 关闭Vue的生产提示
Vue.config.productionTip = false
// 使用插件
Vue.use(vueResource)

//创建vm
new Vue({
    el: '#app',
    render: h => h(App),
    beforeCreate() {
        Vue.prototype.$bus = this
    }
})
  • src/App.vue



  • src/components/Count.vue





效果:

尚硅谷 Vue2.0 + Vue3.0 入门到精通教程学习笔记 (五)_第3张图片

5.1.4  Vuex 工作原理图

尚硅谷 Vue2.0 + Vue3.0 入门到精通教程学习笔记 (五)_第4张图片

5.2  求和案例:vuex 版

5.2.1  搭建 vuex 环境

1. 下载 Vuexnpm i vuex

【注】2022 年 2 月 7 日,vue3 成为了默认版本,执行代码“ npm i vuex ”直接安装的是 vue3,相对应的 vuex 也升级为 4以上的 版本。因此,执行上述安装 vuex 代码会直接安装 vuex4,而 vuex4 只能在 vue3 中使用,若在 vue2 中安装 vuex4 则会报错,如下图:

尚硅谷 Vue2.0 + Vue3.0 入门到精通教程学习笔记 (五)_第5张图片

简而言之:

vue2 中,要用 vuex 的 3 版本 ;

vue3 中,要用 vuex 的 4 版本 ;

安装 vuex3 的代码如下:

npm i vuex@3

2. 创建 src/store/index.js

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
   
//准备actions对象——响应组件中用户的动作
const actions = {}
//准备mutations对象——修改state中的数据
const mutations = {}
//准备state对象——保存具体的数据
const state = {}
   
//创建并暴露store
export default new Vuex.Store({
  actions,
  mutations,
  state
})

3.  src/main.js 中创建 vm 时传入 store 配置项

// 引入 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,
})

5.2.2  求和案例 — vuex 版

  • src/components/Count.vue





  •  src/App.vue



  • src/store/index.js
// 该文件用于创建 Vuex 中最为核心的 store'
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
// 准备 actions——用于响应组件中的动作
const actions = {
  jiaOdd(context, value) {
    console.log('actions中的jiaOdd被调用了')
    if (context.state.sum % 2) {
      context.commit('JIA', value)
    }
  },
  jiaWait(context, value) {
    console.log('actions中的jiaWait被调用了')
   setTimeout(() => {
         context.commit('JIA', value)
      }, 500)
  },
}
// 准备 mutations——用于操作数据(state)
const mutations = {
  JIA(state,value) {
    // console.log('actions中的jia被调用了',state,value)
    state.sum+=value
  },
  JIAN(state,value) {
    // console.log('actions中的jian被调用了',state,value)
    state.sum-=value
  }
}
// 准备 state——用于存储数据
const state = {
   sum: 0, // 当前的和
}

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

5.3  Vuex 开发者工具的使用

5.3.1  Vuex 开发者工具

浏览器安装完 Vue开发者工具(Vue.js.devtools)后,里面包含着 Vuex 开发者工具,不需要额外下载。

5.3.2  Vue 开发者工具界面

尚硅谷 Vue2.0 + Vue3.0 入门到精通教程学习笔记 (五)_第6张图片

 5.3.3  页面按钮详解

尚硅谷 Vue2.0 + Vue3.0 入门到精通教程学习笔记 (五)_第7张图片

●  选择区按钮

①  Base State

里面记录的是 state 里面的初始数据

②  绿色区域

绿色区域所在的哪一行,页面显示该行的数据

③ "JIA"

每一个 “JIA”代表的是一个mutation,JIA 是我们自己定义的 mutation 的名字,这也说明了 vuex 工作图中开发者工具 devtools 是直接操作 mutation 

尚硅谷 Vue2.0 + Vue3.0 入门到精通教程学习笔记 (五)_第8张图片

④  选择区的这三个按钮:

◆  左边的按钮:这个类似于下载的按钮是合并数据,点击之后它会把当前及其前面的 mutation 方法删除,把他们影响后的数据放在 Base State 中;

◆  中间的按钮:这个类似于禁止的按钮是撤回该 mutation,点击后删除此项 mutations 方法以及其依赖项;

◆  右边这个类似于时间的按钮是撤回按钮,页面退到执行此 mutation 方法之前的状态。

●  展示区按钮

 ◆  左边的按钮:Export 按钮,点击此按钮即可导出数据,比如我们需要把数据导出来让其他程序员看,可以点击 Export 按钮,这样 State 中的数据就会在我们的剪切板里面。

 ◆  右边的按钮:Import 按钮,点击此按钮可导入数据,比如我们需要导入其他程序员的数据,可以点击 Import 按钮,我们通过 ctrl +v 就能把数据存在 state 中。

Vuex 基本使用总结 :

1. 初始化数据、配置 actions 、配置 mutations ,操作文件 store.js

 //引入Vue核心库
   import Vue from 'vue'
   //引入Vuex
   import Vuex from 'vuex'
   //引用Vuex
   Vue.use(Vuex)
   
   const actions = {
       //响应组件中加的动作
   	jia(context,value){
   		// console.log('actions中的jia被调用了',miniStore,value)
   		context.commit('JIA',value)
   	},
   }
   
   const mutations = {
       //执行加
   	JIA(state,value){
   		// console.log('mutations中的JIA被调用了',state,value)
   		state.sum += value
   	}
   }
   
   //初始化数据
   const state = {
      sum:0
   }
   
   //创建并暴露store
   export default new Vuex.Store({
   	actions,
   	mutations,
   	state,
   })

 2. 组件中读取 vuex 中的数据:$store.state.sum

 3. 组件中修改 vuex 中的数据:

$store.dispatch('action中的方法名',数据 或 $store.commit('mutations中的方法名',数据)

备注:若没有网络请求或其他业务逻辑,组件中也可以越过 actions,即不写 dispatch ,直接编写 commit

5.4  求和案例:getters配置项

  • src/components/Count.vue





  •  src/store/index.js
//该文件用于创建 Vuex 中最为核心的 store'

import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//准备actions——用于响应组件中的动作
const actions = {
  jiaOdd(context, value) {
    console.log('actions中的jiaOdd被调用了')
    if (context.state.sum % 2) {
      context.commit('JIA', value)
    }
  },
  jiaWait(context, value) {
    console.log('actions中的jiaWait被调用了')
   setTimeout(() => {
         context.commit('JIA', value)
      }, 500)
  },
}
//准备mutations——用于操作数据(state)
const mutations = {
  JIA(state,value) {
    state.sum+=value
  },
  JIAN(state,value) {
    state.sum-=value
  }
}
//准备state——用于存储数据
const state = {
   sum: 0, // 当前的和
}
//准备getters——用于将state中的数据进行加工
const getters = {
  bigSum(state) {
    return state.sum*10
  }
}
Vue.use(Vuex)
//创建并暴露store
export default  new Vuex.Store({
  actions,
  mutations,
  state,
  getters
})

效果:

尚硅谷 Vue2.0 + Vue3.0 入门到精通教程学习笔记 (五)_第9张图片

总结:

getters 的使用

  1. 概念:当 state 中的数据需要经过加工后再使用时,可以使用 getters 加工。

  2. 在 store.js 中追加 getters 配置

const getters = {
   	bigSum(state){
   		return state.sum * 10
   	}
   }
   
   //创建并暴露store
   export default new Vuex.Store({
   	......
   	getters
})

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

5.5  求和案例:四个 map 方法的使用 

5.5.1  求和案例:mapState 与 mapGetters

  • src/components/Count.vue





  •  src/store/index.js
// 该文件用于创建 Vuex 中最为核心的 store'

import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
// 准备 actions——用于响应组件中的动作
const actions = {
  jiaOdd(context, value) {
    console.log('actions中的jiaOdd被调用了')
    if (context.state.sum % 2) {
      context.commit('JIA', value)
    }
  },
  jiaWait(context, value) {
    console.log('actions中的jiaWait被调用了')
   setTimeout(() => {
         context.commit('JIA', value)
      }, 500)
  },
}
// 准备 mutations——用于操作数据(state)
const mutations = {
  JIA(state,value) {
    state.sum+=value
  },
  JIAN(state,value) {
    state.sum-=value
  }
}
// 准备 state——用于存储数据
const state = {
  sum: 0, // 当前的和
  school: '尚硅谷',
  subject:'前端'
}
// 准备getters——用于将state中的数据进行加工
const getters = {
  bigSum(state) {
    return state.sum*10
  }
}
Vue.use(Vuex)
// 创建并暴露store
export default  new Vuex.Store({
  actions,
  mutations,
  state,
  getters
})

效果:

尚硅谷 Vue2.0 + Vue3.0 入门到精通教程学习笔记 (五)_第10张图片

总结:

1. mapState 方法:用于帮助我们映射 state 中的数据为计算属性

computed: {
       //借助mapState生成计算属性:sum、school、subject(对象写法)
        ...mapState({sum:'sum',school:'school',subject:'subject'}),
            
       //借助mapState生成计算属性:sum、school、subject(数组写法)
       ...mapState(['sum','school','subject']),
},

 2. mapGetters方法:用于帮助我们映射 getters 中的数据为计算属性

computed: {
       //借助mapGetters生成计算属性:bigSum(对象写法)
       ...mapGetters({bigSum:'bigSum'}),
   
       //借助mapGetters生成计算属性:bigSum(数组写法)
       ...mapGetters(['bigSum'])
},

5.5.2  mapActions 与 mapMutations

  • src/components/Count.vue





总结:

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

methods:{
    //靠mapActions生成:incrementOdd、incrementWait(对象形式)
    ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})

    //靠mapActions生成:incrementOdd、incrementWait(数组形式)
    ...mapActions(['jiaOdd','jiaWait'])
}

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

methods:{
    //靠mapActions生成:increment、decrement(对象形式)
    ...mapMutations({increment:'JIA',decrement:'JIAN'}),
    
    //靠mapMutations生成:JIA、JIAN(对象形式)
    ...mapMutations(['JIA','JIAN']),
}

备注:mapActions mapMutations 使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。

5.6  多组件共享数据

  • src/App.vue



  • src/store/index.js
// 该文件用于创建 Vuex 中最为核心的 store'

import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
// 准备 actions——用于响应组件中的动作
const actions = {
  jiaOdd(context, value) {
    console.log('actions中的jiaOdd被调用了')
    if (context.state.sum % 2) {
      context.commit('JIA', value)
    }
  },
  jiaWait(context, value) {
    console.log('actions中的jiaWait被调用了')
   setTimeout(() => {
         context.commit('JIA', value)
      }, 500)
  },
}
// 准备 mutations——用于操作数据(state)
const mutations = {
  JIA(state,value) {
    state.sum+=value
  },
  JIAN(state,value) {
    state.sum-=value
  },
  ADD_PERSON(state, value) {
    console.log(' mutations中的ADD_PERSON被调用了')
    state.personList.unshift(value)
  }
}
// 准备 state——用于存储数据
const state = {
  sum: 0, // 当前的和
  school: '尚硅谷',
  subject: '前端',
  personList: [
    {id:'001',name:'张三  '}
  ]
}
// 准备getters——用于将state中的数据进行加工
const getters = {
  bigSum(state) {
    return state.sum*10
  }
}
Vue.use(Vuex)
// 创建并暴露store
export default  new Vuex.Store({
  actions,
  mutations,
  state,
  getters
})
  • src/components/Count.vue





  • src/components/Person.vue



效果:

尚硅谷 Vue2.0 + Vue3.0 入门到精通教程学习笔记 (五)_第11张图片

 

5.7  模块化+命名空间

  • src/store/index.js
// 该文件用于创建 Vuex 中最为核心的 store'

import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
import countOptions from './count'
import personOptions from './person'
// 应用Vuex插件

Vue.use(Vuex)
// 创建并暴露store
export default  new Vuex.Store({
  modules: {
    countAbout:countOptions,
    personAbout:personOptions
  }
})
  • src/store/count.js
// 求和相关的配置
export default{
  namespaced:true,
  actions: {
    jiaOdd(context, value) {
    console.log('actions中的jiaOdd被调用了')
    if (context.state.sum % 2) {
      context.commit('JIA', value)
    }
  },
  jiaWait(context, value) {
    console.log('actions中的jiaWait被调用了')
   setTimeout(() => {
         context.commit('JIA', value)
      }, 500)
    },
  },
  mutations: {
    JIA(state, value) {
    state.sum+=value
  },
  JIAN(state,value) {
    state.sum-=value
  },
  },
  state: {
    sum: 0, // 当前的和
    school: '尚硅谷',
    subject: '前端',
   },
  getters: {
    bigSum(state) {
    return state.sum*10
    }
  },
}
  • src/store/person.js
// 人员管理相关的配置
import axios from 'axios'
import { nanoid } from 'nanoid'
export default {
  namespaced:true,
  actions: {
    addPersonWang(context, value) {
      if (value.name.indexOf('王') === 0) {
        context.commit('ADD_PERSON', value)
      } else {
        alert('添加的人必须姓王!')
      }
    },
    addPersonServer(context) {
      axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(
        response => {
          context.commit('ADD_PERSON', {id:nanoid(),name:response.data})
        },
        error => {
          alert(error.message)
        }
       )
    }
  },
  mutations: {
    ADD_PERSON(state, value) {
    console.log(' mutations中的ADD_PERSON被调用了')
    state.personList.unshift(value)
    }
  },
  state: {
    personList: [
    {id:'001',name:'张三  '}
  ]
  },
  getters: {
    firstPersonName(state) {
      return state.personList[0].name
     }
   }
}
  • src/components/Count.vue





  • src/components/Person.vue



效果:

尚硅谷 Vue2.0 + Vue3.0 入门到精通教程学习笔记 (五)_第12张图片

总结:

模块化+命名空间

1. 目的:让代码更好维护,让多种数据分类更加明确。

2. 修改 store.js

const countAbout = {
  namespaced:true,//开启命名空间
  state:{x:1},
  mutations: { ... },
  actions: { ... },
  getters: {
    bigSum(state){
       return state.sum * 10
    }
  }
}

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

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

3. 开启命名空间后,组件中读取 state 数据:

// 方式一:自己直接读取

this.$store.state.personAbout.list

// 方式二:借助 mapState 读取:

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

4. 开启命名空间后,组件中读取 getters 数据:

// 方式一:自己直接读取

this.$store.getters['personAbout/firstPersonName']

// 方式二:借助 mapGetters 读取:

...mapGetters('countAbout',['bigSum'])

5. 开启命名空间后,组件中调用 dispatch

// 方式一:自己直接 dispatch

this.$store.dispatch('personAbout/addPersonWang',person)

// 方式二:借助 mapActions : 

...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})

 6. 开启命名空间后,组件中调用 commit

// 方式一:自己直接 commit

 this.$store.commit('personAbout/ADD_PERSON',person)

// 方式二:借助 mapMutations

 ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),

★★★ 欢迎批评指正!

★★★ 参考:

1.Vue学习第24天——Vuex开发者工具的使用

2. Vue学习笔记(尚硅谷天禹老师) 

你可能感兴趣的:(Vue学习笔记和案例,学习,vue.js,前端,前端框架)