zoukankan      html  css  js  c++  java
  • 6.Vue技术栈开发实战-状态管理Vuex(二)



    getter相当于vuex里面的计算属性。

    在vue组件中如果我们要触发一个全局的状态更新呢的话,中间其实还缺少一条线。如果我们的操作不具有异步操作的话,可以不走action,可以直接在vue组件中通过cmmitMutations来提交一个状态的改变。然后接着走下面的流程。

    当我们在组件中需要自改vuex中的state状态值的时候,我们不可以在组件中直接修改这个值,而是需要commit提交一个mutation或者dispatch一个action,来走这么一个流程,这么看起来貌似很复杂和多余,这种操作是为了更清楚的帮我们梳理我们数据的改变,能够提供一个清晰的数据流,

    实战

    在mutations创建对象,然后把这个对象导出去。

    index.js内引进来,然后创建实例的时候把他添加进去。

    根级别的state有个appName

    在这里我们使用了这个appName,它是一个计算属性,返回的是store中的appName


    修改这个state的值,先在上面定义一个按钮



    提示注册属性被指定了,但是它没有setter。

    一个计算属性,默认情况下,它只有一个getter。是你在使用这个值的时候才会调取getter

    类似于这种get和set的写法,这只是做一个简单的示范
      appName: {
          set: function (newValue) {
            this.inputValue = newValue + 'sd'
          },
          get: function () {
            return this.inputValue + 'sdfsdf'
          }
        },

    参数1就是通过那个方法名修改这个值

    方法是在mutation中定义的。SET_APP_NAME

    方法有个参数是state,就是同级别的state对象,

    第二个参数vuex文档中叫做载荷,其实他就是参数值。如果是多个值的话params就是对象的形式,因为我们这里是一个值可以直接用params

    commit的第一个参数就是我们要提交的名称

    第二个参数就是要赋的新值

    handleChangeAppName () {
          // this.appName = 'newAppName'
          this.$store.commit('SET_APP_NAME', 'newAppName')
        }



    修改多个参数

    这里就是一个对象的形式

    handleChangeAppName () {
          // this.appName = 'newAppName'
          this.$store.commit('SET_APP_NAME', {
            appName: 'newAppName'
          })
        }


    const mutations = {
      SET_APP_NAME (state, params) {
        state.appName = params.appName
      }
    }



    直接一个参数,对象的写法

    type就是mutations内的名称

    this.$store.commit({
            type: 'SET_APP_NAME',
            appName: 'newAppName'
          })





    params就是一个对象了 ,还是要通过params.appName

    添加新的state值

    想给state动态的添加appVersion这个属性


    appVersion现在是没有的。后面想让他有这个值。

    引入vue,使用vue的set方法,给state对象





    然后使用这个appVersion





    如果这里不用vue的set方法的话,直接修改state的appVersion属性

    没有效果

    说明在这里没有更新视图,这是vue中提到的响应式的原则,

    如果一开始没有在state中定义,在创建实例的时候 是不会被添加get和set方法的,

    那么视图就不会响应式的去更新。那么就需要使用vue.set把这个新的值添加到state对象上,同时它会给你添加get和set方法,同时会触发视图更新

    mapMutations


    注意:...mapMutations这个是methods里面定义的



    这里改成直接用params



    同时也可以写成对象的形式




    模块中的mutation




    上面新添加一个按钮





    这里没有写模块名称,因为vuex会把模块中的和通用级别的,通通注册在全局当中,你只需要把它当做根级别的定义的get和mutation一样调用即可。

    如果你想给他一个密闭的环境就设置namespaced

    mutation中修改的值是通过接口获取的

    获取接口中的操作呢,ajax请求是一个异步的操作。这个逻辑 是不能放在mutation中操作的。mutation只能做一些同步的操作。
    如果有一些异步的操作 ,请求接口的数据再去修改state的值 怎么做?就会需要用到下面课要讲的action

    Action




    修改根级别的appName。这种写法是ES6的解构赋值

    相当于这种写法,接收一个对象,然后获取对象中的commit

    模拟一个异步的操作。假设getAppName是一个接口请求。

    接口定义在api文件夹下的app.js

    引用的简写形式

    创建app.js

    定义个promise对象,然后用settimeOut模拟一个http的延迟请求。 


    这里调用异步操作,打印这个结果看下



    先注释掉

    在这里提交一个action。先引入工具方法mapAction



    调用这个方法



    如果有catch就输出这个错误

    提交修改appName

    这里改成单个参数


    还可以使用ES6的解构赋值

       const { code, info: { appName } } = res
       commit('SET_APP_NAME', appName)


    code没有用到这里就删掉

    const { info: { appName } } = res
    commit('SET_APP_NAME', appName)


    还可以使用store实例上的方法触发这个action,使用this.$store.dispatch(); 使用dispatch这个方法来触发action。参数载荷,可以以为对象 {}的形式,如果是一个值的话,就直接用'123'

    这句话注释掉。

    使用ES8的async来处理异步的问题。

    这里使用了promise来处理逻辑。这种是类似于回调的形式。看起来并不是非常的友好 

    await等待一个异步函数执行,当它执行完成后,它会往下走,

    async getAppName ({ commit }) {
        const { info: { appName } } = await getAppName()
        commit('SET_APP_NAME', appName)
      }




    刚才方法名写错了



    async处理异常 try catch的形式

     async updateAppName ({ commit }) {
        try {
          const { info: { appName } } = await getAppName()
          commit('SET_APP_NAME', appName)
        } catch (error) {
          console.log(error)
        }
      }

    module模块


    当项目非常大的时候,store就会变的非常的臃肿,拆成模块管理比较清晰。每一个模块是一个独立的store

    user下面还可以包含模块,拆分更细的模块。

    如果user加上了命名空间那么这里调用的时候,也需要加上

    如果模块里面套模块,这里就这么写

    模块中用action




    这种方式提交action

    action中有另外的方法,可以在上面调用,用dispatch

    store实例动态的注册一个模块。

    动态的注册模块

    第一个参数是模块名称,后面是一个对象,



    注册一个todoList

    如果有state.todo。那么就用state.todo.todoList.没有的话就是个空数组

    todoList: state => state.todo ? state.todo.todoList : []


    在上面做个循环



    模块添加模块。给user模块添加一个子模块叫做todo


    registerModule () {
          this.$store.registerModule(['user', 'todo'], {
            state: {
              todoList: [
                '学习mutations',
                '学习actions'
              ]
            }
          })
        }


    把todo模块注册在user模块里 。

    todoList: state => state.user.todo ? state.user.todo.todoList : []


    结束



     

  • 相关阅读:
    消息摘要技术(MD5)
    编写JsonResult封装JSON返回值(模板参阅)
    JS面向对象编程(进阶理解)
    markdown常用语法教程
    Spring-MVC请求参数值和向页面传值
    Spring-MVC开发步骤(入门配置)
    Live Templates快捷键模板
    压力测试中java.net.BindException: Address already in use: connect
    jmeter初始化工作
    xshell配色
  • 原文地址:https://www.cnblogs.com/wangjunwei/p/12921592.html
Copyright © 2011-2022 走看看