zoukankan      html  css  js  c++  java
  • Vue-admin工作整理(九): 状态管理Vuex-state和getters

    前提:通过项目结构个人设置创建的项目

    store文件下actions.js、mutations.js、state.js都是根级别的状态管理,引用入口是通过index.js来实现,整个Vuex处理逻辑为:

    一、state

    • 实现方式1:访问根(state.js)状态的方式

    在state.js定义的值,可以在任何组件中使用,其他组件使用计算属性(computed)来获得该值,然后通过store的实例来读取:this.$store.state.appName,具体实现:

    1、state.js:

    const state = {
      appName: 'Robin'
    }
    export default state

    2、store.vue

    <template>
      <div>
        <a-input v-model="inputValue"/>
        <p>{{ inputValue }}</p>
        <p>appName: {{ appName }}</p>
        <a-show :content = "inputValue"/>
      </div>
    </template>
    <script>
    import AInput from '_c/AInput.vue'
    import AShow from '_c/AShow.vue'
    export default {
      name: 'store',
      data () {
        return {
          inputValue: ''
        }
      },
      components: {
        AInput,
        AShow
      },
      computed: {
        appName () {
        // 实现方式1:访问根状态的方式
    return this.$store.state.appName //注意路径,一定要是:store下的state模块实例的appName值 } } } </script>

    结果:

    • 实现方式2:模块里定义的state(model->user.js->state)的值访问

      思路:组件中通过 this.$store.state.user.userName来获取,注意:一定要有模块名(user),具体实现:

    <template>
      <div>
        <a-input v-model="inputValue"/>
        <p>{{ inputValue }}</p>
        <p>appName: {{ appName }}</p>
        <p>userName: {{ userName }}</p>
        <a-show :content = "inputValue"/>
      </div>
    </template>
    <script>
    import AInput from '_c/AInput.vue'
    import AShow from '_c/AShow.vue'
    export default {
      name: 'store',
      data () {
        return {
          inputValue: ''
        }
      },
      components: {
        AInput,
        AShow
      },
      computed: {
        appName () {
          return this.$store.state.appName
        },
        userName () {
          return this.$store.state.user.userName
        }
      }
    }
    </script>

    结果:

    • 实现方式3:通过Vuex提供的工具函数:mapState

      a、数组方式

    <template>
      <div>
        <a-input v-model="inputValue"/>
        <p>{{ inputValue }}</p>
        <p>appName: {{ appName }}</p>
        <p>userName: {{ userName }}</p>
        <a-show :content = "inputValue"/>
      </div>
    </template>
    <script>
    import AInput from '_c/AInput.vue'
    import AShow from '_c/AShow.vue'
    import { mapState } from 'vuex'
    export default {
      name: 'store',
      data () {
        return {
          inputValue: ''
        }
      },
      components: {
        AInput,
        AShow
      },
      computed: {
        ...mapState([ // ...为es6里面的展开操作符,它会展开一个对象,mapState最后会返回一个对象
          'appName',
          'userName'
        ])
      }
    }
    </script>

      b、对象方式

    <template>
      <div>
        <a-input v-model="inputValue"/>
        <p>{{ inputValue }}</p>
        <p>appName: {{ appName }}</p>
        <p>userName: {{ userName }}</p>
        <a-show :content = "inputValue"/>
      </div>
    </template>
    <script>
    import AInput from '_c/AInput.vue'
    import AShow from '_c/AShow.vue'
    import { mapState } from 'vuex'
    export default {
      name: 'store',
      data () {
        return {
          inputValue: ''
        }
      },
      components: {
        AInput,
        AShow
      },
      computed: {
        ...mapState({
          appName: state => state.appName,    // state为根级的state.js对象
          userName: state => state.user.userName // state为根级的state.js对象
        }
        )
      }
    }
    </script>
    • 实现方式4:如果模块中使用了命名空间,那么state值该怎么取?(使用命名空间,会让我们的模块更加密闭,不受外界的干扰)

      思路:可以使用Vuex提供的另一种方法:createNamespacedHelpers,通过它,来定义 mapState ,该方法需要传入一个命名空间的模块名,比如我们是在用user.js增加命名空间:createNamespacedHelpers('user'),这个时候 mapState 就包含了user这个模块名称了,注意书写方式:

    import { createNamespacedHelpers } from 'vuex'
    const { mapState } = createNamespacedHelpers('user')

    使用的时候通过:...mapState的方式,以对象形式取值了:

    <template>
      <div>
        <a-input v-model="inputValue"/>
        <p>{{ inputValue }}</p>
        <p>appName: {{ appName }}</p>
        <p>userName: {{ userName }}</p>
        <a-show :content = "inputValue"/>
      </div>
    </template>
    <script>
    import AInput from '_c/AInput.vue'
    import AShow from '_c/AShow.vue'
    import { createNamespacedHelpers } from 'vuex'
    const { mapState } = createNamespacedHelpers('user')
    export default {
      name: 'store',
      data () {
        return {
          inputValue: ''
        }
      },
      components: {
        AInput,
        AShow
      },
      computed: {
        ...mapState({
          userName: state => state.userName
        }
        )
      }
    }
    </script>

    二、getters

    相当于一个组件里面的计算属性,可以通过组件里的一个值经过计算处理,来返回一个新的值,依赖的值如果发生了变化,那么使用了这个值的getters属性也会发生相应的变化,也会更新

      1、最基础非getters方法:当inputValue改变的时候相应的计算属性也会去重新计算,如果inputValue的data值不变,计算属性是不会进行计算的

    <template>
      <div>
        <a-input v-model="inputValue"/>
        <p>{{ inputValue }} -> lastLetter is {{ imputValueLastLetter }}</p>
        <p>appName: {{ appName }}</p>
        <p>userName: {{ userName }}</p>
        <a-show :content = "inputValue"/>
      </div>
    </template>
    <script>
    import AInput from '_c/AInput.vue'
    import AShow from '_c/AShow.vue'
    import { mapState } from 'vuex'
    export default {
      name: 'store',
      data () {
        return {
          inputValue: ''
        }
      },
      components: {
        AInput,
        AShow
      },
      computed: {
        ...mapState({
          appName: state => state.appName,
          userName: state => state.user.userName
        }),
        // 拿inputValue的最后一个字母
        imputValueLastLetter () {
          return this.inputValue.substr(-1, 1)
        }
      }
    }
    </script>

      2、Vuex里的getters: store->getters.js(根级别的getters)

        例如:想展示一个值,这个值是依赖于state.js里的appName来计算的,需要在getter.js创建一个属性:appNameWithVersion。 属性值是一个函数,函数里面要有一个参数:state,这个state就是当前Vuex实例里的同级的state,然后通过

    const getters = {
      appNameWithVersion: (state) => {
        return state.appName + 'V 2.0.0'
      }
    }
    
    export default getters

    对 appNameWithVersion 进行处理,值获取到后在store.vue中,通过

    appNameWithVersion () {
          return this.$store.getters.appNameWithVersion
        }

    进行传值

    整体store代码:

    <template>
      <div>
        <a-input v-model="inputValue"/>
        <p>{{ inputValue }} -> lastLetter is {{ imputValueLastLetter }}</p>
        <p>appName: {{ appName }} -> appNameWithVersion is {{ appNameWithVersion }}</p>
        <p>userName: {{ userName }}</p>
        <a-show :content = "inputValue"/>
      </div>
    </template>
    <script>
    import AInput from '_c/AInput.vue'
    import AShow from '_c/AShow.vue'
    import { mapState } from 'vuex'
    export default {
      name: 'store',
      data () {
        return {
          inputValue: ''
        }
      },
      components: {
        AInput,
        AShow
      },
      computed: {
        ...mapState({
          appName: state => state.appName,
          userName: state => state.user.userName
        }),
        // 通过getters拿inputValue的最后一个字母
        imputValueLastLetter () {
          return this.inputValue.substr(-1, 1)
        },
        appNameWithVersion () {
          return this.$store.getters.appNameWithVersion
        }
      }
    }
    </script>

       3、通过Vuex提供的工具方法,来获取getter

        a、数组形式:

    import { mapState, mapGetters } from 'vuex'
    ...mapGetters([
          'appNameWithVersion'
        ])

        b、如何取模块中定义的getter呢:

          (1)、user.js:

    const state = {
      userName: 'Cristin'
    }
    
    // 取userName的第一个字母
    const getters = {
      firstLetter: (state) => {
        return state.userName.substr(0, 1)
      }
    }
    const mutations = {
      //
    }
    
    const actions = {
      //
    }
    
    export default {
      namespaced: true,
      state,
      mutations,
      actions,
      getters
    }

          (2)、store.vue:

    <template>
      <div>
        <a-input v-model="inputValue"/>
        <p>{{ inputValue }} -> lastLetter is {{ imputValueLastLetter }}</p>
        <p>appName: {{ appName }} -> appNameWithVersion is {{ appNameWithVersion }}</p>
        <p>userName: {{ userName }} -> firstLetter is {{ firstLetter }}</p>
        <a-show :content = "inputValue"/>
      </div>
    </template>
    <script>
    import AInput from '_c/AInput.vue'
    import AShow from '_c/AShow.vue'
    import { mapState, mapGetters } from 'vuex'
    export default {
      name: 'store',
      data () {
        return {
          inputValue: ''
        }
      },
      components: {
        AInput,
        AShow
      },
      computed: {
        ...mapState({
          appName: state => state.appName,
          userName: state => state.user.userName
        }),
        ...mapGetters([
          'appNameWithVersion'
        ]),
        ...mapGetters('user', [
          'firstLetter'
        ])
      }
    }
    </script>

    呈现:

  • 相关阅读:
    [C++设计模式]observer 观察者模式
    Codeforces 425A Sereja and Swaps(暴力枚举)
    linux中设置TAB键的宽度
    iOS 常见面试图总结2
    网络爬虫初步:从訪问网页到数据解析
    大数据时代之hadoop(二):hadoop脚本解析
    数据格式,訪问信息以及操作数指示符
    javaScript实现日历控件
    每一个程序猿都须要了解的一个SQL技巧
    OpenGL编程逐步深入(九)插值处理
  • 原文地址:https://www.cnblogs.com/cristin/p/9600825.html
Copyright © 2011-2022 走看看