Vue 2.3

📅 发布时间:2026/7/10 9:20:25 👁️ 浏览次数:
Vue 2.3
一、核心概念 - state 状态目标明确如何给仓库提供数据如何使用仓库的数据1.提供数据State提供唯一的公共数据源所有共享的数据都要统一放到Store中的State中存储。 在state对象中可以添加我们要共享的数据。2.使用数据① 通过 store 直接访问② 通过辅助函数二、核心概念 - mutations1.目标明确vuex同样遵循单向数据流组件中不能直接修改仓库的数据通过strict: true可以开启严格模式1定义mutations对象对象中存放修改state的方法2组件中提交调用mutations2.目标掌握mutations传参语法提交mutation是可以传递参数的this.$store.commit( xxx, 参数 )1提供mutation函数 (带参数 - 提交载荷 payload )2页面中提交调用mutationTips:提交参数只能一个如果有多个参数包装成一个对象传递3.核心概念 - mutations - 练习1目标减法功能巩固mutations传参语法2目标实时输入实时更新巩固mutations传参语法三、辅助函数 - mapMutations目标掌握辅助函数mapMutations映射方法mapMutations和mapState很像它是把位于mutations中的方法提取了出来映射到组件methods四、核心概念 - actions目标明确actions的基本语法处理异步操作。需求: 一秒钟之后, 修改state的count成 666。说明mutations 必须是同步的 (便于监测数据变化记录调试)五、辅助函数 - mapActions目标掌握辅助函数mapActions映射方法mapActions是把位于actions中的方法提取了出来映射到组件methods中六、核心概念 - getters目标掌握核心概念 getters 的基本语法 (类似于计算属性)说明除了state之外有时我们还需要从state中派生出一些状态这些状态是依赖state的此时会用到getters例如state中定义了list为 1-10 的数组组件中需要显示所有大于5的数据1.定义 getters2.访问getters1通过store访问getters2通过辅助函数mapGetters映射七、核心概念 - 模块 module (进阶语法)1.目标掌握核心概念 module 模块的创建1由于vuex使用单一状态树应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时store对象就有可能变得相当臃肿。(当项目变得越来越大的时候Vuex会变得越来越难以维护)2模块拆分user模块: store/modules/user.js2.目标掌握模块中 state 的访问语法尽管已经分模块了但其实子模块的状态还是会挂到根级别的state中属性名就是模块名使用模块中的数据1直接通过模块名访问$store.state.模块名.xxx2通过mapState映射默认根级别的映射mapState([ xxx ])子模块的映射mapState(模块名, [xxx])- 需要开启命名空间3.目标掌握模块中 getters 的访问语法使用模块中getters中的数据1直接通过模块名访问$store.getters[模块名/xxx ]2通过mapGetters映射默认根级别的映射mapGetters([ xxx ])子模块的映射mapGetters(模块名, [xxx])- 需要开启命名空间4.目标掌握模块中 mutation 的调用语法注意默认模块中的mutation和actions会被挂载到全局需要开启命名空间才会挂载到子模块。 调用子模块中mutation1直接通过store调用$store.commit(模块名/xxx , 额外参数)2通过mapMutations映射默认根级别的映射mapMutations([ xxx ])子模块的映射mapMutations(模块名, [xxx])- 需要开启命名空间5.目标掌握模块中 action 的调用语法 (同理 - 直接类比 mutation 即可)注意默认模块中的mutation和actions会被挂载到全局需要开启命名空间才会挂载到子模块。 调用子模块中action1直接通过store调用$store.dispatch(模块名/xxx , 额外参数)2通过mapActions映射默认根级别的映射mapActions([ xxx ])子模块的映射mapActions(模块名, [xxx])- 需要开启命名空间// ./store/index.js // 这里面存放的就是 vuex 相关的核心代码 import Vue from vue import Vuex from vuex import user from ./modules/user import setting from ./modules/setting // 插件安装 Vue.use(Vuex) // 创建仓库(空仓库) const store new Vuex.Store({ // 严格模式有利于初学者检测不规范的代码 上线时需要移除 strict: true, // 1. 通过 state 可以提供数据所以组件共享的数据 state: { title: 仓库大标题, count: 100, list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }, // 2. 通过 mutation 可以提供修改数据的方法 mutations: { // 所有 mutation 函数第一个参数都是 state // 注意点mutation 参数有且只能有一个如果需要多个参数包装成一个对象 addCount (state, n) { // 修改数据 state.count n }, subCount (state, n) { state.count - n }, changeCount (state, newCount) { state.count newCount }, changeTitle (state, newTitle) { state.title newTitle } }, // 3. actions 处理异步 // 注意不能直接操作 state. 操作state. 还是需要 commit mutation actions: { // context 上下文此处未分模块可以当成store仓库 // context.commit(mutation名字额外参数) changeCountAction (context, num) { // 这里是setTimeout模拟异步以后大部分场景是发请求 setTimeout(() { context.commit(changeCount, num) }, 1000) } }, // 4.getters 类似于计算属性 getters: { // 注意点 // 1. 形参第一个参数就是state // 2. 必须有返回值返回值就是getters的值 filterList (state) { return state.list.filter(item item 5) } }, // 5.modules 模块 modules: { user, setting } }) // 导出给main.js使用 export default store// ./App.vue template div idapp h1 根组件 - {{ title }} - {{ count }} /h1 input :valuecount inputhandleInput typetext Son1/Son1 hr Son2/Son2 /div /template script import Son1 from ./components/Son1.vue import Son2 from ./components/Son2.vue import { mapState } from vuex // console.log(mapState([count, title])) export default { name: app, created () { // console.log(this.$router) // 没配 console.log(this.$store.state.count) }, computed: { ...mapState([count, title]) }, data: function () { return { } }, methods: { handleInput (e) { // 1. 实时获取输入框的值 const num e.target.value // 2. 提交 mutation 调用 mutation 函数 this.$store.commit(changeCount, num) } }, components: { Son1, Son2 } } /script style #app { width: 600px; margin: 20px auto; border: 3px solid #ccc; border-radius: 3px; padding: 10px; } /style// ./components/Son1.vue template div classbox h2Son1 子组件/h2 从vuex中获取的值: label{{ $store.state.count }}/label br button clickhandleAdd(1)值 1/button button clickhandleAdd(5)值 5/button button clickhandleAdd(10)值 10/button button clickhandleChange1秒后修改成666/button button clickchangeFn改标题/button hr !-- 计算属性getters -- div{{ $store.state.list }}/div div{{ $store.getters.filterList }}/div hr !-- 测试访问模块中的state - 原生 -- div{{ $store.state.user.userInfo.name }}/div button clickupdateUser更新个人信息/button button clickupdateUser21秒后更新个人信息/button div{{ $store.state.setting.theme}}/div button clickupdateTheme更新主题色/button hr !-- 测试访问模块中的getters - 原生 -- div{{ $store.getters[user/UpperCaseName] }}/div /div /template script export default { name: Son1Com, created () { console.log(this.$store.getters) }, methods: { updateUser () { // $store.commit(模块名/mutation名, 额外传参) this.$store.commit(user/setUser, { name: ytl, age: 20 }) }, updateUser2 () { // 如何调用action dispatch this.$store.dispatch(user/setUserSecond, { name: qjl, age: 28 }) }, updateTheme () { this.$store.commit(setting/setTheme, blue) }, handleAdd (n) { // 错误代码vue 默认不会检测需要监测成本开启严格模式即可 // this.$store.state.count // console.log(this.$store.state.count) // 应该通过 mutation 核心概念进行修改数据 // 需要提供调用 mutation // this.$store.commit(addCount) // console.log(n) // 调用带参数的 mutation 函数 this.$store.commit(addCount, n) }, changeFn () { this.$store.commit(changeTitle, 灰太狼) }, handleChange () { // 调用action // this.$store.dispatch(action名字, 额外参数) this.$store.dispatch(changeCountAction, 666) } } } /script style langcss scoped .box{ border: 3px solid #ccc; width: 400px; padding: 10px; margin: 20px; } h2 { margin-top: 10px; } /style// ./components/Son2.vue template div classbox h2Son2 子组件/h2 从vuex中获取的值:label{{ count }}/label br / button clicksubCount(1)值 - 1/button button clicksubCount(5)值 - 5/button button clicksubCount(10)值 - 10/button button clickchanageCountAction(888)1秒后修改成888/button button clickchangeTitle(我是灰太狼)改标题/button hr div{{ filterList }}/div hr !-- 访问模块中的state -- div{{ user.userInfo.name }}/div div{{ setting.theme }}/div hr !-- 访问模块中的state -- divuser模块数据{{ userInfo}}/div button clicksetUser({ name: hettl, age: 40})更新个人信息/button button clicksetUserSecond({ name: hettl, age: 40})1秒后更新个人信息/button divsetting模块数据{{ theme }} - {{ desc }}/div button clicksetTheme(blue)更新主题色/button hr !-- 访问模块中的getters -- div{{ UpperCaseName }}/div div/div /div /template script import { mapState, mapMutations, mapActions, mapGetters } from vuex export default { name: Son2Com, computed: { // mapState 和 mapActions 都是映射属性 ...mapState([count, user, setting]), ...mapState(user, [userInfo]), ...mapState(setting, [theme, desc]), ...mapGetters([filterList]), ...mapGetters(user, [UpperCaseName]) }, methods: { // mapState 和 mapActions 都是映射方法 // 全局级别的映射 ...mapMutations([subCount, changeTitle]), ...mapActions([chanageCountAction]), // 分模块的映射 ...mapMutations(setting, [setTheme]), ...mapMutations(user, [setUser]), ...mapActions(user, [setUserSecond]) // handleSub (n) { // this.subCount(n) // } } } /script style langcss scoped .box { border: 3px solid #ccc; width: 400px; padding: 10px; margin: 20px; } h2 { margin-top: 10px; } /style// ./store/modules/user.js // user模块 const state { userInfo: { name: htl, age: 18 }, score: 100 } const mutations { setUser (state, newUserInfo) { state.userInfo newUserInfo } } const actions { setUserSecond (context, newUserInfo) { // 将异步在action中进行封装 setTimeout(() { // 调用mutation context上下文默认提交的就是直接模块的action和mutation context.commit(setUser, newUserInfo) }, 1000) } } const getters { // 分模块后state指代子模块的state UpperCaseName (state) { return state.userInfo.name.toUpperCase() } } export default { namespaced: true, state, mutations, actions, getters }// ./store/modules/setting.js // setting模块 const state { theme: light, // 主题色 desc: 测试demo } const mutations { setTheme (state, newTheme) { state.theme newTheme } } const actions {} const getters {} export default { namespaced: true, state, mutations, actions, getters }