Vue综合

VUE3之VUEX

vuex的基本使用

创建一个store:

import {createStore} from 'vuex'

const store = createStore();

export default store;

在Main.js中使用:

import store from './store'

createApp(App).use(store).mount('#app')

state

在store中定义数据,需要在state属性中:

const store = createStore({
  state(){
    return{
      counter:0
    }
  }
});

在组件中使用时,需要从$store.state中获取:

<h2>{{$store.state.counter}}</h2>

mutations

在vuex的开发模式中,不推荐直接对数据进行操作,而是应该通过commit来提交一次数据操作。在store中定义mutations属性:

  mutations:{
    increment(state){
      state.counter++
    },
    decrement(state){
      state.counter--
    }
  }

在组件中调用store的commit方法,参数是要执行的mutation的方法名:

  methods:{
    increment(){
      this.$store.commit("increment")
    },
    decrement(){
      this.$store.commit("decrement")
    }
  }

mutations的一些补充

mutations中的方法的第一个参数是state,可以获取state中的变量,第二个参数是payload,即从外部传入的参数:

  mutations:{
    incrementN(state,payload){
      state.counter+=payload
    }
  },
    methods: {
      addTen(){
        this.$store.commit('incrementN',10)
      }
    },

另一种提交的风格是,将两个参数合并,即传入一个对象,当中有type来指明提交给某个函数:

this.$store.commit({
  type:'incrementN',
  incre:10
})

另外为了防止将方法名写错,可以使用常量的方式定义方法名:

  const INCREMENT_N = "increment_n";
    mutations:{
    [INCREMENT_N](state,payload){
      state.counter+=payload
    }
  },

mapState辅助函数

可以通过计算属性来简化获取state中的数据:

  computed:{
    sCounter(){
      return this.$store.state.counter
    }
  }

不过vuex为我们提供了一个函数,可以更加快速地获取到state中的变量:

import { mapState } from 'vuex'
  export default {
    computed:{
      sCounter(){
        return this.$store.state.counter
      },
      ...mapState(["counter","name"])
    }
  }

mapState传入的是要获取的state中的变量名数组,返回值是变量的computed对象,所以需要用…展开;也可以传入一个对象,可以自定义名字:

...mapState({
  sCounter:state=>state.counter,
  name:state=>state.name
})

在composition API中使用

vuex提供了一个useStore方法让我们在setup中可以获取到store:

import { useStore } from 'vuex'
import { computed } from 'vue'
  export default {
    setup(props) {
      const store = useStore();

      const sCounter = computed(()=>store.state.counter)

      return {
        sCounter
      }
    }
  }

如果要使用mapState,需要进行一些处理:

setup(props) {
      const store = useStore();

      const storeStateFns = mapState(["counter","name"]);
      const storeState = {};
      Object.keys(storeStateFns).forEach(fnKey =>{
        const fn = storeStateFns[fnKey].bind({$store:store});
        console.log(fnKey);
        storeState[fnKey]=computed(fn);
      })

      return {
        ...storeState 
      }
    }

mapState返回的都是函数,在执行时需要用到$store属性,所以需要加上bind。

对以上的内容进行封装以便使用:

      const storeStateFns = mapState(["counter","name"]);
      const storeState = {};
      Object.keys(storeStateFns).forEach(fnKey =>{
        const fn = storeStateFns[fnKey].bind({$store:store});
        console.log(fnKey);
        storeState[fnKey]=computed(fn);
      })

getters

一些数据可能需要结果处理之后再进行显示(和computed类似,不用在每一个组件中写计算属性),定义方式如下:

const store = createStore({
  state(){},
  mutations:{},
  getters:{
    totalPrice(state){
      let totalPrice=0;
      for (const book of state.books){
        totalPrice+=book.count*book.price
      }
      return totalPrice;
    }
  }
});

使用方式:

<h2>总价值:{{$store.getters.totalPrice}}</h2>

getters中定义的函数的第一个参数是state,可以获取state中定义的变量,第二个参数是getters,可以用其调用getters中其它的函数:

  getters:{
    totalPrice(state,getters){
      let totalPrice=0;
      for (const book of state.books){
        totalPrice+=book.count*book.price
      }
      return totalPrice * getters.currentDiscount;
    },
    currentDiscount(state){
      return state.discount*0.9;
    }
  }

getter函数的返回值可以是一个值,在使用时就应该如同上面所示:

<h2>总价值:{{$store.getters.totalPrice}}</h2>

也可以返回一个函数,返回函数的一个目的是传入我们的自定义参数:

totalPriceForCountN(state,getters){
  return function(n){
    let totalPrice=0;
    for (const book of state.books){
      if (book.count>=n){
        totalPrice+=book.count*book.price
      }
    }
    return totalPrice * getters.currentDiscount;
  }
}

使用时需要在后面加上小括号表示函数调用:

<h2>总价值:{{$store.getters.totalPriceForCountN(4)}}</h2>

One thought on “VUE3之VUEX

发表评论