(精华)2020年7月19日 vue vuex的使用和vuex辅助函数的使用

vuex的基本使用
store.js

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);
//定义属性
var state = {
    count:6,
    country:'中国'
};

//定义getters
var getters = {
    count(state){
        return state.count
    },
    isEvenOrOdd(state){
        return state.count%2==0?'偶数':'基数';
    }
}

//定义mutation,处理状态(数据)的改变
var mutations = {
    increment(state,payload){  
        debugger   
        state.count = state.count + payload.data
    },
    incrementAsync(state,payload){
         //异步操作
         var p=new Promise((resolve,reject) => {
            setTimeout(() => {
                resolve();
            },3000);
        });
    
        p.then(() => {
            state.count = state.count + payload.data
        }).catch(() => {
            console.log('异步操作');
        });
    }
}

//定义actions,要执行的操作,如流程判断、异步请求等
var actions = {
    // increment(context,payload){
    //     context.commit('increment',payload)
    // },

    increment({commit},payload){
        debugger
        commit('increment',payload)
    },
    incrementAsync({commit,state},payload){
        //异步操作
        var p=new Promise((resolve,reject) => {
            setTimeout(() => {
                resolve();
            },3000);
        });
    
        p.then(() => {
            commit('increment',payload);
        }).catch(() => {
            console.log('异步操作');
        });
    }
}



//创建store对象
var store = new Vuex.Store({
    state,
    getters,
    mutations,
    actions
})

//导出store对象
export default store;

main.js挂载store.js

import Vue from 'vue'
import App from './App.vue'
import Vuestore from './store.js'

new Vue({
  el: '#app',
  //会自动将store对象注入到所有的子组件中
  // 在子组件中通过this.$store访问该store对象
  store:Vuestore,
  render: h => h(App)
})

在vue组件中使用

<template>
  <div id="app">
    <h1>{{ msg }}</h1>
     <h2>获取store仓库中的所有数据state</h2>
     {{$store.state.count}}
    <h2>通过计算属性获取</h2>
    {{getCount}}
 <h2>通过计算属性获取是否基偶数</h2>
    {{isEvenOrOdd}}
  <h2>通过store里的getters</h2>
    {{$store.getters.isEvenOrOdd}}

    <button type="button" @click="increment()">增加</button>

  </div>
</template>

<script>
export default {
  name: 'app',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },
  computed:{
    getCount(){
      return this.$store.state.count;
    },
    isEvenOrOdd(){
       return this.$store.state.count%2==0?'偶数':'基数';
    }
  },
  methods:{
    increment(){
      // 2.通过仓库管理员mutation -  用来修改数据 
        // this.$store.commit('increment',{
        //   data:6
        // })

        // this.$store.commit({
        //   type:'increment',
        //   data:5
        // })

        // this.$store.commit('incrementAsync',{
        //   data:6
        // })


       //3. 通过actions ,dispatch一个action函数
        // this.$store.dispatch('increment',{
        //   data:6
        // })

        this.$store.dispatch({
          type:'increment',
          data:6
        })

        //4. 异步
        // this.$store.dispatch('incrementAsync',{
        //   data:6
        // })
        
    }
  },
  mounted(){
    // this.$store.state.count = 8;
  }
}
</script>

vuex的辅助函数的使用
首先上store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

//定义属性(数据)
var state = {
  count: 16,
  todolist: [{
      id: 1,
      task: '读书',
      finished: true
    },
    {
      id: 2,
      task: '写字',
      finished: false
    }
  ]
}

//定义getters
var getters = {
  getCount(state) {
    return state.count;
  },
  isEvenOrOdd(state) {
    return state.count % 2 == 0 ? '偶数' : '奇数';
  },
  getFinished(state) {
    return state.todolist.filter((item) => {
      return item.finished
    })
  },
  getUnFinished(state) {
    return state.todolist.filter((item) => {
      return !item.finished
    })
  },
}

