我家的花花草草

时间:2018-01-08 10:18:03来源:杰瑞文章网点击:作文字数:600字
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。(源于官网) 状态的自我管理应该包含: state,驱动应用的数据源; view,以声明方式将 state 映射到视图; actions,响应在 view 上的用户输入导致的状态变化。 (源于官网) image Vuex 应用的核心就是 store(仓库,可以理解为容器),store 包含着应用中的大部分状态(state),用户不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation(源于官网) 开始 /// index.js 入口文件 import Vue from 'vue'; import Vuex from 'vuex'; import main from '../component/main' Vue.use(Vuex); // 要注意这里需要启用 Vuex const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } } }) // 设置了一个 Store let vm = new Vue({ el: '#app', render: h => h(main), store // 全局注入,所有组件均可使用这个 store }) ... /// main.vue 子组件 /// 注入的store,可以通过 this.$store 获取 state Vuex 使用单一状态树,用一个对象就包含了全部的应用层级状态。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。(源于官网) 从 store 实例中读取 state 最简单的方法就是在 computed 中返回某个状态(源于官网) 如果把数据获取置于data中,初始化时可以正常获取,但更新后并不能同步更新 mapState mapState 辅助函数帮助我们生成计算属性(源于官网) import { mapState } from 'vuex'; ... computed: mapState({ count (state) { // 在这个方法中可以直接使用state,不用使用 this.$store.state return state.count }, count1: state => state.count, // 这种是上面写法的简写 count2: 'count' // 这种是 state => state.count 的简写 }), // 这个方法最终会返回一个对象 ... /// 如果映射的计算属性的名称与 state 的子节点名称相同时,我们可以简化给 mapState 传一个字符串数组 computed: mapState([ 'count' // 映射 this.count 为 store.state.count ]) ... /// 一般不会使用上面写法,因为这样其他计算属性就无法添加,最好利用这个函数会返回对象的特性,直接使用对象展开的写法 computed: { ...mapState([ 'count' ]), info () { return `${this.msg} info` } }, Getter Getter(可以认为是 store 的计算属性),就像计算属性一样,Getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算(源于官网,稍改) Getter 接受 state 作为其第一个参数 /// 定义时,可以把其当作 state 的计算属性 const store = new Vuex.Store({ state: { count: 0 }, getters: { setCount (state) { return `set count: ${state.count}` } }, 通过属性直接访问(this.$stroe.getters) computed: { showSetCount () { // 访问时可以通过 this.$store.getters 访问 return this.$store.getters.setCount }, Getter 也可以接受其他 getter 作为第二个参数 getters: { setCount (state) { return `set count: ${state.count}` }, allMsg (state, getters) { return `all ${getters.setCount}` // 这里的 getters 和 state 一样都是当前 store 下的 } } mapGetters 同上文的 mapState 一样使用 import { mapState, mapGetters } from 'vuex'; ... computed: { ...mapGetters({ showSetCount: 'setCount', showAllMsg: 'allMsg' }), } Mutation mutation 是更改 store 中状态的唯一方式,每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler),不能直接调用一个 mutation handler,需要通过 store.commit 方法进行调用(源于官网,稍改) 回调函数会接受 state 作为第一个参数 mutations: { increment (state) { state.count++ } } ... ... methods: { incream () { this.$store.commit('increment'); // 通过 store.commit 触发 } } Payload /// commit 接收第二个参数,这样外部数据就可以更新到仓库中 mutations: { increment (state, payload) { state.count += payload.amount } } ... methods: { incream () { this.$store.commit('increment', { amount: 20 }); } }, /// 如果你是redux的使用者,可能更习惯对象风格的代码提交 incream () { this.$store.commit({ type: 'increment', amount: 20 }) } mapMutations /// 如果使用了 types 的方式,应该都要用下面方式,调用时直接传 payload methods: { ...mapMutations({ 'incream': INCREMENT }) }, ... /// 在调用处,直接传参 需要遵守的规则 最好提前在你的 store 中初始化好所有所需属性 当需要在对象上添加新属性时,利用对象展开运算符,使用新对象替换老对象 state.obj = { ...state.obj, newProp: 123 } 使用常量替代 Mutation 事件类型(这是类 Flux 的状态管理都建议的做法,统一管理,统一维护) /// types.js export const INCREMENT = 'INCREMENT'; ... /// index.js import { INCREMENT } from './types'; ... mutations: { [INCREMENT] (state, payload) { state.count += payload.amount } } ... /// main.vue import { INCREMENT } from '../script/types'; ... methods: { incream () { this.$store.commit({ type: INCREMENT, amount: 20 }) } }, Mutation 必须是同步函数(保证状态的变更是可追踪的),如果需要使用异步方法用 Action Action action 提交的是 mutation,不能直接变更状态(state) action 可以包含异步操作,action 通过 dispatch 触发 /// index.js actions: { // action 可以是同步方法,也可以是异步方法 increment (context) { context.commit(INCREMENT, {amount: 10}) } } ... /// main.vue methods: { incream () { this.$store.dispatch('increment') // 通过 dispatch 触发 action } }, context Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。(源于官网) // 使用对象解构简化操作 increment ({commit}) { commit(INCREMENT, {amount: 10}) } Action 函数接受第二个参数用作 payload increment ({commit}, payload) { commit(INCREMENT, {amount: payload.amount}) } ... /// main.vue incream () { // 以 payload 的形式调用 this.$store.dispatch('increment', { amount: 15 }) ... // 还可以用对象形式调用 this.$store.dispatch({ type: 'increment', amount: 15 }) } mapActions methods: { ...mapActions({ incream: 'increment' }) } ... // 在方法调用处传 payload 组合 Action 可以在action中写各种异步方法,来组合复杂的业务逻辑 actions: { increment ({commit, dispatch}, payload) { // context 对象也有 dispatch return new Promise((resolve, reject) => { setTimeout(() => { commit(INCREMENT, {amount: payload.amount}) // 触发 Mutations 更新 dispatch('log') // 在一个 action 中触发另外一个 action resolve({ code: '000000' }) // 返回异步处理情况 }, 500); // 模拟接口返回 }) }, log () { console.log('日志.....') } } ... /// main.vue ... methods: { ...mapActions({ incream: 'increment' }), doneCheck (status) { console.log('status', status); // 这里可以拿到异步处理结果来继续后续逻辑 } }, 这里用 Promise 模拟了一个接口处理情况,在 action 中触发状态更新,并触发另外一个 action,返回异步结果供调用函数使用(还可以使用 async / await 更加简化代码) Module 使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。 Vuex 允许我们将 store 分割成模块(module),每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割(源于官网) /// index.js const countModule = { state: () => ({ // 子 store 下的 state 用这种函数的返回的形式,原因和组件内data 定义一样 count: 0 }), getters: { setCount (state) { return `set count: ${state.count}` }, allMsg (state, getters) { return `all ${getters.setCount}` } }, mutations: { [INCREMENT] (state, payload) { state.count += payload.amount } }, actions: { increment ({commit, dispatch}, payload) { return new Promise((resolve, reject) => { setTimeout(() => { commit(INCREMENT, {amount: payload.amount}) dispatch('log') resolve({ code: '000000' }) }, 500); }) }, log () { console.log('日志.....') } } } const infoModule = { state: () => ({ info: 'store info' }), getters: { allMsg (state) { return `show ${state.info}` } } } const store = new Vuex.Store({ modules: { // 分别定义两个store通过modules的方式组合在一起 countModule, infoModule } }) ... /// main.vue /// 使用时,除state外,和之前使用方式一致 computed: { ...mapState({ count: state => state.countModule.count, // state 要指定模块 info: state => state.infoModule.info }), ...mapGetters({ showSetCount: 'setCount', showAllMsg: 'allMsg' }), }, methods: { ...mapActions({ incream: 'increment' }), } ... /// 如果想保持 mapState 中数组的简介写法,可以这么改造下 ...mapState([ 'countModule', 'infoModule' ]), // mapState 中直接导入模块名 ... {{ countModule.count }} - {{ infoModule.info }} /// 使用时按模块名去获取 state 模块中只有 state 在使用时需要特别指明模块,action、mutation 和 getter 因为是注册在全局 store 上,所以可以直接使用,通过打印 this.$store 也看到两个不同模块的 getters 是都加挂在 store 实例对象上 rootState /// 如果外层 store 中也有 state,可以通过 rootState 获取 const store = new Vuex.Store({ modules: { countModule, infoModule }, state: { copyright: 'xxx company' } }) /// getters、mutations 的第三个参数表示的是 rootState(名字可以随意) getters: { setCount (state, getters, rootState) { return `set count: ${state.count}` }, ... mutations: { [INCREMENT] (state, payload, rootState) { ... /// action中则必须使用(rootState这个变量名) actions: { increment ({commit, dispatch, rootState}, payload) { 命名空间 我感觉没必要使用,如果我们在拆分模块时,模块名是一个有明显语意的名字,在定义 action、getters 这些内容时,用 模块名+属性/方法名 的方式一样能达到相同的功效,这样也可以很明晰的知道这个方法属于哪个模块。 这样也可以有很高的复用性,封装型也不差,使用起来也简单。 /// index.js const infoModule = { getters: { infoModuleShowInfo (state) { return `show ${state.info}` } } ... /// main.vue ...mapGetters({ showInfo: 'infoModuleShowInfo' }), ... /// 模块名+属性名,使用时直接用 infoModuleShowInfo,而且能看出是属于 infoModule 插件 可以在 store 的根节点下,使用 plugins 的形式加挂插件 const store = new Vuex.Store({ // ... plugins: [myPlugin] }) Vuex 内置了 logger 插件 import createLogger from 'vuex/dist/logger' const store = new Vuex.Store({ plugins: [createLogger()] }) 表单处理 Vuex 的 state 上使用 v-model,需要使用带有 setter 的双向绑定计算属性 const store = new Vuex.Store({ modules: { countModule, infoModule }, state: { copyright: '2020 company', auther: 'rede' }, getters: { bookInfo (state) { return `${state.auther} @ ${state.copyright}` } }, actions: { updataAutherAction ({commit}, payload) { commit('updataAuther', { value: payload.value }) } }, mutations: { updataAuther (state, payload) { state.auther = payload.value } } }) ... /// main.vue
{{bookInfo}}
... computed: { ...mapGetters({ bookInfo: 'bookInfo' }), auther:{ get () { return this.$store.state.auther }, set (value) { this.updataAutherAction({ value }) } }, ...
作文投稿

我家的花花草草一文由杰瑞文章网免费提供,本站为公益性作文网站,此作文为网上收集或网友提供,版权归原作者所有,如果侵犯了您的权益,请及时与我们联系,我们会立即删除!

杰瑞文章网友情提示:请不要直接抄作文用来交作业。你可以学习、借鉴、期待你写出更好的作文。

我家的花花草草相关的作文:

    无相关信息

说说你对这篇作文的看法吧