vuex從入門到實戰多功能TodoList

1.vuex的核心蓋概念

Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。他可以方便實現組件之間的數據共享
在這裏插入圖片描述

1.1 state

state 提供唯一的數據資源,所有的共享的數據都要統一放到store 中的state中進行存儲

  • 組件中訪問state第一種方式:

this.$store.state.全局數據名稱

  • 組件中訪問state第二種方式:

1.從vuex中按需求導入mapState函數
import {mapState} from 'vuex'
通過剛纔導入的mapState函數,將當前組件需要的全局數據,映射爲當前組件的computed計算屬性
2. 將全局數據,映射爲當前組件的計算屬性
computed :{ ...mapState(['count']) }

1.2 mutation

mutation用於變更store中的數據
①只能通過mutation更Store數據,不可以直接操作Store中的數據。
②通過這種方式雖然操作起來稍微繁瑣一些,但是可以集中監控所有數據的變化。

  1. this.$store.commit()是觸發mutations的第一種方式,
//store.js中定義mutations
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
   add(state) {
   //更改狀態
    state.count++
   }
  }
})
//組件中接收觸犯mutations
methods: {
    add() {
      this.$store.commit('add')
    },

  },



//mutations可以傳遞參數
 mutations: {
   add2(state,step) {
    state.count += step
   }
  }
//觸發帶參數的mutation
methods: {
    add() {
      this.$store.commit('add',3)
    },

  },
  1. 觸發mutations的第二種方式:通過以函數映射的方式

1.從vuex中按需求導入mapState函數
import {mapMutations} from 'vuex'
通過剛纔導入的mapState函數,將當前組件需要的全局數據,映射爲當前組件的computed計算屬性
2. 將指定的mutations函數,映射爲當前組件的methods函數
methods:{ ...mapMutations(['add']) }

1.3 action

用於處理異步任務
如果通過異步操作變更數據,必須通過Action,而不能使用Mutation,但是在Action中還是要通過觸發
Mutation的方式間接變更數據。

  1. this.$store.dispatch是觸發actions的第一 種方式
//定義store.js 中定義action
  actions: {
    addAsync(context) {
      setTimeout(()=> {
        context.commit('add')
      },1000)
    }
  }


//在事件方法中通過dispatch觸發action
add () {
    //  觸發action
    this.$store.dispatch('addAsync')
  }


觸發異步任務攜帶參數

  mutations: {
   add(state,step) {
    state.count += step
   }
  },
  actions: {
    addAsync(context,step) {
      setTimeout(()=> {
        context.commit('add',step)
      },1000)
    }
  }
//觸發action
add () {
    this.$store.dispatch('addAsync',5)
  }
  1. 觸發actions的第二 種方式:通過以函數映射的方式

1.從vuex中按需求導入mapState函數
import {maptActions} from 'vuex'
通過剛纔導入的mapState函數,將當前組件需要的全局數據,映射爲當前組件的computed計算屬性
2. 將指定的mutations函數,映射爲當前組件的methods函數
methods:{ ...maptActions(['addAsync']) }

1.4 getter

Getter於對Store中的數據進行加工處理形成新的數據。他不會修改state中的原始數據起到的是包裝數據的作用
①Getter 可以對Store中已有的數據加工處理之後形成新的數據,類似Vue的計算屬性。
②Store 中數據發生變化,Getter 的數據也會跟着變化。

  1. this.$store.getters.名字是的調用getters第一 種方式
//組件中調用
 {{$store.getters.showNum}}
 //store.js中定義
   getters: {
    showNum (state){
      return `當前最新的數據${state.count}`
    }
  }
  1. 通過以函數映射的方式

1.從vuex中按需求導入mapState函數
import {maptGetters} from 'vuex'
通過剛纔導入的mapState函數,將當前組件需要的全局數據,映射爲當前組件的computed計算屬性
2. 將指定的mutations函數,映射爲當前組件的methods函數
computed :{ ...maptGetters(['showNum']) }

2.用vue實現todoList功能

開發準備

  • antd-vue組件庫
  • vuex

需求分析

  • 添加事件功能
  • 標記事件功能
  • 刪除事件功能

代碼分享

組件代碼 VuexTodoList.vue