//定义actions,要执行的操作,如流程判断、异步请求等
const actions = {
  // increment(context,payload){//包含:commit、dispatch、state
  //     console.log(context);
  // 	context.commit('increment',payload)
  // },
  increment({
    commit
  }, payload) {
    commit('increment', payload)
  },
  decrement({
    commit,
    state
  }, payload) {
    if (state.count > 10) {
      commit('decrement', payload);
    }
  },
  incrementAsync({
    commit,
    state
  }, payload) {
    //异步操作
    var p = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve();
      }, 3000);
    });

    p.then(() => {
      commit('increment', payload);
    }).catch(() => {
      console.log('异步操作');
    });
  },
  todosUpdate({
    commit
  }, payload) {
    var p = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve();
      }, 3000);
    });
    p.then(() => {
      commit('todosUpdate', payload);
      // state.todolist.push(payload);
    })

  }
}

//定义mutations,处理状态(数据)的改变
const mutations = {

  // 没有参数的情况
  // increment(state){
  // 	state.count++;
  // },

  // 有参数的情况
  increment(state, payload) {
    state.count += payload.data;
  },
  decrement(state, payload) {
    state.count -= payload.data;
  },
  todosUpdate(state, payload) {
    state.todolist.push(payload);

    // 异步情况, 不方便调试 
    // var p=new Promise((resolve,reject) => {
    // 	setTimeout(() => {
    // 		resolve();
    // 	},3000);
    // });
    // p.then(()=>{
    // 	state.todolist.push(payload);
    // })
  }
}

//创建store对象
const store = new Vuex.Store({
  state,
  getters,
  actions,
  mutations
})

//导出store对象
export default store;

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

mapstate辅助的使用

<template>
  <div class="map-state">
    直接通过state 获取 {{this.$store.state.count}}
    <ul>
      <!-- <li>countTest1: {{countTest1}}</li>
      <li>countTest2: {{countTest2}}</li>-->
      <!-- <li>countTest3: {{countTest3}}</li>  -->
      <li>count: {{count}}</li>
    </ul>todolist:
    <br />
    {{todolist}}
  </div>
</template>

<script>
import { mapState } from "vuex";
export default {
  data() {
    return {};
  },
  computed: {
    //          ...mapState({
    //              countTest1:state=>state.count,  //直接获取state
    //              countTest2(state){
    //                 return state.count
    //              }
    //        }),
    // ...mapState({
    //      countTest3:'count'
    //       // countTest3是方法名,count 并不是字符串,是对应state里的变量,
    //       // 然后将这个state重命名
    // }),
    // 映射 this.count 为 store.state.count
    ...mapState(["count", "todolist"])
  },
  mounted() {
    //1. 直接从state里获取
    console.log(this.$store.state.count);
  }
};
</script>

mapgetter使用

<template>
  <div class="map-getters">
    <h2>通过本页面的计算属性:</h2>
    <!-- {{FinishedTask}} -->
    <ul>
      <li v-for="(item,index) in FinishedTask" :key="index">{{item.task}}</li>
    </ul>
    <h2>通过在store中配置getters后获取:</h2>
    <ul>
      <li v-for="(item,index) in $store.getters.getFinished" :key="index">{{item.task}}</li>
    </ul>

    <h2>通过辅助函数mapGetters获取 getUnFinished:</h2>
    <ul>
      <li v-for="(item,index) in getUnFinished" :key="index">{{item.task}}</li>
    </ul>

    <div>
      <h2>通过辅助函数mapGetters获取 todosALise</h2>
      {{todosALise}}
    </div>
    <div>
      <!-- 通过辅助函数mapGetters获取 getCount
      {{getCount}}-->
    </div>
  </div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
  data() {
    return {
      todoList: this.$store.state.todolist
    };
  },
  computed: {
    //本页面的计算属性
    FinishedTask() {
      return this.$store.state.todolist.filter(item => {
        return item.finished;
      });
    },
    // ...mapGetters( ['getCount','getFinished','getUnFinished']),

    //  方式一 :如果你想将一个 getter 属性另取一个名字,使用对象形式:
    // 把 `this.todosALise` 映射为 `this.$store.getters.getCount`
    // 把 `this.getUnFinished` 映射为 `this.$store.getters.getUnFinished`
    ...mapGetters({
      todosALise: "getCount",
      getUnFinished: "getUnFinished"
    })
  }
};
</script>

