Vue3 Composition API 中使用 Vuex

下面是一个Vue3 Composition API 中使用Vuex的实例todoList,用到了state,mutations,actions,可以把自己之前用vue2的旧语法改写成vue3的语法,使用setup,ref, reactive, toRefs,useStore等,完整代码指路:github: color-library

<!-- todoList.vue -->
<template>
  <div class="todo-list-wrap">
    <h2>{{ title }}</h2>
    <div class="name-wrap">
      <h3>{{ name }}</h3>
      <el-button @click="handleChangeName">
        修改
      </el-button>
      <el-button @click="handleRestoreName">
        还原
      </el-button>
    </div>
    <div class="input-wrap">
      <el-input v-model="inputVal"  @keyup.enter="handleAddItem"></el-input>
      <el-button @click="handleAddItem">
        新增
      </el-button>
    </div>
    <div class="list-item-wrap">
      <div v-for="(item,index) in dataList" :key="index" class="list-item">
        <span>{{ item }}</span>
      </div>
    </div>
  </div>
</template>
<script>
import { ref, reactive, toRefs } from 'vue'
import { useStore } from 'vuex'

  export default {
    name: 'TodoList',
    setup() {
      const title = ref('TodoList')
      const store = useStore()
      const { name } = toRefs(store.state) // 解构
      const inputVal = ref('')
      const dataList = reactive([])
      
      const handleAddItem = ()=> {
        dataList.push(inputVal.value)
        inputVal.value = ''
      }
      const handleChangeName = ()=> {
        // commit和mutations做关联,提交一个commit,触发一个mutation
        store.commit('changeName', 'Happy')
      }
      const handleRestoreName = ()=> {
        // dispatch和actions做关联,派发一个action
        store.dispatch('getData', 'Biblee')
      }
      return {
        title,
        name,
        inputVal,
        dataList,
        handleAddItem,
        handleChangeName,
        handleRestoreName
      }
    }
  }
</script>

<style lang="scss" scoped>
.todo-list-wrap {
  padding: 20px;
  
}
.name-wrap {
  margin: auto;
  display: flex;
  justify-content: center;
  align-items: center;
}
.input-wrap {
  width: 300px;
  margin: auto;
  display: flex;
}
.el-button {
  margin-left: 8px;
}
.list-item-wrap {
  padding: 16px;
  .list-item {
    text-align: left;
  }
}
</style>

store:

// store/index.js
import { createStore } from "vuex"

export default createStore({
  state: {
    name: 'Biblee'
  },
  // 同步操作
  mutations: {
    changeName(state, val) {
      state.name = val
    }
  },
  // 异步操作
  actions: {
    getData(store, val) {
      setTimeout(()=>{
        store.commit('changeName',val)
      },2000)
    }
  },
  modules: {

  }
})
posted @ 2021-09-12 22:42  叶子玉  阅读(650)  评论(2编辑  收藏  举报