# fed-e-vue-3-3 **Repository Path**: dadami/fed-e-vue-3-3 ## Basic Information - **Project Name**: fed-e-vue-3-3 - **Description**: vuex - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2020-08-01 - **Last Updated**: 2023-01-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # vuex-demo ## 启动node服务 ``` node server.js ``` ## Project setup ``` yarn install ``` ### Compiles and hot-reloads for development ``` yarn serve ``` ### Compiles and minifies for production ``` yarn build ``` ### Lints and fixes files ``` yarn lint ``` ### Customize configuration See [Configuration Reference](https://cli.vuejs.org/config/). ### 课程目标 - Vue组件间同学方式回顾 - Vuex核心概念和基本使用回顾 - 购物车案例 - 模拟实现vuex ### 1.组件内的状态管理流程 Vue 最核心的两个功能:数据驱动和组件化。 组件化开发给我们带来了: - 更快的开发效率 - 更好的可维护性 每个组件都有自己的状态、视图和行为等组成部分。 ```js new Vue({ // state data() { return { count: 0 } }, // view template: `
{{ count }}
`, // actions methods: { increment() { this.count++ } } }) ``` **状态管理包含以下几个部分** - state,驱动应用的数据源 - view, 以声明方式将state映射到视图 - actions,响应在view上的用户输入导致的状态变化 - 见图 ### 2.组件通信方式- 父组件给自组件传值 大多数场景下的组件都并不是独立存在的,而是相互协作共同构成了一个复杂的业务功能。在 Vue 中为 不同的组件关系提供了不同的通信规则。 - 见图 **父组件给自组件传值** - 子组件中通过props接收数据 - 父组件中给自组件通过相应属性传值 ```js // parent ``` ```js // child ``` ### 3.自组件给父组件传值 ```html // child ``` ```html // parent ``` 通过自组件触发事件携带参数,然后在父组件注册子组件内部触发的事件,并接收参数,通过`$emit` ### 4.不相关组件传值 ``` // eventbus import Vue from 'vue' export default new Vue() ``` ```html ``` ```html ``` ### 5.通过ref获取子组件 其他常见方式 - $root - $parent - $children - $refs ref 有两个作用: - 如果你把它作用到普通 HTML 标签上,则获取到的是 DOM 如果你把它作用- 到组件标签上,则获取到的是组件实例 创建 base-input 组件 ```html ``` 在使用子组件的时候,添加 ref 属性: ```html ``` 然后在父组件等渲染完毕后使用 $refs 访问: ```js mounted () { this.$refs.usernameInput.focus() } ``` > `$refs` 只会在组件渲染完成之后生效,并且它们不是响应式的。这仅作为一个用于直接操作子组 件的“逃生舱”——你应该避免在模板或计算属性中访问 `$refs` 。 ### 6.简易的状态管理方案 问题 - 多个视图依赖同一状态 - 来自不同视图的行为需要变更同一状态 使用父子组件,麻烦不易管理 ### 7.什么是Vuex > Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件 的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调 试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调 试功能。 - Vuex 是专门为 Vue.js 设计的状态管理库 - 它采用集中式的方式存储需要共享的数据 - 从使用角度,它就是一个 JavaScript 库 - 它的作用是进行状态管理,解决复杂组件通信,数据共享 **什么情况下使用 Vuex** - 非必要的情况不要使用Vuex - 大型的单页应用程序 - 多个视图依赖与同一状态 - 来自不同视图的行为需要变更同一状态 **Vuex核心概念** - Store - State - Getter - Mutation - Action - Module ### 8. Vuex基本结构 - 导入 Vuex - 注册 Vuex - 注入 $store 到 Vue 实例 ```js import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex) export default new Vuex.Store({ state: { }, mutations: { }, actions: { }, modules: { } }) import store from './store' new Vue({ router, store, render: h => h(App) }).$mount('#app') ``` ### 9.State - state 是响应式的 - Vuex 使用单一状态树,用一个对象就包含了全部的应用层级状态。 使用 mapState 简化 State 在视图中的使用,mapState 返回计算属性 mapState 有两种使用的方式: 接收数组参数 ```js // 该方法是vuex 提供的, 所以使用前需要导入 import { mapState } from 'vuex' // 通过传入对象, 可以重命名返回的计算属性 // 在模版中直接使用num 和 messge export default { computed: { ...mapState({ num: 'count', message: 'msg' }) } } ``` ### 10.Getter Getter 就是 store 中的计算属性,使用 mapGetter 简化视图中的使用 ```js import { mapGetter } from 'vuex' computed: { ...mapGetter(['reverseMsg]), ...mapGetters({ reverse: 'reverseMsg'}) } ``` ### 11.Mutation 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每 个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们 实际进行状态更改的地方,并且它会接受 state 作为第一个参数。 使用 Mutation 改变状态的好处是,集中的一个位置对状态修改,不管在什么地方修改,都可以追踪到 状态的修改。可以实现高级的 time-travel 调试功能 ```js import { mapMutations } from 'vuex' methods: { ...mapMutations(['increate']), ...mapMutations({ increateMut: 'increeate' }) } ``` ### 12. Action Action类似与mutation,不同在于 - Action提交的是mutation,而不是直接变更状态 - Action 可以包含任意异步操作 ```js import { mapActions } from 'vuex' export default new Vuex.Store({ state: { count: 0, msg: 'Hello Vuex' }, actions: { increateAsync (context, payload) { context.commit('increate', payload) } } }) methods: { ..mapActions(['increate']), // 传对象解决重名的问题 ...mapActions({ increateAction: 'increate' }) } ``` ### 13.module 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对 象就有可能变得相当臃肿。 为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、 mutation、action、getter、甚至是嵌套子模块。 在案例中体会 Module 的使用。 ```js // products. const state = { products: [ { id: 1, title: 'iPhone 11', price: 8000 }, { id: 2, title: 'iPhone 12', price: 10000 } ] } const getters = {} const mutations = { setProducts (state, payload) { state.products = payload } } const actions = {} export default { namespaced: true, state, getters, mutations, actions } // index.js import products from './modules/products' import cart from './modules/cart' // index.js export default new Vuex.Store({ state: { count: 0, msg: 'Hello Vuex' }, modules: { products, cart } }) // app.vue export default { computed: { ...mapState('products', ['products']) }, methods: { ...mapMutations('products', ['setProducts']) } } ``` ### 14.Vuex严格模式 Vuex中的状态的更新要通过提交mutation来修改,但其实在组件中还可以通过$store.state.msg进行修改,从语法从面来说这是没有问题的,但是这破坏了Vuex的约定,如果在组件中直接修改state,devtools无法跟踪到这次状态的修改。 开启严格模式之后,如果在组件中直接修改state会抛出错误,但数据仍被成功修改。 如何开启:在store中增加一个属性strict为true ```js export default new Vuex.Store({ strict: process.env.NODE_ENV !== 'production', state: { count: 0, msg: 'Hello Vuex' }, // ... }) ``` ### 15 购物车案例-演示 ![image](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/69295be4afe14c849a4b3d1c414698b9~tplv-k3u1fbpfcp-zoom-1.image) ### 16. 购物车案例 ```js npm i element-ui -S // main.js import 'element-ui/lib/theme-chalk/index.css'; Vue.config.productionTip = false Vue.use(ElementUI) ```