mapmutation的使用

<template>
  <div class="map-mutation">
    <p>改变count</p>
    <button type="button" @click="totalCount({data:5})">通过mapMutations改变count</button>
    <br />
    <button type="button" @click="changeCount({data:5})">通过普通的mutation改变count</button>

    <div>
      <ul>
        <li v-for="(item,index) in $store.state.todolist" :key="index">
          {{item.task}}
          <br />
          任务状态:{{item.finished?'已完成':'未完成'}}
        </li>
      </ul>
    </div>
    <button type="button" @click="mutationTodos()">通过普通的mutation改变todoList</button>
    <br />
    count的值: {{$store.state.count}}
  </div>
</template>

<script>
import { mapMutations } from "vuex";
export default {
  data() {
    return {};
  },

  methods: {
    ...mapMutations({
      totalCount: "increment",
      todosUpdate: "todosUpdate"
      // increment 是mutation 里的方法,totalCount是重新定义的一个别名方法,本组件直接调用这个方法
    }),

    changeCount() {
      //  2.通过仓库管理员mutation -  用来修改数据
      // this.$store.commit('increment',{
      //     data:6
      // })

      // this.$store.commit({
      //     type:'increment',
      //     data:5
      // })

      //3. 通过mapMutations的方法
      this.totalCount({ data: 5 });
    },
    mutationTodos() {
      var datas = {
        id: 3,
        task: "画画",
        finished: false
      };

      // this.$store.commit('todosUpdate',datas) //方式一

      this.todosUpdate(datas); // 方式二  mapMutations
      //注意:如果mutation里有异步的方法, 这里获取不到实时的信息
      console.log(this.$store.state.todolist);
    }
  }
};
</script>

mapaction的使用

<template>
    <div class="map-action">
        <button type="button" @click="totoalCount({data:6})">增加count</button>
        <button type="button" @click="decrement({data:4})">减少count</button>
         {{$store.state.test03.count}}
         <button type="button" @click="updateTodos()">增加任务</button>
         <div>
            {{$store.state.test03.todolist}}
        </div>

         <button type="button" @click="changeCount()">增加count</button>
    </div>
</template>
<script>
import {mapActions} from 'vuex';
export default {
    data(){
        return {

        }
    },
    // methods:mapActions(['decrement','todosUpdate','incrementAsync']),
    // methods:mapActions({
    //     'decrement':'decrement',
    //     'totoalCount':'increment',
    //     'incrementAsync':'incrementAsync',
    //     'todosUpdate':'todosUpdate'
    // }),
    watch:{
        '$store.state.todolist':{
            handler(newobj,oldObj){
                console.log(newobj);
            },
            deep:true
        }
    },
    methods:{
        ...mapActions({
            'decrement':'decrement',
            'totoalCount':'increment',
            'incrementAsync':'incrementAsync',
            'todosUpdate':'todosUpdate'
        }),
        changeCount(){
            this.totoalCount({data:6})
        },
        updateTodos(){
            var datas = {
                id:3,
                task:'画画',
                finished:false
            };
        this.todosUpdate(datas);  

        this.$nextTick(()=>{  //微任务
            console.log('--------------');
            console.log(this.$store.state.todolist); //取不到action里面的异步数据
        })
         
        }
    }
    // methods:{
    //     // totoalCount(data){
    //     //     this.$store.dispatch('increment',data)
    //     // },
    //     decrement(data){
    //         this.$store.dispatch('decrement',data)
    //     },
    //     incrementAsync(data){
    //          this.$store.dispatch('decrement',data)
    //     },
    //     todosUpdate(data){
    //         this.$store.dispatch('todosUpdate',data)
    //     },

    // }

}
</script>
<style scoped>
.map-action {
    margin-top: 30px;
}
</style>

猜你喜欢

转载自blog.csdn.net/aa2528877987/article/details/107440465