• Vue中的状态管理器


    我们知道vue是组件式开发的,当你的项目越来越大后,每个组件背后的数据也会变得越来越难以理顺,

    这个时候你就可以考虑使用vuex了。

    备注: 官方建议小项目不要使用,引入vuex会带来新的概念和模式,这对于新手而言理解上本身有难度,而且小项目中vuex发挥的功效确实不怎么明显,

    反而增加了开发难度,就像后端项目中常说的 过度设计。

    说了这么多,下面介入正题(以下讲解需要一个空的vue项目,推荐使用 vue-cli 创建,快速搭建一个vue开发环境 ):

    vuex的作用就是作为一个数据仓库(store),把多个组件的背后的数据都放到store中,然后所有组件通过约定的方式去读取数据和修改数据。

    这一句话就概括完了。没有想象的那么复杂。注意,这句话里面一个关键词叫 约定,下面来说说有那些约定:

    在将约定之前,首先还是要知道怎么定义一个仓库(store),进入项目然后  vue add vuex 。

    通过这条命令,vue-cli 帮我们创建了一个 store.js 的文件,并自动在根组件中引入了store,具体变化如下:

    main.js 文件中自动变化了两处

    import Vue from 'vue'
    import App from './App.vue'    
    import store from './store' #【引入store文件】
    
    Vue.config.productionTip = false
    
    new Vue({
      store, #【在根组件中引入了store】
      render: h => h(App)
    }).$mount('#app')

    现在我们编辑一下 store.js 文件:

    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    export default new Vuex.Store({
      state: {
          user: {
            name: '张三', sex: '男'
          }
      },
      mutations: {
        change_name (state,payload) {
          state.user.name = payload.new_name
        },
        change_sex (state,payload) {
          state.user.sex = payload.new_sex
        }
      },
      actions: {
        change_sex_by_action (context,payload) {
          setTimeout(() => {
            context.commit('change_sex',payload)
          },3000)
        }
      }
    })

    理解:

      state 是状态(数据中心)。

      mutations 里面定义的函数用来修改state,mutation只能执行同步操作。

      actions 的目的也是更改state,但是他不像mutation一样可以直接更改state,而是通过调用mutation来更改state。还有一个不同点是,action可以执行异步操作,比如网络请求。

      getters 返回组装DIY后的数据,比如state有个sex=“女”,通过getter在后面加一个 生 ,返回 女生,但是我觉得把组件中 computed 干的事情放到store层不是一个好主意,所以本例中不涉及。

    用法:

      mutation的一个参数是 state,第二个参数是从 组件传过来的参数对象,

      action的第一个参数是一个与 store 实例具有相同方法和属性的 context 对象,这句话有点难以理解,你就把context想象成一个新的store对象,

      第二个参数还是 组件传过来的参数对象

    在编辑一下 App.vue 文件

    <template>
      <div id="app">
        <button @click="change_name">change name by mutation</button>
        <p>current name({{ user.name }})</p>
        <button @click="change_sex">change sex by action</button>
        <p>current sex({{ user.sex }})</p>
      </div>
    </template>
    <script>
    export default {
      data () {
        return {
          // user: this.$store.state.user
        }
      },
      computed: {
        user() {
          return this.$store.state.user
        }
      },
      methods: {
        change_name() {
          this.$store.commit({
            type: 'change_name',
            new_name: '李四'
          })
        },
        change_sex() {
          this.$store.dispatch({
            type: 'change_sex_by_action',
            new_sex: '女'
          })
        }
      }
    }
    </script>

     通过store获取数据都要放到computed里面,虽然在其他地方也可以直接获取,但是无法监听数据变动(就像上面注释的一样)。

    change_name是通过mutation方式同步更改store中的数据,change_sex采用了action方式异步更改store中的数据。

    如果在computed中需要获取的数据很多,可以使用 官方提供的 mapState,具体用法查看官方 文档 。

    我自己的理解:

    不要滥用store,不要把所有的数据都放到store中,在组件化开发思想下,我认为组件和组件之间本就应该独立封装,

    如果一个数据只有在某个组件中使用,而不需要被其他组件共享,那么最好不要放到其中,store只存储有必要的数据,不要让他变得太臃肿,否则麻烦迟早会来。

    官方文档中说明,如果store太大可以采用模块方式分割,但貌似不太优雅,

    最后我还是推荐store只放必要的东西,不要让他变得太肥胖。

  • 相关阅读:
    联赛前第七阶段总结
    tomcat启动服务一会后自动关闭
    删除软件服务
    jmeter ramp-up解释
    mysql数据库报错1045
    tomcat在linux上的安装
    ant在linux下的安装部署
    查看一条mysql语句的性能
    linux下安装svn服务器
    InfluxDB数据库报错ERR: unable to parse authentication credentials Warning: It is possible this error is due to not setting a database. Please set a database with the command "use <database>".
  • 原文地址:https://www.cnblogs.com/codeAB/p/10251669.html
Copyright © 2020-2023  润新知