• 【Vue】Re20 VueX 第一部分(共享数据,Getters)


    一、概述

    专门为VueJS应用程序开发的状态管理模式

    集中式存储管理应用的所有组件的状态,按照相应的规则保证状态以一种可预测的方式发生变化

    VueX也集成到了官方调试工具devtools extension中

    状态共享问题:

    类似JavaWeb中的Session,每一个资源共同需要的变量

    二、案例演示

    首先需要安装VueX,CLI2的安装是没有提供VueX的

    npm install vuex --save

    App.vue

    <template>
      <div id="app">
        <h3>{{message}}</h3>
        <p>
          <button @click="$store.state.count --"> - </button>
          <span>{{$store.state.count}}</span>
          <button @click="$store.state.count ++"> + </button>
        </p>
        <vuex-comp></vuex-comp>
      </div>
    </template>
    <!-- Actions行为 + View视图 + State状态 -->
    <script>
    import VueXComp from "./components/VueX";
    export default {
      name: 'App',
      data () {
        return {
          message : 'sss',
          // count : 0
        }
      },
      components : {
        vuexComp : VueXComp
      },
    
    }
    </script>
    
    <style>
    #app {
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>

    VueX.vue

    <template>
      <div>
        <h3>VueX Component</h3>
        <p>{{$store.state.count}}</p>
      </div>
    </template>
    
    <script>
    
    export default {
      name: "VueX"
    
    }
    </script>
    
    <style scoped>
    
    </style>

    store目录的Index.js

    import Vue from 'vue';
    import VueX from 'vuex';
    
    /* 安装VueX */
    Vue.use(VueX);
    
    const store = new VueX.Store({
      state : { /* 状态保存,存放所有组件共享的对象 */
        count : 0
      },
      mutations : {
    
      },
      actions : {
    
      },
      modules : {
    
      }
    });
    
    export default store;

    main.js引入VueX的初始化:

    // The Vue build version to load with the `import` command
    // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import Store from './store';
    
    Vue.config.productionTip = false
    
    // Vue.use(VueX);
    
    /* eslint-disable no-new */
    
    new Vue({
      el: '#app',
      router,
      store : Store,
      components: { App },
      template: '<App/>'
    })

    两个组件是共用store中的state属性的count

    变量引用依靠$store

    $store.state.定义的属性

    但是官方不推荐使用上面这样的直接引用获取

    因为在devtools的调试插件中可以发现这样的问题:

    在界面中的点击,共享的count数据更新了,但是在调试插件中的vuex属性状态栏中,

    数据是没有发生变化的。

    使用mutations实现,并且可以被devtools跟踪

    至少使用先使用mutations调用,如果还有请求的操作,那还需要actions中调用

    store/index.js

    import Vue from 'vue';
    import VueX from 'vuex';
    
    /* 安装VueX */
    Vue.use(VueX);
    
    const store = new VueX.Store({
      state : { /* 状态保存,存放所有组件共享的对象 */
        count : 0
      },
      mutations : { /*  */
        increment (state) {
          state.count ++
        },
        decrement (state) {
          state.count --
        }
      },
      actions : {
    
      },
      modules : {
    
      }
    });
    
    export default store;

    首页App.vue

    <template>
      <div id="app">
        <h3>{{message}}</h3>
        <p>
    <!--      <button @click="$store.state.count &#45;&#45;"> - </button>-->
          <button @click="aaa"> - </button>
          <span>{{$store.state.count}}</span>
          <button @click="bbb"> + </button>
    <!--      <button @click="$store.state.count ++"> + </button>-->
        </p>
        <vuex-comp></vuex-comp>
      </div>
    </template>
    <!-- Actions行为 + View视图 + State状态 -->
    <script>
    import VueXComp from "./components/VueX";
    export default {
      name: 'App',
      data () {
        return {
          message : 'sss',
          // count : 0
        }
      },
      methods : {
        aaa () {
          this.$store.commit('decrement');
        },
        bbb () {
          this.$store.commit('increment');
        }
      },
      components : {
        vuexComp : VueXComp
      },
    
    }
    </script>
    
    <style>
    #app {
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>

    修改预览的效果可以跟踪Mutations的方法执行

    但是state变量不知道为什么对不上值:

    三、使用Getters计算复杂的需求

    现在Store中多了一组学生信息,需求是获取某一属性的某一范围的所有学生信息

    例如年龄大于20或者小于20

    store/index.js

    import Vue from 'vue';
    import VueX from 'vuex';
    
    /* 安装VueX */
    Vue.use(VueX);
    
    const store = new VueX.Store({
      state : { /* 状态保存,存放所有组件共享的对象 */
        count : 0,
        str : 'sss',
        students : [
          { id : 110, name : '学生110', age : 28, gender : true, },
          { id : 111, name : '学生111', age : 18, gender : true, },
          { id : 112, name : '学生112', age : 38, gender : false, },
          { id : 113, name : '学生113', age : 14, gender : true, },
          { id : 114, name : '学生114', age : 44, gender : false, },
          { id : 115, name : '学生115', age : 10, gender : true, },
        ]
      },
      mutations : { /*  */
        increment (state) {
          state.count ++
        },
        decrement (state) {
          state.count --
        },
      },
      actions : {
    
      },
      modules : {
    
      },
      getters : {
        getStringJoin (state) {
          return state.str + 'saa';
        },
        getCount (state) {
          return state.count;
        },
        large20Age (state) {
          return state.students.filter(student => student.age > 20);
        }
      }
    });
    
    export default store;

    App.vue

    <template>
      <div id="app">
        <h3>{{message}}</h3>
        <p>
    <!--      <button @click="$store.state.count &#45;&#45;"> - </button>-->
          <button @click="aaa"> - </button>
          <!--<span>{{$store.state.count}}</span>-->
          <strong>{{$store.getters.getCount}}</strong>
          <button @click="bbb"> + </button>
    <!--      <button @click="$store.state.count ++"> + </button>-->
        </p>
    
        <ul> <!-- 使用store的getters属性调用 -->
          <li v-for="student in $store.getters.large20Age">
            {{student.id}} | {{student.name}} | {{student.age}} | {{student.gender}}
          </li>
        </ul>
    
        <ul> <!-- 使用当前组件computed属性调用 -->
          <li v-for="student in largeThan20Age">
            {{student.id}} | {{student.name}} | {{student.age}} | {{student.gender}}
          </li>
        </ul>
    
        <p>
          {{$store.getters.getStringJoin}}
        </p>
        <vuex-comp></vuex-comp>
      </div>
    </template>
    <!-- Actions行为 + View视图 + State状态 -->
    <script>
    import VueXComp from "./components/VueX";
    export default {
      name: 'App',
      data () {
        return {
          message : 'sss',
          // count : 0
        }
      },
      methods : {
        aaa () {
          this.$store.commit('decrement');
        },
        bbb () {
          this.$store.commit('increment');
        }
      },
      computed : {
        // largeThan20Age () {
        //   return this.$store.state.students.filter(student => {
        //     return student.age >= 20;
        //   });
        // }
    
        largeThan20Age () {
          return this.$store.state.students.filter(student => student.age >= 20);
        }
    
      },
      components : {
        vuexComp : VueXComp
      },
    
    }
    </script>
    
    <style>
    #app {
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>

    getters属性支持内嵌式调用,提高了其他getters方法的可重用性

      getters : {
        getStringJoin (state) {
          return state.str + 'saa';
        },
        getCount (state) {
          return state.count;
        },
        large20Age (state) {
          return state.students.filter(student => student.age > 20);
        },
        large20AgeLength (state, getters) {
          return getters.large20Age.length;
        }
      }

    年龄限制条件交给参数决定,更灵活的需求:

    getters方法无法自定义我们希望的参数【已经固定了参数格式,第一state、第二getters】

    解决方案是先返回一个函数,在这个函数的形参就可以获取了,然后里面再写需求逻辑

        largeAgeBy (state) {
          return age => {
            return state.students.filter(student => student.age > age);
          }
        }

    App.vue调用

    <template>
      <div id="app">
        <h3>{{message}}</h3>
        <p>
    <!--      <button @click="$store.state.count &#45;&#45;"> - </button>-->
          <button @click="aaa"> - </button>
          <!--<span>{{$store.state.count}}</span>-->
          <strong>{{$store.getters.getCount}}</strong>
          <button @click="bbb"> + </button>
    <!--      <button @click="$store.state.count ++"> + </button>-->
        </p>
    
        <ul> <!-- 使用store的getters属性调用 -->
          <li v-for="student in $store.getters.large20Age">
            {{student.id}} | {{student.name}} | {{student.age}} | {{student.gender}}
          </li>
        </ul>
    
        <ul> <!-- 使用当前组件computed属性调用 -->
          <li v-for="student in largeThan20Age">
            {{student.id}} | {{student.name}} | {{student.age}} | {{student.gender}}
          </li>
        </ul>
    
        <p>{{$store.getters.large20AgeLength}}</p>
    
        <p>
          {{$store.getters.getStringJoin}}
        </p>
    
        <ul>
          <li v-for="student in $store.getters.largeAgeBy(0)">
            {{student.id}} {{student.name}} {{student.age}} {{student.gender}}
          </li>
        </ul>
    
        <vuex-comp></vuex-comp>
      </div>
    </template>
    <!-- Actions行为 + View视图 + State状态 -->
    <script>
    import VueXComp from "./components/VueX";
    export default {
      name: 'App',
      data () {
        return {
          message : 'sss',
          // count : 0
        }
      },
      methods : {
        aaa () {
          this.$store.commit('decrement');
        },
        bbb () {
          this.$store.commit('increment');
        }
      },
      computed : {
        // largeThan20Age () {
        //   return this.$store.state.students.filter(student => {
        //     return student.age >= 20;
        //   });
        // }
    
        largeThan20Age () {
          return this.$store.state.students.filter(student => student.age >= 20);
        }
    
      },
      components : {
        vuexComp : VueXComp
      },
    
    }
    </script>
    
    <style>
    #app {
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>
  • 相关阅读:
    免费的视频、音频转文本
    Errors are values
    Codebase Refactoring (with help from Go)
    Golang中的坑二
    Cleaner, more elegant, and wrong(msdn blog)
    Cleaner, more elegant, and wrong(翻译)
    Cleaner, more elegant, and harder to recognize(翻译)
    vue控制父子组件渲染顺序
    computed 和 watch 组合使用,监听数据全局数据状态
    webstorm破解方法
  • 原文地址:https://www.cnblogs.com/mindzone/p/13913621.html
Copyright © 2020-2023  润新知