日韩精品一区二区三区在线视频放-无码中文字幕V?一区二区-成年片免费观看视频-国内少妇人妻丰满av-国产精品中文字幕免费观看-亚洲成人久久一区二区三区-国内少妇偷人精品视频无缓冲-一区二区国产精品日本一区二区三区在线网

ARTICLE DETAIL

資訊詳情

深耕商務建站與企業(yè)官網運營的一線實戰(zhàn)洞察。

Vuex 4 狀態(tài)管理全解析:核心原理、模塊拆分與高頻踩坑

Vuex 4 狀態(tài)管理全解析:核心原理、模塊拆分與高頻踩坑 Vuex 這玩意兒現(xiàn)在提起來有點微妙。新項目里 Pinia 基本是默認選項很多人一上手 Vue 3 就沒碰過 Vuex。但你去翻一翻手上維護的那些跑了三四年的中后臺系統(tǒng)十有八九還在store/index.js里躺著幾十個 mutation改一個字段要先找 action、再找 mutation、最后才敢動 state。這時候你要是連 Vuex 的執(zhí)行鏈路都說不清楚排查問題基本靠猜。這篇就把 Vuex 的知識點掰開揉碎講透從“到底什么時候該用它”到“store 怎么拆模塊”再到“為什么我的 commit 沒生效”這類真實踩坑全部過一遍。適合兩類人看一類是剛接手老項目、被mapState和各種root: true繞暈的新手另一類是想把狀態(tài)管理這塊徹底搞清楚、以后不管換 Pinia 還是別的庫都能快速上手的同學。代碼以 Vuex 4 Vue 3 為主線涉及 Vue 2 的差異我會單獨標出來。1. 先搞清楚什么時候真的需要 Vuex1.1 狀態(tài)管理的邊界到底在哪我在帶人的時候發(fā)現(xiàn)一個特別普遍的問題很多人學完 Vuex 的第一反應是“好東西全塞進去”。結果一個只有三個頁面的小工具store 里堆了二十多個字段其中一半是某個組件內部的彈窗開關。這就屬于把狀態(tài)管理當成了全局變量倉庫最后維護成本比不用還高。判斷一個狀態(tài)該不該進 store我一般看三條第一這份數據是不是被兩個以上互不相鄰的組件同時使用。父子組件之間傳值props加emit就夠了爺孫層級深一點provide/inject也能解決。只有當兄弟組件、或者跨了好幾層的遠房親戚都要讀寫同一份數據時才輪到 Vuex 出場。第二這份數據是不是跨越了路由。比如登錄態(tài)、用戶信息、權限菜單從 A 頁面跳到 B 頁面還得用這種放在組件里必然會隨著組件銷毀而丟失必須提上去。第三這份數據變更后是不是需要留下可追溯的痕跡。Vuex 配 devtools 能記錄每一次 mutation 的時間旅行對于復雜的表單聯(lián)動、購物車增刪改這個調試能力值不少時間。反過來說哪些不該進 store組件的 loading 狀態(tài)、某個列表的滾動位置、彈窗的顯隱開關這些都屬于“局部狀態(tài)”跟著組件生命周期走才是最干凈的。我見過有人把dialogVisible放進 store結果兩個頁面復用同一個彈窗組件時互相干擾排查了半天才發(fā)現(xiàn)是狀態(tài)被共享了。記住一句話狀態(tài)放得越高耦合就越重能不升就不升。還有一種常見誤區(qū)是把接口返回的原始數據全量塞進 store然后組件里再filter一遍。這樣做的問題在于 store 變成了緩存層但你又沒做失效策略最后數據新舊不一致的 bug 特別難查。我的習慣是 store 只存“經過業(yè)務加工、有明確語義”的狀態(tài)原始響應體在 action 里處理完就丟掉。1.2 Vuex 和 Pinia 到底怎么選這個話題繞不開。Pinia 確實是官方現(xiàn)在主推的方案API 更簡潔、TypeScript 支持更好、沒有 mutation 這一層。但“新項目用 Pinia”不等于“Vuex 就沒用了”。我整理了一張對照表你對著自己項目的情況看就行。對比維度Vuex 4Pinia變更入口mutation 提交action 觸發(fā)直接改 stateaction 里也能改模塊機制modules namespaced 嵌套每個 store 天然獨立TypeScript 支持需要額外類型聲明較繁瑣原生推導幾乎零配置devtools 時間旅行支持粒度到 mutation支持粒度到 action代碼量一個功能要寫 state/getter/mutation/action 四份基本一份 setup 或 option 就夠學習曲線概念多鏈路長概念少接近組合式函數存量項目兼容原生可與 Vuex 共存逐模塊遷移適合場景老項目維護、團隊已有約定新項目、TS 重度使用我的實際經驗是已經在跑的 Vuex 項目別為了追新去動它。遷移本身不難難的是遷移期間兩套狀態(tài)管理并存帶來的心智負擔以及測試覆蓋不足時的回歸風險。真要遷也是按模塊一個個搬先把用戶模塊搬過去跑一周沒問題再搬下一個。反倒是新起的項目沒有歷史包袱直接上 Pinia 更省事。不過有一點要說清楚Vuex 那套“mutation 必須同步、action 處理異步”的約束雖然寫起來啰嗦但它強迫你把“改數據”和“做業(yè)務”分開這個思維在團隊協(xié)作里是有價值的。很多 Pinia 新手直接在 action 里一頓this.xxx yyy出了問題連是哪一步改的都定位不到。所以就算你用的是 Pinia也建議保留“純函數式改狀態(tài)”的習慣。1.3 一張判斷清單幫你決定要不要引入我給自己團隊寫過一個很土但很好用的清單五個問題中三個以上才考慮上 Vuex有沒有一份數據被三個以上的組件讀取且這些組件不在同一條父子鏈上這份數據會不會因為路由切換而需要保留這份數據的修改是否需要多人協(xié)作、且改動點分散在多個文件出問題時是否需要回放“誰在什么時候改了什么”項目規(guī)模是不是已經超過二十個頁面或者五個以上的業(yè)務模塊如果只中一兩條老老實實用props加組合式函數封裝別給自己找事。狀態(tài)管理的本質是降低溝通成本不是炫技。2. Vuex 的五個核心概念一次捋直2.1 state單一狀態(tài)樹和它的設計原則Vuex 把所有狀態(tài)收攏到一棵樹里官方叫單一狀態(tài)樹Single Source of Truth。好處是任何一個時刻你都能通過store.state拿到應用完整的數據快照調試的時候特別直觀。壞處是這棵樹如果沒人管長到幾百個字段之后新人進來根本看不懂哪個字段屬于哪個業(yè)務。我的做法是按業(yè)務域切分而不是按數據類型切分。什么叫按數據類型切就是state.list、state.detail、state.loading這么平鋪看著整齊實際上一旦業(yè)務變多就全亂。按業(yè)務域切就是user、order、permission各占一塊每個模塊自洽。具體到寫法Vuex 4 里定義模塊的 state 一定要用函數返回對象// store/modules/user.js const state () ({ profile: null, token: , roles: [], permissionLoaded: false })為什么必須是函數因為模塊在注冊時會被合并進根 state如果直接寫對象字面量多個組件實例或者熱更新場景下會共享同一份引用出現(xiàn)“A 頁面改了 B 頁面也變了”的靈異事件。這個坑我在服務端渲染的項目里踩過一次排查了整整一個下午。另外 state 里的字段命名要帶語義。data、info、list這種詞盡量別用orderList、userProfile、pendingTaskCount一眼就知道是什么。字段一多命名就是最好的文檔。2.2 getters派生狀態(tài)和它的緩存機制getters 可以理解為 store 里的 computed。它的返回值會基于依賴做緩存依賴不變就不重新計算。這個特性用好了能省不少性能用不好反而會成為 bug 來源。const getters { isLogin: state Boolean(state.token), displayName: state state.profile?.nickname || state.profile?.username || 未登錄, // 依賴其他 getter第二個參數是當前模塊的 getters welcomeText: (state, getters) ${getters.displayName}歡迎回來, // 依賴根 state第四個參數是 rootState hasPermission: (state, getters, rootState) code { return state.roles.includes(code) || rootState.user.roles.includes(code) } }這里有個關鍵點getter 返回函數時緩存就失效了。上面hasPermission返回的是一個函數每次調用都會重新執(zhí)行因為 Vue 沒法追蹤函數內部用到的參數。這種寫法適合做權限判斷這類需要傳參的場景但別在模板里高頻調用它尤其是列表渲染里v-for每一項都調一次性能會明顯下降。真要這么用先在 computed 里把結果算好。還有一個容易翻車的地方getter 里返回新對象。比如// 不推薦每次都返回新數組緩存形同虛設 filteredList: state state.list.filter(item item.active)因為filter每次執(zhí)行都會產生新數組引用Vue 的依賴追蹤會認為結果變了導致依賴這個 getter 的組件反復更新。如果這個列表很大、更新又頻繁頁面會明顯卡頓。正確做法是把過濾邏輯放到組件 computed 里或者用shallowRef之類的思路做手動緩存。我在一個萬級數據的表格項目里就吃過這個虧后來把 getter 改成了只做簡單映射流暢度立刻回來了。2.3 mutations為什么它必須是同步的這是 Vuex 里被問得最多的問題?!拔揖驮?mutation 里發(fā)個請求怎么了”答案藏在 devtools 的工作原理里。devtools 記錄狀態(tài)變化的方式是每執(zhí)行一次 mutation就拍一張 state 的快照存進時間線。如果你在 mutation 里發(fā)異步請求那么“mutation 開始執(zhí)行”和“state 真正被改”之間存在時間差devtools 拍到的那張快照可能是請求還沒回來的中間態(tài)。等你點時間旅行回到某一步看到的狀態(tài)和實際不符調試就徹底失去了意義。所以 Vuex 強制 mutation 同步是為了保證每一幀快照都是確定性的。const mutations { SET_PROFILE(state, payload) { state.profile payload }, SET_TOKEN(state, token) { state.token token }, ADD_ROLE(state, role) { if (!state.roles.includes(role)) { state.roles.push(role) } }, RESET(state) { // 重置時不要直接替換整個 state 對象Vue 會丟失響應式追蹤 Object.assign(state, { profile: null, token: , roles: [], permissionLoaded: false }) } }mutation 的命名我統(tǒng)一用全大寫加下劃線這是社區(qū)慣例好處是在 devtools 列表里一眼就能和 action 區(qū)分開。action 用小駝峰比如fetchProfile。這套約定看起來是小事但團隊人多的時候能省掉很多溝通。還有一個細節(jié)mutation 里不要做副作用。什么叫副作用發(fā)請求、寫 localStorage、彈 toast這些都算。mutation 應該是一個純函數給它同樣的輸入state 就變成同樣的結果。這樣你寫單元測試的時候只需要斷言 state 變化不用 mock 一堆東西。2.4 actions異步編排和業(yè)務邏輯的落腳點action 是 Vuex 里唯一允許寫異步的地方它不直接改 state而是通過commit觸發(fā) mutation。這個設計看起來多繞了一層實際上把“業(yè)務流程”和“數據變更”解耦了。const actions { async fetchProfile({ commit, state, dispatch }, force false) { if (state.profile !force) { return state.profile } const res await api.getUserProfile() commit(SET_PROFILE, res.data) // 跨模塊調用要加 root: true await dispatch(permission/loadRoutes, res.data.roles, { root: true }) return res.data }, async login({ commit, dispatch }, { username, password }) { const { token } await api.login({ username, password }) commit(SET_TOKEN, token) await dispatch(fetchProfile, true) }, logout({ commit }) { commit(RESET) commit(permission/RESET, null, { root: true }) } }action 的返回值很重要。因為 action 內部是 Promise你可以在組件里await store.dispatch(login, form)拿到結果后再做跳轉或者提示。很多老代碼里 action 不 return組件只能靠 watch 某個 state 來判斷成功與否這種寫法非常脆弱。養(yǎng)成習慣action 有結果就 return 出去??缒K dispatch 的{ root: true }是新手最容易漏的參數。不加這個參數Vuex 會只在當前模塊內查找 action找不到就靜默失敗或者報unknown action type。我第一次遇到的時候盯著代碼看了半小時最后發(fā)現(xiàn)就是少了個 root。2.5 modules 和 namespaced拆分與隔離項目一大單文件 store 必然爆炸。modules 就是用來拆的而namespaced: true決定了拆完之后彼此是否隔離。// store/index.js import { createStore } from vuex import user from ./modules/user import permission from ./modules/permission import cart from ./modules/cart export default createStore({ strict: import.meta.env.DEV, modules: { user: { namespaced: true, ...user }, permission: { namespaced: true, ...permission }, cart: { namespaced: true, ...cart } } })開不開命名空間我的答案是業(yè)務模塊一律開。不開的話所有模塊的 mutation 都注冊在全局兩個模塊都定義了SET_LOADING后注冊的會覆蓋前一個這種 bug 隱蔽性極強。開了之后方法名變成user/SET_LOADING雖然寫起來長一點但邊界清晰。全局的通用狀態(tài)比如 app 級別的主題、語言可以單開一個不開命名空間的 root 模塊但數量要克制。嵌套模塊的調用鏈路也要理清楚。假設有個setting模塊掛在user下面那么在setting的 action 里調用兄弟模塊路徑要寫成dispatch(cart/addItem, item, { root: true })。這個 root 參數指的是“從根開始找”不管你現(xiàn)在在哪一層。記不住的話就記一句只要跨出當前模塊就帶 root: true。3. 從零搭一個能落地的 Store 結構3.1 目錄設計和模塊拆分原則先看目錄這是我用了幾年、覺得最不容易亂的一種src/ ├── store/ │ ├── index.js // 入口注冊模塊和插件 │ ├── plugins/ │ │ └── persist.js // 持久化插件 │ ├── modules/ │ │ ├── user.js // 用戶信息、登錄態(tài) │ │ ├── permission.js // 路由權限、菜單 │ │ └── cart.js // 業(yè)務模塊示例 │ └── helpers.js // 通用工具比如生成 mutation types拆分粒度怎么定我的一般原則是一個模塊對應一個業(yè)務域而不是一個頁面。比如訂單列表和訂單詳情都屬于 order 模塊不要拆成兩個。反過來用戶和權限雖然是相關的但職責不同用戶管“我是誰”權限管“我能看什么”拆開更好維護。模塊內部的結構我習慣按state → getters → mutations → actions → 導出的順序寫和 Vuex 的執(zhí)行鏈路一致讀代碼的人從上往下看正好是數據流向。文件末尾統(tǒng)一導出export default { namespaced: true, state, getters, mutations, actions }有一點要注意如果模塊之間有數據依賴不要在模塊文件里直接import另一個模塊的 state那樣會造成循環(huán)依賴。正確方式是通過rootState讀取或者用dispatch讓對方的 action 來處理。3.2 完整實現(xiàn)一個購物車模塊光說概念沒意思直接上一個能跑的。假設我們要做一個購物車需求是加商品、改數量、刪除、算總價、選中狀態(tài)管理。// store/modules/cart.js const state () ({ items: [], // { id, name, price, count, checked } submitting: false }) const getters { totalCount: state state.items.reduce((sum, i) sum i.count, 0), checkedItems: state state.items.filter(i i.checked), totalPrice: (state, getters) { // 金額用分做單位避免浮點誤差最后再除以 100 const cents getters.checkedItems.reduce((sum, i) sum i.price * 100 * i.count, 0) return cents / 100 }, isAllChecked: state state.items.length 0 state.items.every(i i.checked) } const mutations { ADD_ITEM(state, product) { const exist state.items.find(i i.id product.id) if (exist) { exist.count 1 } else { state.items.push({ ...product, count: 1, checked: true }) } }, UPDATE_COUNT(state, { id, count }) { const item state.items.find(i i.id id) if (item) { item.count Math.max(1, Math.min(99, count)) } }, TOGGLE_CHECK(state, id) { const item state.items.find(i i.id id) if (item) item.checked !item.checked }, TOGGLE_ALL(state, checked) { state.items.forEach(i { i.checked checked }) }, REMOVE_ITEM(state, id) { state.items state.items.filter(i i.id ! id) }, SET_SUBMITTING(state, flag) { state.submitting flag }, CLEAR(state) { state.items [] } } const actions { async checkout({ commit, state, rootState }) { if (!state.items.length) return { ok: false, msg: 購物車是空的 } const payload state.items .filter(i i.checked) .map(i ({ productId: i.id, count: i.count })) commit(SET_SUBMITTING, true) try { const res await api.submitOrder({ items: payload, userId: rootState.user.profile?.id }) commit(REMOVE_ITEM_BATCH, res.data.removedIds) return { ok: true, orderId: res.data.orderId } } catch (e) { return { ok: false, msg: e.message } } finally { commit(SET_SUBMITTING, false) } } } export default { namespaced: true, state, getters, mutations, actions }這里有幾個我自己踩過坑之后固定下來的寫法。金額全部用“分”來算最后展示時再轉回元0.1 0.2那種經典浮點問題在電商場景真的會出事。數量做了Math.max(1, Math.min(99, count))的鉗制防止用戶在輸入框里手打負號或者超大批量。checkout的返回值統(tǒng)一成{ ok, msg }結構組件層不用 try-catch直接看ok就行。另外REMOVE_ITEM_BATCH我在 mutations 里沒寫實際項目中應該補上避免循環(huán)提交單條刪除。這類細節(jié)在真實業(yè)務里會因為批量操作導致幾十次 commitdevtools 面板直接被刷屏。3.3 組件里怎么調用四種方式對比Vuex 提供的調用方式有好幾種很多人只會mapState遇到方法就不知道咋辦了。列個表對照著記場景選項式寫法組合式寫法setup讀 statecomputed(() this.$store.state.user.profile)const profile computed(() store.state.user.profile)讀 getterthis.$store.getters[user/isLogin]computed(() store.getters[user/isLogin])觸發(fā) mutationthis.$store.commit(user/SET_TOKEN, t)store.commit(user/SET_TOKEN, t)觸發(fā) actionawait this.$store.dispatch(user/login, f)await store.dispatch(user/login, f)批量映射...mapState(user, [profile])storeToRefs(store.state.user)配合解構組合式 API 里推薦用useStore加storeToRefsimport { computed } from vue import { useStore } from vuex import { storeToRefs } from pinia // 注意Vuex 沒有官方 storeToRefs這里用 toRefs 替代 export default { setup() { const store useStore() // 直接解構會丟失響應式必須轉成 ref const { profile, token } toRefs(store.state.user) const isLogin computed(() store.getters[user/isLogin]) function handleAdd(product) { store.commit(cart/ADD_ITEM, product) } return { profile, token, isLogin, handleAdd } } }補充一句上面代碼里storeToRefs是 Pinia 的 APIVuex 項目要用 Vue 的toRefs配合store.state.模塊名。這個區(qū)別我見過不止一個人寫混。toRefs只能處理普通響應式對象store.state本身就是響應式的所以能用但store.getters不行因為 getters 是每次訪問時動態(tài)計算的得用computed包一層。選項式 API 里用輔助函數會簡潔很多import { mapState, mapGetters, mapActions } from vuex export default { computed: { ...mapState(cart, [items, submitting]), ...mapGetters(cart, [totalPrice, isAllChecked]), // 自己再算的派生值 isEmpty() { return this.items.length 0 } }, methods: { ...mapActions(cart, [checkout]), async onSubmit() { const res await this.checkout() if (res.ok) { // 跳轉邏輯 } } } }有個小坑要提醒mapState映射出來的名字如果和組件data里的字段重名Vue 會告警而且行為不確定。命名的時候盡量錯開或者在映射時用對象形式重命名...mapState(cart, { cartItems: items })。3.4 嚴格模式、持久化插件和 devtools 配置嚴格模式我強烈建議只在開發(fā)環(huán)境開const store createStore({ strict: import.meta.env.DEV, modules: { ... } })嚴格模式下任何不經過 mutation 的 state 修改都會拋錯[vuex] do not mutate vuex store state outside mutation handlers。這個檢查很耗性能因為它需要深度監(jiān)聽整棵 state 樹。生產環(huán)境開嚴格模式在大型應用里能明顯感覺到卡頓。用 Vite 的話import.meta.env.DEV就是現(xiàn)成的webpack 環(huán)境用process.env.NODE_ENV ! production。持久化這塊Vuex 本身不提供社區(qū)有插件但也都不太維護了我一般手寫一個三十行的插件// store/plugins/persist.js const KEY APP_STORE_V1 export default function createPersistPlugin(paths []) { return store { // 恢復 const raw localStorage.getItem(KEY) if (raw) { try { const saved JSON.parse(raw) paths.forEach(path { const [module, field] path.split(/) const target module ? store.state[module] : store.state if (saved[path] ! undefined) { target[field] saved[path] } }) } catch (e) { localStorage.removeItem(KEY) } } // 保存做節(jié)流避免頻繁寫入 let timer null store.subscribe((mutation, state) { clearTimeout(timer) timer setTimeout(() { const data {} paths.forEach(path { const [module, field] path.split(/) const target module ? state[module] : state data[path] target?.[field] }) localStorage.setItem(KEY, JSON.stringify(data)) }, 300) }) } }用它的時候只白名單需要的字段createStore({ plugins: [createPersistPlugin([user/token, cart/items])] })為什么只白名單而不是全量存因為submitting、loading這類瞬時狀態(tài)被持久化下來刷新頁面后按鈕會一直處于 loading 狀態(tài)用戶以為卡死了。我見過一個項目把整個 store 都存了 localStorage結果用戶重新打開頁面上次沒提交完的表單數據混著新數據出現(xiàn)問題反饋了一堆。4. 高頻踩坑與排查實錄4.1 報錯信息對照表先會看再看懂Vuex 的報錯信息其實寫得挺清楚只是新手不知道往哪查。整理一張表遇到問題先對號入座報錯內容大概率原因處理方式[vuex] unknown mutation type: xxx模塊沒開 namespaced或漏寫模塊前綴檢查模塊配置commit 時補上模塊名/[vuex] unknown action type: xxx跨模塊調用漏了{ root: true }dispatch 第三個參數加上 root[vuex] unknown getter: xxxgetters 沒導出或訪問路徑錯確認 export default 里有 gettersdo not mutate vuex store state outside mutation handlers開發(fā)環(huán)境嚴格模式直接改了 state把所有賦值搬進 mutation[vuex] module namespace not found in mapState()模塊名拼錯或模塊還沒注冊檢查 createStore 的 modules 鍵名Cannot read property xxx of undefined模塊 state 寫成了對象但被復用state 改成函數返回數據改了但頁面沒更新直接改數組下標或對象新增屬性用 mutation 里整體替換或Vue.setVue 2這張表我自己貼在工位旁邊貼了兩年新人來的時候直接拍照。說實話Vuex 報錯里 80% 都是“路徑寫錯”或者“沒開命名空間”這兩類剩下 20% 是響應式丟失。4.2 響應式丟失的幾種典型情況Vue 2 時代最經典的問題state.list[0] newItem頁面不更新。原因是Object.defineProperty攔截不到數組下標賦值。Vue 3 換成 Proxy 之后這個問題基本解決了但如果你維護的是 Vue 2 Vuex 3 的項目還是得注意數組按下標賦值用splice或者整體替換數組對象新增屬性用Vue.set(obj, key, val)刪除屬性用Vue.delete(obj, key)Vue 3 里雖然 Proxy 能攔截新增和刪除但還是有兩個容易忽略的點。一是reactive對象被解構之后失去響應式比如const { profile } store.state.user后面profile就是普通對象了怎么改頁面都不動。二是把 state 里的對象直接賦給組件里的變量做雙向綁定v-model一改就直接改了 state繞過 mutation開發(fā)環(huán)境立刻報嚴格模式錯誤。正確的v-model寫法是這樣computed: { keyword: { get() { return this.$store.state.cart.keyword }, set(val) { this.$store.commit(cart/SET_KEYWORD, val) } } }啰嗦是啰嗦但這條鏈路是完整的devtools 能記錄到每一次輸入。如果嫌麻煩就在組件內用本地 ref提交時再一次性寫回 store。4.3 性能問題什么時候 store 成了瓶頸Vuex 的性能問題我遇到過的就那么幾類但每一類都很要命。第一類是大列表全量放進 store。有個項目把五千條訂單數據放在 state 里每次篩選都要經過 getter頁面卡得沒法用。后來改成 store 只存篩選條件列表數據留在組件里通過 action 拿問題立刻解決。記住store 適合存“狀態(tài)”不適合存“數據集合”。第二類是在 getter 里做重計算。比如對列表做排序、格式化日期、算分組小計這些操作如果依賴頻繁變化getter 會被反復觸發(fā)。我的做法是把這類計算移到組件 computed或者在 store 里緩存一份計算結果只在源數據變化時重算。第三類是過度訂閱。mapState把整個模塊的 state 都映射進來其中某個字段高頻變化導致組件整體重新渲染。用computed精確取需要的字段能緩解一部分更好的辦法是把高頻變化的狀態(tài)比如輸入框的值、鼠標坐標留在組件本地不要進 store。還有一種不太容易發(fā)現(xiàn)的devtools 開著跑生產構建。Vuex 的 devtools 集成在開發(fā)模式下才有但如果你不小心在生產包里引入了開發(fā)版本的 Vue性能會差好幾倍。打包配置里確認一下mode和define有沒有問題這個坑我踩過一次找了一周。4.4 老項目遷移與工程化建議如果手上的 Vuex 項目要重構我建議按這個順序推進別一把梭。第一步先把所有this.$store的直接調用收斂成統(tǒng)一的 API 層。寫一個src/store/api.js把常用的讀寫封裝成函數比如useUser()、useCart()。這一步不改邏輯只是加一層殼風險極低。第二步把模塊的 mutation 命名規(guī)范化。原來可能叫setUser、updateUser、changeUser統(tǒng)一成SET_USER。這一步靠grep加人工核對工作量不大但收益明顯后面遷移 Pinia 時一一對應就能改。第三步按模塊遷移。先挑一個依賴最少的模塊比如cart改成 Pinia 的defineStore然后在入口同時注冊兩套。Vuex 和 Pinia 是可以共存的只要別讓同一個業(yè)務狀態(tài)兩邊都存就行。第四步清理。所有模塊遷完之后刪掉 Vuex 依賴把mapState之類的 import 全部替換。這一步用 ESLint 的自定義規(guī)則能掃出一部分剩下的靠編譯報錯兜底。遷移過程中有個細節(jié)值得說Pinia 的storeToRefs和 Vuex 的toRefs行為不完全一樣直接在組件里解構很容易出問題。我當時的做法是先把所有組件里的解構都改成computed遷完之后再按需優(yōu)化。寧可多寫幾行也別在響應式上翻車。5. 幾個真實場景下的套路組合5.1 登錄態(tài)與路由守衛(wèi)的配合登錄態(tài)是最典型的需要 store 的場景但它和路由守衛(wèi)的配合有個時序問題必須處理。守衛(wèi)在頁面渲染前執(zhí)行這時候如果 store 里的用戶信息還沒加載權限判斷就會失敗用戶被誤踢回登錄頁。我的處理方式是token 從 localStorage 同步恢復用戶信息異步加載但守衛(wèi)里做“是否已加載”的判斷沒加載就先觸發(fā) action 并等待。// permission.js router.beforeEach(async (to, from, next) { const store useStore() const token store.state.user.token if (!token) { return to.meta.public ? next() : next({ path: /login, query: { redirect: to.fullPath } }) } if (!store.state.user.permissionLoaded) { try { await store.dispatch(user/fetchProfile) await store.dispatch(permission/loadRoutes) } catch (e) { store.commit(user/RESET) return next(/login) } } if (to.meta.roles !store.getters[user/hasPermission](to.meta.roles)) { return next(/403) } next() })這里的關鍵是permissionLoaded這個標記位。沒有它每次路由跳轉都要重新拉一次用戶信息接口壓力大不說頁面還會閃。有了它第一次加載完之后所有跳轉都是同步判斷體驗就順了。異步路由用router.addRoute動態(tài)注冊注冊完再next({ ...to, replace: true })重新進入一次否則會白屏。5.2 跨模塊協(xié)作別讓模塊之間互相 import項目一大模塊之間必然有協(xié)作。比如下單成功后要清空購物車、刷新訂單列表、更新用戶積分。這三件事分屬三個模塊怎么串起來最差的做法是在order模塊里import cart from ./cart然后直接調。這樣寫會形成循環(huán)依賴打包時可能報錯運行時也可能拿到 undefined。正確做法是通過 action 互相 dispatch// order 模塊的 action async createOrder({ commit, dispatch }, payload) { const res await api.createOrder(payload) commit(ADD_ORDER, res.data) // 跨模塊通知各自處理各自的邏輯 await dispatch(cart/clearChecked, null, { root: true }) await dispatch(user/refreshPoints, null, { root: true }) return res.data }這樣order模塊不需要知道cart內部怎么實現(xiàn)只要知道有這么個 action 就行。耦合度低測試也好寫。如果模塊數量多、協(xié)作關系復雜可以再引入一個“編排層”專門寫跨模塊的 action把業(yè)務流程集中在一處。還有個小技巧跨模塊讀取數據用 getters不要直接讀rootState.xxx.yyy。getters 是一層抽象將來內部結構變了只要 getter 的返回不變調用方就不用改。5.3 表單草稿和列表緩存的取舍后臺系統(tǒng)里最常見的兩個需求表單填一半切走了回來要恢復列表翻到第五頁點進詳情再返回要停在第五頁。表單草稿我的做法是不進 store用sessionStorage加組件內的watch做防抖保存。原因很簡單草稿是頁面級的狀態(tài)多個表單同時編輯時放 store 會互相干擾還要處理各種清理邏輯。sessionStorage 天然按標簽頁隔離關掉就沒了符合直覺。列表緩存反而適合進 store。因為篩選條件、頁碼、排序方式這些是需要跨路由保留的而且詳情頁返回時要用。做法是在list模塊里存一份query對象列表頁onMounted時讀出來發(fā)起請求條件變化時同步更新。要注意的是從菜單重新點進列表時應該重置從詳情返回時應該保留這個區(qū)分靠路由的meta.keepAlive或者判斷from路徑來做。const actions { async loadList({ state, commit }, { reset false } {}) { if (reset) { commit(RESET_QUERY) } const res await api.getList(state.query) commit(SET_LIST, res.data) } }reset參數由調用方決定模塊本身不猜。這種“讓調用方明確表達意圖”的設計比在模塊里寫一堆 if 判斷當前路由要清晰得多。6. 我個人在實際項目里的幾點體會寫到這里Vuex 的主要知識點基本都覆蓋了。最后分享幾個不太適合寫進文檔、但實際干活時確實管用的經驗。第一別怕寫重復代碼。Vuex 的四段式state/getters/mutations/actions看起來很啰嗦但每多寫一行將來排查問題時就少猜一次。我曾經為了省事把 mutation 和 action 合并成一個函數結果 devtools 里全是匿名調用出問題時完全不知道是誰改的。后來老老實實拆開調試效率反而高了。第二給 store 加注釋比加文檔有用。每個模塊文件頂部寫清楚這個模塊管什么、依賴誰、被誰依賴比單獨維護一份文檔靠譜得多。文檔會過期代碼不會。我現(xiàn)在接手新項目第一件事就是看 store 模塊的頂部注釋五分鐘就能摸清業(yè)務脈絡。第三調試時善用 devtools 的 import/export。Vuex 面板可以把當前狀態(tài)導出成 JSON也能導入一份狀態(tài)來復現(xiàn)問題。遇到用戶反饋的詭異 bug讓對方導出一份狀態(tài)文件本地導入后就能完全復現(xiàn)當時的場景比反復溝通效率高太多。這個功能知道的人不多但真的好用。第四測試只測 action 和 getter。state 和 mutation 太簡單測了也是形式主義。真正有價值的是 action 里的業(yè)務流程和 getter 里的計算邏輯這兩塊寫單測覆蓋率能上一個大臺階。測 action 的時候記得 mock 掉commit和dispatch用jest.fn()或者vi.fn()都行斷言調用參數就夠了。最后提一句狀態(tài)管理這塊工具會換但“什么狀態(tài)該放在哪一層、變更走什么路徑、如何保證可追溯”這三個問題不會變。把 Vuex 這套東西吃透換成 Pinia、換成任何別的方案思路都是通用的。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
国产东北女人在线视频| 久久华人网| 亚洲熟女乱色一区二区三区| 人人色97| 成人午夜小视频手机在线看| 超碰一区二区| 亚洲久热| 亚洲免费在线探花| 五月丁香激情四射| 四虎AV无码| 国产视频一区二区免费| 边做饭边操逼逼| 久久亚洲欧美一区二区三区-亚洲国产精品第一区二区 | 国产精品久久久久久久久久久久久久| 97se综合网| 色优久久| 我爱大香蕉| 国产精品久久久久久久AV大片| 天堂性色| 丁香五月婷婷基地| 成人免费在线网站| 97在线免费| 清纯唯美综合亚洲| 天天射影院| 国产一区二区啪啪视频| 免费A片三p视频| 欧差乱伦二三| 五月婷婷hd| 色偷偷2020免费视频播放| 亚洲国产成人7777| 午夜天堂精品久久久久91| 男女激情中文字幕| 五十路六十路七十路熟婆| 色呦呦、国产精品| AV色五月| 天天色香欲综合网| 亚洲欧洲中文日韩女优乱码| 久久久久9999妇女| 超碰成人公开| 18+91网站| 日韩一级片在线看| 国产精品午夜精品| 熟妇亚洲一区二区三区| 亚洲欧洲综合av在线| 98超碰日本| 黄片直播三级黄片两女一男| 欧美日韩传媒| 色偷偷人人玩人人舔人人操人人摸人人爽| 精品超碰国产| 国产在线激情视频| 激情视频一二三| 69精品在线| 国产深夜福利| 91欧洲入口| 人妖欧美一区二区| 91激情综合| 色女网日韩| 九九视频黄色片| 超97在线精品视频| 蜜臀一区二区三区亚洲最新章节在线观看 - 高清蜜臀一区二区三区亚洲全集播放 | 色综合av综合久久| 高精欧美色| 91艹逼精品| 久久精品国产精品亚洲艾通辽熟妇| 人妻精品视频一区二区三区| 人妻丝袜一区二区三区在线| 97天天| 亚洲日韩乱码中文无码蜜桃臀网站| 97色97干| 欧美在线第五页| 播播亚洲小说亚洲| 国产v片在线免费观看| 在线观看AV片| 美女国产一区二区久久| 操操逼操操逼操操逼逼| 综合在线导航一区| 日韩探花精品在线视频| 狠狠操狠狠| 婷婷五月天网| 开心激情站| 天天插天天插| 美国人人操人人操| V A在线| 电家庭影院午夜69久久夜色精品国产69乱| 精品妇操一区二区三区| 亚洲色婷婷久久久综合日本| 国模限制级电影| 精品久久无码午夜福利| 欧美性性性| 国产精品天美传媒| 蜜臀99久| 果冻传媒A片麻豆熟妇人妻| 欧美一二级| 亚洲性爱乱操x| 超碰69| 国产女人成人精品视频| 91狠| 天天色综合影视网| 国产黄色在线播放观看| 精品国产久热在线观看| 欧美日韩精品国产91| 熟妇一区,二区,三区。| 国产精品美女在线一区| 67194无码不卡| 欧美狠狠狠| 性影在线视频| 精品中文一区二区| 性爱免费视频成人| 区一在线观看| 欧美国产精品久久九九| 欧美日不卡| 蜜桃狠狠色伊人亚洲综合 | 麻豆天美制片厂网站视频| 日日躁夜夜躁狠狠躁超爽| se吧提供国产乱老熟视频胖女人| 日本有码久久| 男女猛烈无遮掩视频免费软件| 99久久com免费视频′| 美欧色综合| 自拍偷拍2025在线观看| 啊啊嗯嗯好爽| 亚洲男人的天堂AV| 日韩一级成人毛片免费观看| 天天综合网合集91| 无码又爽又硬又激情免费视频| 欧美BT 亚洲色图| 久99久视频| 久久久人妻| 任我爽视频在线观看| 日B操| 丰满精品人妻少妇久久字幕| 日本一级二级三级网站| 91无遮挡| 夜夜国自区| 五月天激情网图片| 日韩亚洲Av人人夜夜澡人人爽| 欧美 亚洲 另类 综合| 欧美一区二区三区日韩| 国产福利电影| 清纯唯美综合亚洲| 亚洲操操| 亚洲91av| 亚洲AV无码秘 蜜桃臀国精产品| 欧美第一页| 啪一啪免费视频| 狠狠操使劲操| 夜夜爽爽夜夜精品视频| 亚州色图第三区| 日本大香蕉| 激情AV| 91人妻素女| 亚洲三级。日韩三级| 很很很很操| 9久久精品| 久久久四区| 91麻豆天美国产| 亚洲第一页欧美| 国产精品盗摄 偷窥盗摄| 精品一区二区三区四区外站| 白丝1区2区3区| 一级黄色影片| 一牛影视久久久一区二区三区| 欧美黄片视频在线观看免费 | 安徽熟妇视频| 精品v1区| 福利偷拍视频-中文字幕2019国语完整视频大全-S91AV | 欧美少妇性乱| 国产噜噜噜噜噜久久久久久久久| 91丨国产丨白浆| 日韩人妻精品久久久久| 五月天激情小说网| 色性荡荡荡荡视频| 成人日本精品九区| 国产精品3| 舔舔啊| 一区二区三区四区理论片| 骚日日av| 亚洲日韩美女丝袜美腿人妻视频| 最新日本中文字幕| 伊人色综合网电影| 九九久久久久久爱| 亚洲黄a三级三级三级看三级| 欧美一二在线| AV高清一区| 97bbn| 禁十八久久| 国产不卡精品91| 噜噜噜久久亚洲精品色情| 婷婷15月天青娱乐| 麻豆视频一区二区| 激情综合网五月婷婷五月天| 九九av| 久久久久久久78| 久久激情视频| 韩国手机不卡无码三级视频| 另类天堂| 欧美第二页午夜| 精品人妻免费观看| 九九热免费国产视频婷婷伊人五月 | 日本一区不卡| 黄色视频特级毛片| 人妻熟女一区二区三区在线| 欧美色综合| 无码又爽又硬又激情免费视频| 制服中出中文人人精品| 亚洲天堂五月天国产| 看看日B真人视频| 五毛骚逼极品美女怕怕| 乱伦熟妇一区二区| 香蕉综合网| 亚洲高清在线se| 精品蜜乳AV免费观看| 人妻少妇蜜桃视频欧美一区| 亚洲无码 国产无码| 国产精品久久久亚洲一区| 97在线观看免费| 性生活性生大爱77AV国产 | 成人无码专区精品视频| AV天堂丝袜| 校园春色亚洲欧洲| 青娱乐91| 天天影视色香色欲| 亚州性色| 人妻丝袜肏逼| 91久| 九九九九九九九| 久久日韩肥臀| 亚洲精品九九九| 久久精品91| 干干干天天| 综合在线导航一区| 久久激情视频| 综合网亚洲| 蜜桃视频一区二区三区在线观看| 自拍偷拍亚洲熟女妇人精品| 欧美综合中文| 综合亚洲情色| 黄污污污污| 日韩福利综合一区| 亚洲精品国产拍免费91在线| 中文字幕一区二区三区人妻少妇在线| 美女网站91| 日本一区二区电影网站| 超碰97资源大奶| 亚洲第一黄色av网站| 99视频内射三四| 免费看黄片现成| 亚洲经典啪啪| 在线一区| 午夜电影在线观看无码专区| 黄色片大香蕉| 热99这里有精品综合久久| 欧美综色欧| 97国产超湿| 久久九九99| 日人妻视频91| 亚洲蜜乳av| 日日干夜夜欢| 久操影视| 无卡一区=区| 中文字幕文字幕无码一区二区三区电影99| 久久99国产综合精品女同| 丁香五月激情啪啪| 国产免费久久久久| SS久久| 亚洲国产欧美中文永久| 天堂亚洲精品| 91中文精品日韩欧美在线| 手机在线播放国产福利| 亚欧精品久久久久久久久久久| 欧美成人四级在线播放| av绯色| 国产 日韩 欧美 中文 另类,国产 欧美 另类 制服 变态,高清 日韩 欧美 中文,高 | 亚洲色 国产 欧美 日韩| 一牛影视成人片免费| 久射吧| 国产精品天干天干综合网麻豆| 国产隔壁老王影院在线| 国产精品一区二区久久精品| 女优免费一区二区永久| 黄色小视频日本txt| 在线岛| 无码黑人精品一区二区三区三| 性videos欧美熟妇hdx| 中文久久| 一级久久性爱视频| 男人天堂2019亚洲| 啊啊啊啊啊,啊啊啊啊好舒服,操我舒服啊啊啊| AV天堂男人的天堂| 噜噜噜噜天天狠狠| 国产强奸无码乱伦| 国产精品久久久久久亚洲色欲| 强奸乱伦AV网址| 九九伊人网| 极品久久久久久久久久久久久久| 91国产丝袜白虎| 少妇高潮流水av免费| 黄色av一区二区在线| 日韩情色AV| 91n处女在线观看| 26uuu欧美日韩| 婷婷色婷婷| 久久精品免视看国产成人﹣蜜臀av一区. 久久精品免视看国产成人,蜜臀av一区 | 日韩中文字幕国产| 亚洲图片偷拍欧美| 久久日韩肥臀| 成·人免费午夜在线观看| 日韩无码操逼片| 久久精品人体| 欧美中文字幕精品人妻| 日日狠狠久久偷偷色综合免费| 一级免费精品| 免费A V在线| 夜夜免费视频| 丁香婷婷啪啪| 亚洲欲色| 日韩影片中文字幕一区二区三区| 黄页av| 欧美成人黄网色网站| 殴美色网| 91色碰| 强奸乱伦 亚洲一区| 久久久艹艹艹| 国产高清自拍视频| 久久国模av| 精品人体无圣光凹凸| 亚州中文字幕超碰97| 国产精品熟女九色九色蜜臀| 五十路人妻在线| 欧美黄色片AAAAA| 国产精品欧美在线观看| 色好看av| 国产小u女在线观看| 在线午夜成人无码视频| 久久久96精品| 国产suv精品一区二区四| 性爱Av免费| 青青久久久| 96免费视频在线| 粉嫩av在线一区二区| 亚洲日韩电影| 久操电影网| 日韩人妻少妇 一区二区三区| 精品国产Av无码久久久亚洲| 夜夜欧美| 精品九九淫乱男| 亚洲日韩精品久久久久一区壹牛 | 在线看的av| 国产精彩女在线观看视频| 长长久久88视频| 一牛影视成人片免费| 色婷婷淫色网| 99九九精品| 中文字幕,人妻,日韩| 啊啊啊啊操死我| 亚欧操逼片在线观看| 国产精品青青草| 婷婷五月天色色| 黄片无码在线制服| A片 AV一级在线播放观看免费| a片自拍直播视频| 人妻熟女一区二区三区视频| AV在线资源| 亚欧韩av| 再深点灬舒服灬太大了好硬好爽| 大香蕉一线视频| 99视频这有这里有精品| 国产中文字幕在线点播| 亚洲啪AⅤ永久无码| 国产成久久综合片| 操逼逼一区视频| 大香蕉乱级| 国产日韩区| 免费视频在线一区二区不卡| 亚洲熟女精品| 亚洲永久AV无码精品秋霞| 丁香五月大香蕉| 91精品人妻一区二区-全集完整版免费正片国语-B02AV | 欧美综合站| 六月丁香啪啪| 国产视频三区四区| 亚洲吊色| 啊嗯嗯啊好大好爽| 综合久久9| 中文字幕精品一区二| 日本十八禁免费看污网站| 又大又长又粗又爽又黄| 99亚洲天堂| 久久精品免视看国产成人﹣蜜臀av一区. 久久精品免视看国产成人,蜜臀av一区 | 亚洲成人妻日韩在线| 天天干18禁| 秋霞Av理论一级在线| 大色综合网| 国产av青草| 青青草中出视频| 97Ai亚洲| 五月天精品| 中文字幕-区二区三区四区视频中国| 日日夜夜噜| 亚洲欧美综合网| 国产又粗又大硬免费色网视频| 久久夜夜| 青娱乐日韩无码| 天天日天天舔东京热| 欧美亚洲天天| 中文字幕 人妻不满 在线视频| 操逼精品视频| 亚洲欧洲无码bt精品合集| 97电影院超碰| 欧美一区二区男人天堂| 99国产精品视频尤物| 亚洲 欧美 91| 久久精品女同亚洲女同13| 欧美天天| 麻豆久久久久久久久丝袜| 日日干夜夜骑| 三级色影综合网| 青青草亚洲一区| 日骚逼视频| 簧片免费看视频| 啊灬快c我灬啊灬用力灬啊灬-国产精品性做久久久久久-成人AV | 蜜乳AV一区| 国产欧美第五页| 亚洲一区二区 麻豆传媒| 99re28在线观看| 激情干在线| 欧美97日韩精品| 亚洲国产综合视频| 国产欧美日韩女同性恋ww喷水精品| 激情啪啪视频| 伊人久久大香线蕉无码| SS久久| 熟女乱3伦999| 精品国产乱码久久久兰草影视| 亚洲无线观看久久| 97干天天| 岛国激情视频软件| 大香伊人在线一区| 亚洲国产成人精品999| 亚洲一二三四区机械| 亚洲激情片| 黄色成品网站| 国产精品福利视频| 久久精品色欧美aⅴ一区二区| 欧美另类综合久久| 97色色婷婷| 久久久96| 大奶尤物鲍汁淫荡欧美视频粉嫩夜夜骚 | 婷婷五月成人| 嗯嗯啊啊好爽| 99黄页网站| 日本网色| av网站免费线看| 老熟妇一区二区三区啪啪| 飘花国产午夜精品不卡| 激情人妻另类| 99爱爱| 91丨国产丨白浆秘 洗澡动漫| 欧美日韩黄片精品在线| 淫乱图区 | 久久久久久久9| www.高清无码诱惑一区.com| 日韩精品一区二区三区色欲| a'v在线资源| 久久久久9| 日日操天天操| 人人干人人搞人人摸| 91综合熟女| 欧美暴力猛交| 久久人妻四季| 日韩中文字幕二区| 强奸乱伦资源| 中文欧丝袜诱惑| 中文字幕交换人妻| 大香蕉日韩| 白丝AV网站| A片三级无码| 男啪女色黄无遮挡免费观看| 噜噜噜噜久久久精品免费| 欧美激情 一区| 综合av社区| 日少妇视频| 99热在线播放| 欧美九九九| 亚洲中文字幕乱码无码一区二区 | 夜夜夜夜夜夜夜夜夜狠狠狠狠狠狠狠| 色哟哟 日韩精品| 亚洲精品天堂久久A∨51成人漫| 精品国产AV一区天美传媒| 日本久久久久久久久| 熟女欧美日韩综合婷婷| 亚洲欧洲日韩国产自在线| 日韩黄色一区二区三区| jizz啪啪| 精品国产乱码久久| 国内毛片欧美香蕉精品| 中文字幕一区二区三区高清| 国产精品色片一区二区| 国产精品久久久三级无码| 免费一级a毛片久久久久久鸭绿欲| 欧美综合另类| 国产狂喷潮在线精品| 成人性爱av| 97福利视频| 欧美日韩一区二区三区四区蜜桃| 国产强奸超碰AV| 黑丝少妇| 国产乱不卡| 亚洲性网| 欧美人妻精品一区二区| 女人爽到高潮潮喷18禁网站 | 伊人99热| 亚洲天天精品| 人妻中文字幕精品无码| 超碰综合97在线| 91九九九逼| 色天堂综合| 国内精品嫩模A∨私拍小视频| 波多野42部无码喷潮在线观看| 又大又长又爽| 99在线无码精品秘 入口黑人| 精品久久視頻在线| 精品一区二区三区四区外站| 秋霞福利网| 亚洲图片小说欧洲| 人、人、摸,人、人、草| 夜夜狼人妻| 2017天天插| 国产精品香蕉热久久新品| 欧美日韩操操操| 亚洲 欧美 中文 日韩超碰| 免费久久9999| 欧美一级A一级a爱片久久| 婷婷五月天丁香花| 91日韩网站| 欧美爆乳精品一区二区| 99www.bibizy香蕉资源国产一区二区三区高清 | 超碰97起碰| 精品熟妇视频一区二区| av在线一区二区三区| 欧美久久婷婷| 20cm女自慰在线日韩欧美| 久久婷婷六月综合| 欧美色另类| 精品国产精品一区二区| 久9爱经典视频| 夜夜爽夜夜爽| 欧美 综合| 欧美区亚洲区偷拍区| CCYY草草影院地址入口| 新97国产超碰| 亚洲欧美日韩夜夜| A男人的天堂| 爽极品影院| 欧美骚少妇| 激情综合五| 嗯嗯啊啊操我| 丁香婷婷激情五月天无毒不卡 | 死我十八禁| 久精品无码av一区二免费国产在线观看| 91红杏| 三级激情网站| 天天色怡春院| 欧美一级色| 超碰免费97| 97日视频| 天堂九九九九九九九九九| 日韩精品99999| 欧美白嫩在线放| 91肉片| 999九九精品| 熟女在线视频| 狠狠色婷婷777| 国产免a费看黄片在线| 午夜操操操| 91日产欧美| 97中文天堂| 中文字幕日本久久| 国产黄色小视频网站| 97色冈| 五月天玖玖资源站| 芊芊操逼视频无码| 久久精品国产亚洲妲己影视| 香蕉精品二区二区| 一级性爱啪啪视频| 欧美亚男人的天堂| 91 丝袜在线播放| 欧美色蜜桃97| 蜜臀va69| 91精品网站| 蜜臀久久在线视频| 小草三级久久观看| 久久久久久9| 欧美色另类| 美女好片色日本| 极品少妇久久久| 欧美综合中文| 超碰人妻久久| 欧美巨大性舒爽顶到了| 日韩超碰97| 欧美黄色手机在线观看| 日韩操p| 丰满人妻一区二区三区四区| 国产欧美日韩一区二区三区| 草莓精品视频| 99无码精品| 欧美狠狠弄| 日韩不卡网操逼中文字幕日韩| 色网综合网| 香蕉精品二区二区| 日韩欧洲操屄视频| 国产精品无码在线| 婷婷香蕉欧美在线一区二区三区 | 久久婷婷苹果| 97久久网| 久久久久国产精品片区无码直播| 无码伊人久久大杳蕉中文无码| 69超碰综合| 97在线资源| 午夜国产综合视频在线观看| 亚洲熟妇综合久久久久久| 欧美精品欧美精品系列| 成人草草视频| 日日操免费视频| 伊人91| 老熟女中文字幕高清| 91欧洲国产成人久久精品网站| 99re欧美| 99性爱在线观看| 免费综合亚洲中文| www.五月天| 色臀aV| 亚洲熟女乱色一区二区三区| 色情五月丁香| 久久婷婷亚洲欧| 中文?日韩?免费?精品| 婷色五月| 婷婷探花久久精品一区| 国产AAAAAABBBBB| 亚洲免费成人精品电影| 嗯嗯啊啊用力视频免费| 久热最新在线杭州| 91九九| 久久久久久久久9| 婷婷影院入口| 97就爱干| 免费亚洲黄色视频在线观看 | 素颜老阿姨乱情色| 中文字幕一区二区三区高清| 欧美第38页| 人妻偷拍一区二区三区| xxx亚洲午夜天堂| 欧美日韩资源| 欧美v日韩欧亚洲电影天堂色诱,国产传媒| 丝袜狠狠草尤物 91| 亚洲一曲日韩精品| 夜夜操91744565| 国产一区二区a毛片| 大香蕉日亚洲日本亚大 | 99碰碰| 久久骚| 九九碰九九爱97超碰| 国产精品伦理| 亚洲精品一区二区三区新线路| 天天躁日日躁成人字幕aⅴ| 男人的天堂2019AV| 伊人网免费视频| 欧美情色男人的天堂| 97欧美性爱| 加勒比综合| 久久天天躁日日躁狠狠躁 | 亚洲,日韩,欧美,成人播放| 97视频620| 久久亚洲AV成人精品无码| 五月天亚洲网| 青娱乐 成人娱乐在线| 手机在线播放国产福利| 99久久99九九99九九九| 狠狠图片青青草| 熟女乱伦二区| 男人a天堂手机在线版| 久久久久99999| 一区二区亚州激情久婷婷欧美| 五月丁香影视| 多毛小伙内射老太婆| 欧美色图 色综合图| 丝袜狠狠草尤物 91| www.97在线| 欧美高清18A片| 国产夜夜艹| 10000部十八禁看电影| 亚州色阁| 天天综合站| 欧美性夜| 成人七区| 日本狂喷奶水在线播放212| 日韩欧美丝袜诱惑| 五月天精品| 午夜国产成人精品视频| 久久精品店| 国模限制级电影| 天天日美女的B| 日韩视频中文字幕| 欧亚性爱视频免费看| 中文字幕人妻色偷偷久久皮| 东京热大香焦| 人人操人人舒服| 亚洲av强奸乱伦| 精品精品精品| 五月天丁香网| 日日日啊啊啊| 岛国激情视频软件| 国产一区二区成人av在线播放| 日天天九九天堂666| 日韩精品影视| 婷婷激情四射| 亚洲精品三区在线观看| AV不卡在线| 人妻天堂综合网| 97精品97| 欧美黑人极品高潮喷吹熟女黑人性暴力日韩在线欧美极品一区二区 | 一区二区首页| 青青草黑寡妇男人天堂| 中国AAAAAA黄色片| 97操| 日韩欧美午夜视频在线| 丁香九月婷婷| 九九九精品色乱九九九| 亚洲天堂久久久久久粉红视频| 欧美日韩国产另类综合| 污啪啪啪视频| 神马久久久久眼| 美女骚尻视频| 四虎国产精品永久入口| 日本一本一区二区三区四区五区欧美日韩中文字幕 | A级片日韩欧美国产欧美视频精选观看 | 99亚洲精品| 亚洲国产日韩精品久久久| 国产成年精品高清在线观看91| 狠狠综合网| 96精品久久久| 无色无码| 公司1区2区3区精产精| 最好看的中文字幕在线2018| 四虎884a| 国产Aα| 激情视频一二三| 草莓精品视频在线免费观看| 欧美色图私拍91| 波多野结衣之双飞调教在线播放| 中文字幕高清20页视频| 欧美第五页| 久久久国产成人一区二区三区在线| 啊啊啊啊啊啊啊啊要喷了| 家庭乱伦性爱av| 91女优在线观看| 国产激情av女片自拍| 天天综合站| 亚洲AV免费在线| 亚洲开心网| 色综合潮| 黄在线| 丰满少妇精品一区二区| 五月丁香综合激情| 人妻一区二区三区四区视频| 欧美视频第二页| 日韩av性爱在线播放| 免费观看网黄| 久久熟女精品不卡一区| 亚洲色图超碰在线| 精品日韩中文在线| 国内毛片四区| 大香蕉欧美伊| 日本三级中国三级99人妇网站| 中文字幕蜜乳av| 亚洲综合色在线| 裸体女人草逼视频播放一区,二区,三区,四区,五区 | 日韩乱码Av| 丰满人妻一区二区三区四区| 欧美日韩中文字幕人妻| 操淫穴亚洲五月丁香| 亚洲精品丝袜-不卡成人免费……| www.99色| 亚洲婷婷丁香在线| 亚洲欧美校园| 人妻天天爽| 男人在线天堂| 亚洲色图 91| 狠狠2050在线观看| 国产精品熟女AV中文字幕在线播放| 国产尤物AV尤物在线观看不卡| 亚洲福利影院一区久久| 啪啪啪男女亚洲中文字幕99| 国产十八禁视频| 狠狠躁AV| 曰韩精品九九无码| 亚洲天堂 视频你懂的| 国产高清26uuu| 日韩黄片影院| 国内毛片热久久思思热| 亚洲综合97| 男人的天堂2019| 蜜臀久久99精品久久久久| 中文字幕青青草| 天美传媒麻豆一区二区三区国产精| 亚洲成人妻日韩在线| 今日头条成人一区二区三区四虎精品| 91ise欧美| 麻豆精品久久久久久久| 色综合美国| 亚洲国产综合久久久性感熟妇| 色欧美天天| 日韩熟女精品无码专区一区二区| 亚洲欧美九九| 东北女人的毛片| 欧美亚洲美少妇一区二区| 中文字幕十五区| 中文字幕午夜精品久久久| 精品人妻高清麻豆av| 91性感在线| 乱性AV| 免费啪啪一级视频| 九九热精品视频在线观看| 人人插人人搞人人操| 国产极品一区二区三区三州| 97国产成人精品免费视频| 婷婷五月丁香五月| 天天插夜夜爽| 天堂性色| 亚洲最大成人a毛毛片| 色婷婷五月天| 欧美亚洲日韩16色| 久久久青青草| 久久毛卡| 欧美日本久久精品一区| 国产少妇内射| 色翁荡息又大又硬又粗又爽| 日本网色| 中文字幕久久亚州无码| 日本阿v天堂在线观看| 怡红院一区二区熟女人妻| 黄色小说亚洲| 国产丝袜啪啪| 91香蕉视频在线观看免费| 综合久久中文字幕综合日韩精品| 精品久久99| 好爽免费视频,| 情趣丝袜无码操逼视频| 97超碰碰碰| 亚洲第二页| 国产精品色片一区二区| 亚洲欧美大| 一摸二插三插| hd成人一区二区在线| 97视频620| 亚洲无码 国产无码| 粉嫩国产精品久久粉嫩| 九九热av| 草草影院在线视频| 91国模| 热久久这里只有精品| 欧洲亚洲天堂精品| 91 丝袜在线播放| 9久综合网| 久久大黄片| 色91综合网| 老外又粗又长一晚做五次| 欧美日韩222| 人妻无一区二区三区| av午夜玫瑰| 欧美老妇曰批的视频| 欧美在线色| 国产热RE99久久6国产精品首| 操老熟女AV| 欧美中出1| 91亚州| 人妻免费观看| 久久婷婷精品| 国产精品国产亚洲区艳妇糸列| 亚洲蜜臀懂色| 欧美亚洲日本激情在线| 91第一页| 狠狠色一区二区中文字幕| 日本性爱少妇| 国产强奸乱伦第1页| 香蕉色网| 国产视频三区四区| 人妻人人做人人澡人人爽欧美一区| 国产深喉| 牛牛久久国产精品视频一二三| 黑人黄片在线免费观看| 亚洲欧美国产中文视频| 国产日产欧产美韩系列麻豆免费| 91国产精品在线看| 日韩久久.一级黄色片| 精品福利| 国产激情在线| 超碰97在线色男人??| 亚洲伊人久久精品狠狠在线| 美女被艹尤物视频| 久久 国产 无码| 91丝袜| 国产91 丝袜在线播放| 97超碰精品成| 亚洲欧美一区二区不卡视频播放 | 能直接看AV的网站| 久久天天艹| 亚洲精品国产精品成人| 97欧美综合| 韩日欧亚a级| 精品国产乱码久久久久久免费| 欧美色一二三| 久久伊人青青草| 99啪啪| 色婷婷蜜臀av| 男人干美女| 偷拍亚洲高清图片| 九九久久久九九| 日韩紧密久久| 色婷婷成人综合| 99www.bibizy香蕉资源国产一区二区三区高清| 五月丁香| 久热69九色熟妇97| 亚洲。日韩。欧美| 亚洲精品国产AV天美传媒| 91jk色拍| 国产一区二区在线播放,久久亚洲精品中文字幕第一区,亚洲精品在线中文字幕视频 | 97se亚洲综合自| 91亚洲欧洲| 另类图片欧美激情综合| 国产精品盗摄 偷窥盗摄| 日本三级A片网站com| www.91理论| 久久婷五月天| 欧美少妇第一页| 久九9精品| 999热日韩精品| 91在线视频国产网站| 免费1级a做爰片观看| 亚洲日韩国产欧美综合v| 丁香六月婷婷| 加勒比日本在线| 中文字幕午夜精品久久久| 92久久| 国产女同视频在线播放| 国内毛片免费h片在线| 亚洲欧美校园另类春色| 青青草玖玖爱| 欧美高清色| 操逼无码一区| 蜜臀av中字字幕网站| 97在线观看免费| 激情 欧美 亚洲 小说| 五月天婷婷色| 日韩中文9| 欧美日韩啪啪电影| A V少妇特黄三级| 午夜九九| 成年女人黄网站| 亚洲最大的黄色电影网站。| 日韩色图 一区二区| 国产极品999| 亚洲天天更新| 亚洲熟女av日韩熟女| 东北老女人的激情视频| 91精片| 人妻天天夜夜爽一区二区| 免费97视频| 国产精品久久久久中文字幕| 精品十三区| 免费无码婬片AAAA片直播色戒| 小少妇| www.男人的天堂| 六月丁香五月婷婷| 少妇天堂| 91精品大奶人妻| 99超碰网| 国产精品交换一区二区| 夜色91| 九久久九精品视频| 伊人一区二区在线播放| 69av一区二区三区| 麻豆一区二区三区精品| 美國A片| 九九九999久久久网站| 亚洲五月天激情| 欧美999| 东京热不卡视频| 人人透人人操| 97干在线视频| 白丝少妇一区二区| hd成人一区二区在线| 夜夜欧美 | 欧美姓爱综合网| 蜜臀人妻少妇久久在线观看| 国产一进一出视频网站| 亚洲天堂一区二区| 天天肏美女| 精品人妻一区| 五十路成人在线视频二区三区| 欧美极度丰满熟妇hd| 久久夜夜| 1204人成网站色www| 性色avv| 日韩性爱播放| 看免费的黄片| 人妻91少妇| 久久视频,这里只有精品| 天堂av2019| 中文字幕一区日韩精| 大香蕉久| 免费a级毛片av无码久久精品中文字幕| 无毛精品| 传媒免费一区二区三区| 91亚·色| 丁香五月影院| 亚洲中文日韩精品| 午夜一区二区三区国产| 69视频入口| 久久人妻| 国产400孕妇孕交群| 天天色欧美| 大香蕉草草| 欧美96交| 亚洲天堂少妇| 超碰精品人妻狠狠干| 另类专区加勒比| 99日免费视频中文字幕| 日本中文字幕一区| 丝袜美腿射精91| 蜜臀av网址| 超碰97资源网亚洲| 啊啊啊操死我了| 久久99干一本高清| 91亚洲最新在线| 东京热毛片177b2viP| 无码一区免费在线不卡| 日本国产亚洲一区在线观看| 日韩一级久久毛片| 豆花视频操逼网址| 国产av强奸美女| 国岛片视频| 狠狠综合| 爱爱动态试试看6 0秒| 蜜臀AV成人精品蜜臀| 小草精彩毛片| 国产免费一区| JuliaAnn丝袜熟女系列| 日韩啊V| 一区二区三区四区免费视频| 在线观看精品国产免费| 蜜臀久久99精品久久久老,,| 国产a级精品| 99热线麻豆 | 99免费在线视频| 高潮嗯啊性感美女久久久| 久久久∴| 2017av无码免费无线播| 强奸乱伦Av网| 男人亚洲91首页在线| 99re这里| 精品视频一区二区| 天天做日日爱夜夜爽| 五月天春色激情网| 亚洲无码日韩电影| 狠狠色狠狠色狠狠五月| 超91综合网| 人妻少妇无码 | 少妇被c 黄 免费观看| 在线无码操| 美欧老女人97| 色婷婷国产精品一区在线观看| 亚洲av国产av综合av卡| 色综合91| 97久久国产精品女不卡| 五月天玖玖资源站| 97 九色| 99e久久国产精品| 极品白嫩福利在线| 国产成人精品一区| 国产亚州高清国产拍精| 亚洲男人天堂2016| 青娱乐福利99| 草久久久| 国产亚洲日韩欧| 国产农村妇女精品1区二区| 中日韩一区二区三区欧美| 国产在线不卡导航| 久久久久97| 欧美日韩淫加| 少妇一级无码精品| 欧美一区二区三区大综合| 91性高朝久久久久久久久| 亚洲 欧美 小说| xxxx网站亚洲精品| 91精品又粗又猛又爽| 性色av网站| 唯美清纯 妖精视频| 日本精品一区二区中文字幕| 91天天综合在线观看| 亚洲成A∨人影院在线欢看| 少好三P| 天天日少妇逼AV| 91精品国产91久久青草| 精品人妻无码一区二区三区不卡-精品人妻无码一区二区...|精品少妇一区二区三 | 日韩精品区二区三区不卡| 99热在线播放| 亚洲宗合电影| 欧美精品久久久久久久久88| 操91| 亚洲精品97在线| 久久久久久久国产视频| 欧美熟妇色| 美女主播色欲91抠b在线播放| 一起草精品人妻| 人人操人人干xxx| www.acm成人黄色毛片| 人妻啊啊人妻啊| 黄色AAAAAAAAAAA大片| 欧美 亚洲精品首页| 91少妇香蕉久久精品| 午夜欧美J进J出白浆流出久久久| 国产熟女免费观看久久| 亚洲国产另类在线中文| 久久久久幕乱码| 欧美在线55555| 九九九九九九九九九九九免费国产| 婷婷五月天激情网| 涩涩这里只有精品视频| 久久精品国产AV一区二区三区| 欧美在线大香999| 亚洲成人色情五月天丁香花| 性色中出| 色欲人妻一区二区在线| 亚洲熟女国产综合另类| 国产精品天美传媒| 亚州精人品大香蕉| 九九在线精品| 亚洲美乱| 91精品人妻一区二区三区蜜桃臀| 97久久精品亚洲| 看看小穴| 国产成自自拍在线观看| 九九拍拍精品视频在线播放 | 风韵犹存大大大大香蕉 | 囯产操逼片| 亚洲人人操| 蜜臀av中字字幕网站| 婷婷久久五月天| 1956日韩精品| 日韩一级片在线看| 中文字幕乱碼在线| 97超碰欧美手机在线| 大香蕉一级黄色片久久| 一起草在线视频| 国产欧美日韩在线不卡第一页| 不卡超碰护士AV在线免费播放| 97av,com| 17c在线成人免费A片观看| 欧美日韩超碰在线|