項目地址 https://github.com/bolonotlob...
方法一:vue
.router-link-exact-active
<!--App.vue--> <template> <div class="app"> <div class="nav"> <router-link tag="li" to="/home">Home</router-link> <router-link tag="li" to="/market">Market</router-link> <router-view></router-view> </div> </div> </template> <script> export default {}; </script> <style scoped > .nav li.router-link-exact-active { // 高亮 color: red; } </style>
方法二:ios
linkActiveClass:個人樣式名
git
//router/index.js const routes = [ { path: '/', redirect: '/home' }, { path: '/home',component: ()=>import('@/views/Home')}, { path: '/market',component: ()=> import('@/views/Market')} ] const router = new VueRouter({ linkActiveClass: 'myactive', // .myactive 爲路由激活樣式名,在 App.vue 中定義 .myactive{ color: red; } routes })
根目錄/vue.config.jsgithub
const products = [ { id: 1, name: 'iphone', price: 800, inventory: 10 }, { id: 2, name: 'iphone pro', price: 1000, inventory: 10 }, { id: 3, name: 'iphone max', price: 1200, inventory: 10 }, ] module.exports = { devServer: { before(app, serve) { app.get('/api/products', (req, res) => { res.json({ result: products }) }) } } }
http://localhost:8080/api/products
訪問數據const store = new Vuex.Store({ // ... strict: true }) /* 在嚴格模式下,不管什麼時候發生了狀態變動且不是由 mutation函數引發的, 將會拋出錯誤。這能保證全部的狀態變動都能被調試工具跟蹤到 */
/* ---apis |---apis.js |---index.js */ // apis.js export default { baseUrl: 'http://localhost:8080/api', getAllProducts: '/products' } // index.js import apis from './apis' import axios from 'axios' const ajax = axios.create({ baseURL:apis.baseUrl }) export const getAllProducts = ()=> ajax.get(apis.getAllProducts)
import * as service from '@/apis/index.js' actions: { async getAllProducts({ commit }) { // 發起請求獲取商品數據 try { const ret = await service.getAllProducts() if (ret.status === 200) { const products = ret.data.result commit('SET_PRODUCTS',products) } } catch (err) { console.log(err) } } }
這裏咱們只把商品id和數量存入cartList,固然也能夠存整個商品對象(這裏不這麼作)ajax
//store/modules/products.js mutations: { ADD_TO_CART: (state, { id, quantity }) => { state.cartList.push({ id, quantity }) }, INCREMENT_QUANTITY: (state, { id }) => { state.cartList.find(v => v.id === id).quantity++ } }, actions: { addToCart({ commit, state }, product) { console.log('addToCart') // 判斷購物車中是否已經存在 const cartItem = state.cartList.find(v => v.id === product.id) if (cartItem) { // 若是有 commit('INCREMENT_QUANTITY', { id: product.id }) } else { // 沒有 commit('ADD_TO_CART', { id: product.id, quantity: 1 }) } } }
//store/modules/cart.js getters: { getCartListInfo: (state, getters, rootState) => { return state.cartList.map(({ id, quantity }) => { const product = rootState.products.products.find(v => v.id === id) return { id, name: product.name, price: product.price, quantity } }) } },
// store/modules/cart.js getTotalPrice: (state, getters) => { return getters.getCartListInfo.reduce((total, item) => { return total + item.price * item.quantity }, 0) }
//cart.js 提交 mutations 到 products.js // 全局命名空間提交 mutations 須要加上 {root: true} commit('products/DECREMENT_INVENTORY', { id: product.id }, { root: true })
// main.js Vue.filter('currency', v => '$' + v)
當觸發 Actions,會把父模塊和子模塊的都觸發vuex
官方: 默認狀況下,模塊內部的 action、mutation 和 getter 是註冊在全局命名空間的——這樣使得多個模塊可以對同一 mutation 或 action 做出響應。
/* --- store |---index.js |---modules |---products.js |---cart.js */ // index.js actions getAllProducts(){ console.log(111) } // products.js actions getAllProducts(){ console.log(222) } // Products.vue 組件 dispatch created(){ this.$store.dispatch('getAllProducts') } // 結果分析 // 咱們products 沒有使用命名空間(namespaced:true) 時,這兩個都會觸發 // 輸出結果: // 111 // 222 // 咱們給 products.js 加上命名空間 // namespaced: true, // 組件Products.vue dispatch created(){ this.$store.dispatch('products/getAllProducts') }
// store/index.js state: { products: [1,2] } // store/modules/products.js state: { prodcuts:[3,4] } // 組件中獲取 computed: { ...mapState(['products']) // [3,4] } // vuex.esm.js?2f62:721 [vuex] state field "products" was overridden by a module with the same name at "products"
mapState 的參數json
// 1 computed: { products(){ return this.$store.state.products.products } } // 2 函數形式 state做爲形參傳入 computed: mapState({ /** products(state){ return state.products.products } */ products:state=>state.products.products }) // 3 對象形式 computed: mapState({ products:'products' }) // 4 展開運算 ...mapState computed: { ...mapState('products',['products']) // ...mapState('命名空間',對象/數組) }
this.$store.dispatch(命名空間/actions中方法名)axios
this.$store.dispatch('cart/addToCart')
// cart.vue created() { // 經過 localStorage 初始化購物車 this.$store.dispatch("cart/initializeCartList"); } // products.vue created() { // 若是localStorage 有就直接從裏面拿,沒有再去服務器取 this.$store.dispatch("products/getAllProducts"); }, // 出現的問題: /* 當時沒注意,products.js 裏面用的是mounted 去 dispatch 的 而 cart.js 裏面是 created() 就 dispatch 了 而 cart.js 的 getters裏面返回商品信息的時候須要根據 cartList 的 id,去查詢 products 裏面商品的price,name 這些屬性。 那這個時候由於 生命週期的順序 created 在 mounted 以前(雖然不一樣組件, 並不能保證 cart組件的 created 必定在 products 組件的 mounted 以前) cart 組件 created 時拿到了數據更新了 cartList,getters重新開始計算(像計算屬性), 可是這個時候 products 沒有拿回來數據,全部 getCartListInfo 裏面會出現 product的 屬性沒有定義會報錯 error: Cannot read property 'name' of undefined" */ // cart.js getters: { getCartListInfo: (state, getters, rootState) => { return state.cartList.map(({ id, quantity }) => { const product = rootState.products.products.find(v => v.id === id) return { id, name: product.name, price: product.price, quantity } }) } }
如何解決這個問題呢?後端
let products = JSON.parse(localStorage.getItem('products')) if (products) { commit('SET_PRODUCTS', products) // 在這裏去dispatch // 先拿到 products 再去拿 cartList dispatch('cart/initializeCartList',null,{root:true}) }
// 有命名空間時 commit ,dispatch, 全局分發,...mapState this.$store.dispatch("products/getAllProducts"); this.$store.commit("cart/ADD_TO_CART") commit('products/DECREMENT_INVENTORY', { id: product.id }, { root: true }) //全局分發 mapState(namespace?: string, map: Array<string> | Object<string | function>): Object