vuex最詳細完整的使用用法(轉載 爲了更乾淨的觀看環境)

爲何使用vuex?vue

vuex主要是是作數據交互,父子組件傳值能夠很容易辦到,可是兄弟組件間傳值(兄弟組件下又有父子組件),或者大型spa單頁面框架項目,頁面多而且一層嵌套一層的傳值,異常麻煩,用vuex來維護共有的狀態或數據會顯得駕輕就熟。webpack

需求:兩個組件A和B,vuex維護的公共數據是 餐館的名稱 resturantName,默認餐館名稱是 飛歌餐館,那麼如今A和B頁面顯示的就是飛歌餐館。若是A修改餐館名稱 爲 A餐館,則B頁面顯示的將會是 A餐館,反之B修改同理。這就是vuex維護公共狀態或數據的魅力,在一個地方修改了數據,在這個項目的其餘頁面都會變成這個數據。
圖片描述圖片描述web

**vue-router

①使用 vue-cli腳手架工具建立一個工程項目,工程目錄,建立組件A和組件B路由以下:

**
圖片描述vuex

路由以下:vue-cli

import Vue from 'vue'
import Router from 'vue-router'
import componentsA from '@/components/componentsA'
import componentsB from '@/components/componentsB'
 
Vue.use(Router)
 
export default new Router({
   mode: 'history',
    routes: [
        {
        path: '/',
        name: 'componentsA',
        component: componentsA
        },
        {
            path: '/componentsA',
            name: 'componentsA',
            component: componentsA
        },
        {
            path: '/componentsB',
            name: 'componentsB',
            component: componentsB
        }
    ]
})

app.vue

<template>
  <div id="app">
    <router-view/>
  </div>
</template>
 
<script>
export default {
  name: 'App'
}
</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,新建一個 store文件夾,分開維護 actions mutations getters

圖片描述

②在store/index.js文件中新建vuex 的store實例

*as的意思是 導入這個文件裏面的全部內容,就不用一個個實例來導入了。app

import Vue from 'vue'
import Vuex from 'vuex'
import * as getters from './getters' // 導入響應的模塊,*至關於引入了這個組件下全部導出的事例
import * as actions from './actions'
import * as mutations from './mutations'
 
Vue.use(Vuex)
// 首先聲明一個須要全局維護的狀態 state,好比 我這裏舉例的resturantName
const state = {
    resturantName: '飛歌餐館' // 默認值
    // id: xxx  若是還有全局狀態也能夠在這裏添加
    // name:xxx
}
 
// 註冊上面引入的各大模塊
const store = new Vuex.Store({
    state,    // 共同維護的一個狀態,state裏面能夠是不少個全局狀態
    getters,  // 獲取數據並渲染
    actions,  // 數據的異步操做
    mutations  // 處理數據的惟一途徑,state的改變或賦值只能在這裏
})
 
export default store  // 導出store並在 main.js中引用註冊。

③actions

// 給action註冊事件處理函數。當這個函數被觸發時候,將狀態提交到mutations中處理
export function modifyAName({commit}, name) { // commit 提交;name即爲點擊後傳遞過來的參數,此時是 'A餐館'
    return commit ('modifyAName', name)
}
export function modifyBName({commit}, name) {
    return commit ('modifyBName', name)
}
 
// ES6精簡寫法
// export const modifyAName = ({commit},name) => commit('modifyAName', name)

④mutations框架

// 提交 mutations是更改Vuex狀態的惟一合法方法
export const modifyAName = (state, name) => { // A組件點擊更改餐館名稱爲 A餐館
    state.resturantName = name // 把方法傳遞過來的參數,賦值給state中的resturantName
}
export const modifyBName = (state, name) => { // B組件點擊更改餐館名稱爲 B餐館
    state.resturantName = name
}

⑤getters異步

// 獲取最終的狀態信息
export const resturantName = state => state.resturantName

⑥在main.js中導入 store實例

// 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
 
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,  // 這樣就能全局使用vuex了
  components: { App },
  template: '<App/>'
})

④在組件A中,定義點擊事件,點擊 修改 餐館的名稱,並把餐館的名稱在事件中用參數進行傳遞。

...mapactions 和 ...mapgetters都是vuex提供的語法糖,在底層已經封裝好了,拿來就能用,簡化了不少操做。函數

其中...mapActions(['clickAFn']) 至關於this.$store.dispatch('clickAFn',{參數}),mapActions中只須要指定方法名便可,參數省略。

...mapGetters(['resturantName'])至關於this.$store.getters.resturantName

<template>
  <div class="componentsA">
      <P class="title">組件A</P>
      <P class="titleName">餐館名稱:{{resturantName}}</P>
      <div>
            <!-- 點擊修改 爲 A 餐館 -->
          <button class="btn" @click="modifyAName('A餐館')">修改成A餐館</button>
      </div>
      <div class="marTop">
          <button class="btn" @click="trunToB">跳轉到B頁面</button>
      </div>
  </div>
</template>
 
<script>
import {mapActions, mapGetters} from 'vuex'
export default {
  name: 'A',
  data () {
    return {
    }
  },
  methods:{
      ...mapActions( // 語法糖
          ['modifyAName'] // 至關於this.$store.dispatch('modifyName'),提交這個方法
      ),
      trunToB () {
          this.$router.push({path: '/componentsB'}) // 路由跳轉到B
      }
  },
  computed: {
      ...mapGetters(['resturantName']) // 動態計算屬性,至關於this.$store.getters.resturantName
  }
}
</script>
 
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
    .title,.titleName{
        color: blue;
        font-size: 20px;
    }
    .btn{
        width: 160px;
        height: 40px;
        background-color: blue;
        border: none;
        outline: none;
        color: #ffffff;
        border-radius: 4px;
    }
    .marTop{
        margin-top: 20px;
    }
</style>

B組件同理

<template>
  <div class="componentsB">
      <P class="title">組件B</P>
      <P class="titleName">餐館名稱:{{resturantName}}</P>
      <div>
          <!-- 點擊修改 爲 B 餐館 -->
          <button class="btn" @click="modifyBName('B餐館')">修改成B餐館</button>
      </div>
      <div class="marTop">
          <button class="btn" @click="trunToA">跳轉到A頁面</button>
      </div>
  </div>
</template>
 
<script>
import {mapActions, mapGetters} from 'vuex'
export default {
  name: 'B',
  data () {
    return {
    }
  },
  methods:{
      ...mapActions( // 語法糖
          ['modifyBName'] // 至關於this.$store.dispatch('modifyName'),提交這個方法
      ),
      trunToA () {
          this.$router.push({path: '/componentsA'}) // 路由跳轉到A
      }
  },
  computed: {
      ...mapGetters(['resturantName']) // 動態計算屬性,至關於this.$store.getters.resturantName
  }
}
</script>
 
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
    .title,.titleName{
        color: red;
        font-size: 20px;
    }
    .btn{
        width: 160px;
        height: 40px;
        background-color: red;
        border: none;
        outline: none;
        color: #ffffff;
        border-radius: 4px;
    }
    .marTop{
        margin-top: 20px;
    }
</style>

做者:飛歌Fly
來源:CSDN
原文:https://blog.csdn.net/qq_3543... 版權聲明:本文爲博主原創文章,轉載請附上博文連接!

相關文章
相關標籤/搜索