//組件代碼 VuexTodoList.vue
<template>
  <div id="app">
    <a-input placeholder="請輸入任務" class="my_ipt" :value="inputValue" @change="handleInputChange" />
    <a-button type="primary" @click="addItemToList">添加事項</a-button>

    <a-list bordered :dataSource="infolist" class="dt_list">
      <a-list-item slot="renderItem" slot-scope="item">
        <!-- 複選框 -->
        <a-checkbox :checked="item.done" @change="(e) => {cbStatusChanged(e, item.id)}">{{item.info}}</a-checkbox>
        <!-- 刪除鏈接 -->
        <a slot="actions" @click="removeItemById(item.id)">刪除</a>
      </a-list-item>

      <!-- footer區域 -->
      <div slot="footer" class="footer">
        <!-- 未完成的任務個數 -->
        <span>{{unDoneLength}}條剩餘</span>
        <!-- 操作按鈕 -->
        <a-button-group>
          <a-button :type="viewKey === 'all' ? 'primary' : 'default'" @click="changeList('all')">全部</a-button>
          <a-button :type="viewKey === 'undone' ? 'primary' : 'default'" @click="changeList('undone')">未完成</a-button>
          <a-button :type="viewKey === 'done' ? 'primary' : 'default'" @click="changeList('done')">已完成</a-button>
        </a-button-group>
        <!-- 把已經完成的任務清空 -->
        <a @click="clean">清除已完成</a>
      </div>
    </a-list>
  </div>
</template>

<script>
import { mapState, mapGetters } from 'vuex'

export default {
  name: 'app',
  data() {
    return {}
  },
  created() {
    this.$store.dispatch('getList')
  },
  computed: {
    ...mapState(['inputValue', 'viewKey']),
    ...mapGetters(['unDoneLength', 'infolist'])
  },
  methods: {
    // 監聽文本框內容變化
    handleInputChange(e) {
      this.$store.commit('setInputValue', e.target.value)
    },
    // 向列表中新增 item 項
    addItemToList() {
      if (this.inputValue.trim().length <= 0) {
        return this.$message.warning('文本框內容不能爲空!')
      }

      this.$store.commit('addItem')
    },
    // 很據Id刪除對應的任務事項
    removeItemById(id) {
      // console.log(id)
      this.$store.commit('removeItem', id)
    },
    // 監聽複選框選中狀態變化的事件
    cbStatusChanged(e, id) {
      // 通過 e.target.checked 可以接受到最新的選中狀態
      // console.log(e.target.checked)
      // console.log(id)
      const param = {
        id: id,
        status: e.target.checked
      }

      this.$store.commit('changeStatus', param)
    },
    // 清除已完成的任務
    clean() {
      this.$store.commit('cleanDone')
    },
    // 修改頁面上展示的列表數據
    changeList(key) {
      // console.log(key)
      this.$store.commit('changeViewKey', key)
    }
  }
}
</script>

<style scoped>
#app {
  padding: 10px;
}

.my_ipt {
  width: 500px;
  margin-right: 10px;
}

.dt_list {
  width: 500px;
  margin-top: 10px;
}

.footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>

狀態管理代碼store.js

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    // 所有的任務列表
    list: [],
    // 文本框的內容
    inputValue: 'aaa',
    // 下一個Id
    nextId: 5,
    viewKey: 'all'
  },
  mutations: {
    initList(state, list) {
      state.list = list
    },
    // 爲 store 中的 inputValue 賦值
    setInputValue(state, val) {
      state.inputValue = val
    },
    // 添加列表項
    addItem(state) {
      const obj = {
        id: state.nextId,
        info: state.inputValue.trim(),
        done: false
      }
      state.list.push(obj)
      state.nextId++
      state.inputValue = ''
    },
    // 根據Id刪除對應的任務事項
    removeItem(state, id) {
      // 根據Id查找對應項的索引
      const i = state.list.findIndex(x => x.id === id)
      // 根據索引,刪除對應的元素
      if (i !== -1) {
        state.list.splice(i, 1)
      }
    },
    // 修改列表項的選中狀態
    changeStatus(state, param) {
      const i = state.list.findIndex(x => x.id === param.id)
      if (i !== -1) {
        state.list[i].done = param.status
      }
    },
    // 清除已完成的任務
    cleanDone(state) {
      state.list = state.list.filter(x => x.done === false)
    },
    // 修改視圖的關鍵字
    changeViewKey(state, key) {
      state.viewKey = key
    }
  },
  actions: {
    getList(context) {
      axios.get('/list.json').then(({ data }) => {
        // console.log(data)
        context.commit('initList', data)
      })
    }
  },
  getters: {
    // 統計未完成的任務的條數
    unDoneLength(state) {
      return state.list.filter(x => x.done === false).length
    },
    infolist(state) {
      if (state.viewKey === 'all') {
        return state.list
      }
      if (state.viewKey === 'undone') {
        return state.list.filter(x => !x.done)
      }
      if (state.viewKey === 'done') {
        return state.list.filter(x => x.done)
      }
      return state.list
    }
  }
})

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章