uni-app中應用vuex示例

uni-app是當前前端開端多端應用的一個強大的工具,可以同時七端發佈。由於之前前端的功能較簡單,所以前端一般不重視程序架構設計,通常所說的MVVM等架構,一般也就止步於VUE就是基於MVVM,使用VUE就是採用MVVM架構,而實際上採用架構的作用,就是要使應用代碼職責分離,增加可維護性。在本篇博文中,我將向大家展示,怎樣通過使用VUEX,將業務邏輯代碼由.vue文件中抽取出來,形成一個職責清晰的應用架構。

整體架構

我們首先來看一下程序的整體架構:
在這裏插入圖片描述
如上圖所示,我們在store中保存vuex的store定義,以及store下的模塊定義。在pages裏面是頁面*.vue文件,components中是我們頁面將要使用的組件,這裏定義了兩個組件:cart和products,分別用來顯示購物車和商品列表,api下保存與後臺接口交互的模塊,這裏定義的是shop。

全局引用vuex

我們首先在main.js引入vuex的總store:

....................................
import store from './store'
....................................
const app = new Vue({
	store,
    ...App
})
...................................

我們在這裏定義的store,可以在應用任何頁面中引用。

主頁面

接着我們定義示例的頁面,這個頁面引用購物車和商品組件顯示相關內容:

<template>
  <div id="app">
    <h3>購物車示例</h3>
    <hr>
    <h5>產品列表</h5>
    <ProductList/>
    <hr>
    <ShoppingCart/>
  </div>
</template>

<script>
import ProductList from '../../components/ProductList.vue'
import ShoppingCart from '../../components/ShoppingCart.vue'
export default {
  components: { ProductList, ShoppingCart }
}
</script>

商品組件

商品組件主要是顯示商品列表,如下所示:

<template>
  <ul>
    <li
      v-for="product in products" :key="product.id">
      {{ product.title }} - {{ product.price}}
      <br>
      <button
        :disabled="!product.inventory"  
		@click="addProductToCart(product)">
        加入購物車
      </button>
	  <button @click="test001">測試</button>
	  <button @click="test002">內部</button>
    </li>
  </ul>
</template>

<script>
import { mapState, mapActions } from 'vuex'
export default {
  computed: {
	...mapState({
		products: state => state.products.all
	})
  },
  methods: {
	...mapActions('cart', ['addProductToCart']),
	...mapActions({
		test001: 'products/test001'
	}),
	test002: (e) => {
		console.log('頁面內事件')
	}
  },
  created () {
    this.$store.dispatch('products/getAllProducts')
  }
}
</script>

頁面用v-for顯示商品列表,加入購物車按鈕可以調用store.cart模塊的addProductToCart,將其加入購物車中;測試按鈕顯示另外一種方式調用store模塊的actions方法,內部按鈕顯示僅用於頁面內事件,無需使用vuex。
在腳本部分,首先引入vuex的mapState和mapActions,雖然有其他方法實現同樣任務,但是建議統一使用這種方式。
在計算屬性部分,我們將store中products.all屬性賦給頁面的計算屬性products。
在方法部分,我們將加入購物車按鈕的響應事件,定義爲調用store的cart模塊的addProductToCart的actions;將測試按鈕的單擊響應事件,定義爲調用store的products模塊的test001的actions;將內部按鈕的單擊響應事件,定義爲調用頁面內消息響應函數。在頁面創建完成的生命週期函數中,調用store的products模塊的getAllProducts的actions。

products模塊

接下來我們來看products模塊:

import shop from '../../api/shop'

// initial state
const state = {
  all: []
}

// getters
const getters = {}

// actions
const actions = {
  getAllProducts ({ commit }) {
    shop.getProducts(products => {
      commit('setProducts', products)
    })
  },
  test001() {
	  console.log('store.products.test001 is running...')
  }
}

// mutations
const mutations = {
  setProducts (state, products) {
    state.all = products
  },

  decrementProductInventory (state, { id }) {
    const product = state.all.find(product => product.id === id)
    product.inventory--
  }
}

export default {
  namespaced: true,
  state,
  getters,
  actions,
  mutations
}

這裏我們看到,其有一個all的屬性,就是主頁中要顯示的商品列表數據。
接下來定義getter方法,這裏沒有定義。
在接下來是定義actions,當我們要在異步請求中更新store.state時,需要調用actions中的方法,由這些方法調用對應的mutation,而mutation只能是同步調用。例如這裏定義的getAllProducts,由於需要調用網絡請求,因此是異步的,所以需要在actions裏調用mutation方法。大家可以看到,調用shop對應的方法時,參數爲一個箭頭函數,當API層處理返回函數時,會執行這個箭頭函數,在這個箭頭函數中調用commit方法,由vuex處理爲對mutation方法的調用。
接下來定義mutation方法,該方法去實際更新state中的數據。
我們在getAllProducts中看到,我們要調用api層的shop來實現從後臺取商品列表數據的功能,因此我們來看api層的實現。

API層

這一層主要用於處理與後臺交互,以getAllProducts爲例:

/**
 * Mocking client-server processing
 */
const _products = [
  {"id": 1, "title": "魚香肉絲", "price": 25.01, "inventory": 20},
  {"id": 2, "title": "宮爆雞丁", "price": 30.99, "inventory": 10},
  {"id": 3, "title": "剁椒魚頭", "price": 59.99, "inventory": 5}
]

export default {
  getProducts (cb) {
    setTimeout(() => cb(_products), 100)
  },

  buyProducts (products, cb, errorCb) {
    setTimeout(() => {
      // simulate random checkout failure.
      (Math.random() > 0.5 || navigator.userAgent.indexOf('PhantomJS') > -1)
        ? cb()
        : errorCb()
    }, 100)
  }
}

這裏爲了簡化,沒有使用Axiox調用網絡請求,只使用定時函數,返回一個寫死的結果,並調用回調函數,完成整個流程。

發佈了204 篇原創文章 · 獲贊 1236 · 訪問量 124萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章