2018.3.1更:
有贊·微商城(base杭州)部門招前端啦,最近的前端hc有十多個,跪求大佬扔簡歷,我直接進行內推實時反饋進度,有興趣的郵件 lvdada#youzan.com,或直接微信勾搭我 wsldd225 瞭解跟多html
有贊開源組件庫·zanUI前端
初次接觸vue,刷完了堪稱經典的vue官網文檔+vue-router文檔+vuex文檔+vue-cli文檔,而後就開始刷項目了。這篇文章總結了項目實踐的一些思路。
首先看下項目的總覽圖(mockplus製做)vue
這個項目我負責的部分是一個控制檯的需求,用戶能夠在這個模塊進行佣金、訂單等項目的修改設置,能夠看到第1張圖至關於控制檯首頁,頁面上有一、二、三、四、5個入口,其中1-4入口進入的頁面對應4個頁面,可是4個頁面主要結構相同,中間商品列表樣式信息不一樣,爲了簡略4圖歸爲第二張圖。入口5對應第三張圖。vue-router
這幾個頁面需求並不複雜,大項目自己也是是基於zepto的,單單把這個模塊拿出來抽離成單頁形式主要爲了兩點考慮:vuex
基於以上兩點使用vue以及vue大禮包編寫了這個單頁模塊。vue-cli
由入口而知一共有6個頁面(包含控制檯首頁),雖然是單頁模塊,也是必需要符合經過url地址直接進入對應分頁的需求。在切換的過程當中,留下url路由信息也方便用戶進行後退操做。json
首先是頂級路由的配置,六個頁面(組件)分別設置六個頂級路由。api
// 在App.vue文件中設置<router-view> <template> <div id="app"> <router-view keep-alive :style="{'padding-bottom': paddingBottom + 'rem'}"></router-view> </div> </template>
// 在main.js中配置路由 router.map({ '/': { component: Index, name: 'index' }, '/commission': { name: 'commission', component: Commission }, '/order': { name: 'order', component: Order }, '/inventory': { name: 'inventory', component: Inventory }, '/shop': { name: 'shopList', component: ShopList }, '/qcode': { name: 'qcode', component: Qcode } })
由上圖具體的佣金頁面(組件)能夠看到,這個頁面有兩個主要操做,一:搜索,根據搜索結果展現商品條目;二:翻頁,根據頁數展現商品條目。數組
原始的思路是搜索與翻頁都在當前頁面(組件)操做,將異步獲取的數據替換當前頁面的items數組。Vue會將變化的數據與view綁定,同步刷新view頁面。微信
這樣作有個缺陷,任何操做(搜索、翻頁)都不會留下可追溯的路徑,假設有個場景:
用戶翻n頁,發現了一款商品點擊進入詳情頁(外鏈,屬於大項目中的頁面),用戶返回佣金設置頁面時發現又從第一頁開始瀏覽了。
基於此類場景結合vue-router的路由查詢參數功能能夠換一種實現方式。
點擊搜索再也不在當前頁面(組件)異步請求數據,而是經過$route對象進行路由跳轉。
this.$route.router.go({ name: 'index', query: { keyWord: 'searchWorld', page: 1 } })
根據上圖,搜索n次,或者是點擊翻頁n次,都會改變當前的url的查詢參數。實際上改變路由查詢參數,就至關於從新進入一次當前頁面(組件),Vue會識別計算是否重用當前組件,這種狀況<router-view>並不會產生切換效果,由於即便查詢參數變化,當前頁面組件始終都是component: Commission
同一個組件。
這樣設計就留下了一系列的路徑,可供歷史回退。
那麼數據該如何獲取呢?
vue-router
有一個「切換控制流水線」的概念,即在不一樣路由切換的過程當中會有不一樣的鉤子函數能夠調用。
其中data
鉤子函數無論組件是否能夠重用,在每次路由切換的時候都會觸發。
route: { data (transition) { this.$http.get('/api/test/test', { params: { keyword: this.keyWord, page: this.currentPage, pageSize: this.numberPerPage } }).then((response) => { transition.next({ items: response.json().data.item.items, listNumber: response.json().data.item.totalNum }) }, (response) => { // error }) } },
這樣實現了數據的獲取,參數部分依靠當前組件的$route
對象獲取。
上文已經提到的6大分頁其實就是6個組件,可是爲了在開發環境下區分資源,將這6個組件放在了views文件下內。
| |-src | | | |-components | |-views | | |-Index.vue | | |-Commission.vue | | |-Order.vue | | |-...
由上圖可知能夠將1.title 2.搜索欄 3.confirm 4.toast 5.分頁器 6.loading等待封裝成全局組件。在main.js
中進行註冊。
import Toast from './components/common/Toast' Vue.component('c-toast', Toast); ... ...
商品列表也能夠抽離成組件,可是在每一個分頁裏的商品列表是不一樣的,因此每一個分頁裏的商品列表都獨立抽離成組件,並註冊在對應的分頁組件裏。
import ListCommission from '../components/ListCommission' export default { name: 'commission', components: { ListCommission } }
控制檯這個模塊狀態並不複雜,多數狀態的傳遞都只發生在父組件和子組件這種上下層級的關係之間。
好比Commission組件(佣金分頁)中的ListCommission組件(佣金頁的商品列表組件)之間的狀態傳遞就只發生在這兩級之間。
// Commission.vue <template> <list-commission :visible="listNumber > 0" v-if="!$loadingRouteData" :items="items"></list-commission> </template>
其中items
狀態屬於父組件,會傳遞到ListCommission
組件內供其view展現。這種狀態稱爲「組件本地狀態」,組件自己管理本身的狀態。
可是如今有這麼一個功能點,生成二維碼模塊須要使用一個完整url路徑,這個路徑須要根據測試、線上環境的不一樣對應.net/.com
。這個狀態也許還有許多不一樣層級的組件須要使用,那麼這樣的狀態就適合用vuex去管理。
1.首先在store中定義狀態初始值
const state = { suffix: '.net' }
2.在根組件App.vue中觸發action
let suffix = window.location.hostname.indexOf('showjoy.net') > -1 ? '.net' : '.com'; export const setGlobalSuffix = function ({dispatch}, suffix) { dispatch('SET_GLOBAL_SUFFIX', suffix); } this.setGlobalSuffix(suffix);
3.觸發dispatch
SET_GLOBAL_SUFFIX (state, suffix) { state.suffix = suffix; }
4.get狀態
export function getSuffix (state) { return state.suffix; }
只要在相應組件中定義了getSuffix的getters,就能夠在相應的組件中調用這個函數,獲取suffix狀態。此時suffix狀態可稱爲「應用層級狀態」。應用層級狀態不屬於任何特定的組件,但每一個組件均可以監視其變化並響應式的更新DOM。
suffix
狀態只是一個簡單的例子,像上圖所示,當同級組件之間或者是不一樣直系關係的父子組件之間須要進行狀態的變動,依賴「組件本地狀態」將難以維護。
好比Commission組件
須要改變Order組件
的一個狀態,若是不借助vuex,那麼須要顯示的編寫事件將狀態分發到上層組件App,Order組件須要監聽這個事件。狀態變動一多,那維護將是噩夢。
對我以上的理解有疑問和意見的歡迎找我私聊~微博-寫前端的暹羅