zoukankan      html  css  js  c++  java
  • 【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>
  • 相关阅读:
    JS控制SVG缩放+鼠标控制事件
    JS多线程之Web Worker
    通过Java调用Python脚本
    Cornerstone的使用
    SVN服务器的搭建
    Python 函数作用域
    RDD转换算子(transformantion)
    Spark RDD简介
    Django 外键
    Django 模型常用属性
  • 原文地址:https://www.cnblogs.com/mindzone/p/13913621.html
Copyright © 2011-2022 走看看