vue+vue-router+vuex實戰


shopping

vue + vue-router + vuex實現電商網站

效果展示

install

  • 下載代碼: git clone https://github.com/chenchangyuan/shopping.git
  • 安裝依賴: npm install
  • 啟動項目: npm run dev

運行環境: node v9.11.1 npm 5.6.0

需求分析

  1. 登錄頁面、商品列表頁(網站首頁)、購物車頁(實現結算)、商品詳情頁
  2. 可按顏色、品牌對商品進行篩選,單擊選中,再次點擊取消
  3. 根據價格進行升序降序、銷量降序排列
  4. 商品列表顯示圖片、名稱、銷量、顏色、單價
  5. 實時顯示購物車數量(商品類別數)
  6. 購物車頁面實現商品總價、總數進行結算,優惠券打折

數據存儲 & 數據處理

  • product.js存放商品數據(生產環境需通過接口調用獲取數據)
{
	id: 1,
	name: 'AirPods',
	brand: 'Apple',
	image: '/src/images/airPods.jpg',
	imageDetail: '/src/images/airPods_detail.jpg',
	sales: 10000,
	cost: 1288,
	color: '白色'
},
  • window.localStorage實現數據存儲與驗證
let username = window.localStorage.getItem('username');
let password = window.localStorage.getItem('password');
if(!util.trim(this.username) || !util.trim(this.username) ){
	window.alert('賬號或密碼不能為空');
	return;
}
if(username === this.username && password === this.password){
	this.login = false;
	window.localStorage.setItem('loginStatus', 'login');
	this.$store.commit('getUser', this.username);
	window.alert('登陸成功,確定進入網站首頁');
	window.location.href = '/list';
}else{
	window.alert('賬號或密碼錯誤');
}

數據過濾與排序處理

filteredAndOrderedList(){
	//拷貝原數組
	let list = [...this.list];
	//品牌過濾
	if(this.filterBrand !== ''){
		list = list.filter(item => item.brand === this.filterBrand);
	}
	//顏色過濾
	if(this.filterColor !== ''){
		list = list.filter(item => item.color === this.filterColor);
	}
	//排序
	if(this.order !== ''){
		if(this.order === 'sales'){
			list = list.sort((a, b) => b.sales - a.sales);
		}else if(this.order === 'cost-desc'){
			list = list.sort((a, b) => b.cost - a.cost);
		}else if(this.order === 'cost-asc'){
			list = list.sort((a, b) => a.cost - b.cost);
		}
	}
	return list;
}

實時顯示應付總額與商品數

//購物車商品總數
countAll(){
	let count = 0;
	this.cartList.forEach(item => {
		count += item.count;
	});
	return count;
},
//購物車商品總價
costAll(){
	let cost = 0;
	this.cartList.forEach(item => {
		cost += this.productDictList[item.id].cost * item.count;
	});
	return cost;
}

購物車結算處理

//通知Vuex,完成下單
handleOrder(){
	this.$store.dispatch('buy').then(() => {
		window.alert('購買成功');
	})
},

vue-router & vuex

vue-router路由管理/src/views/目錄下的vue組件進行設置,router-views掛載所有路由,登錄界面與商品列表頁面之間header做隱藏顯示處理,登錄狀態下刷新頁面跳轉至列表頁,其他頁面設置默認跳轉

跳轉處理

const router = new VueRouter(RouterConfig);

//跳轉前設置title
router.beforeEach((to, from, next) => {
    window.document.title = to.meta.title;
    next();
});
//跳轉后設置scroll為原點
router.afterEach((to, from, next) => {
    window.scrollTo(0, 0);
});

routers配置

//商品列表路由配置
const routers = [
    {
        path: '/list',
        meta: {
            title: '商品列表'
        },
        component: (resolve) => require(['./views/list.vue'], resolve)
    },
    {
        path: '/product/:id',
        meta: {
            title: '商品詳情'
        },
        component: (resolve) => require(['./views/product.vue'], resolve)
    },
    {
        path: '/cart',
        meta: {
            title: '購物車'
        },
        component: (resolve) => require(['./views/cart.vue'], resolve)
    },
    {
        path: '/login/:loginStatus',
        meta: {
            title: '購物車'
        },
        component: (resolve) => require(['./views/login.vue'], resolve)
    },
    {
        path: '*',
        redirect: '/login/login'
    }
];
export default routers;

vuex狀態管理,各組件共享數據在state中設置,mutation實現數據同步,action異步加載

//配置Vuex狀態管理
const store = new Vuex.Store({
    state: {
        //商品列表信息
        productList: [],
        //購物車數據,數組形式,數據元素為對象(商品id,購買數量count)
        cartList: [],
        //當前用戶賬號
        username: window.localStorage.getItem('username'),
        //登錄狀態
        loginStatus: !!window.localStorage.getItem('loginStatus'),
    },
	getters: {
        //品牌、顏色篩選
        brands: state => {
            const brands = state.productList.map(item => item.brand);
            return util.getFilterArray(brands);
        },
        colors: state => {
            const colors = state.productList.map(item => item.color);
            return util.getFilterArray(colors);
        }
    },
    //mutations只能以同步方式
    mutations: {
        //添加商品列表
        setProductList(state, data){
            state.productList = data;
        },
        //添加購物車
        addCart(state, id){
            const isAdded = state.cartList.find(item => item.id === id);
            //如果不存在設置購物車為1,存在count++
            if(isAdded){
                isAdded.count++;
            }else{
                state.cartList.push({
                    id: id,
                    count: 1
                })
            }
        },
		//修改購物車商品數量
        editCartCount(state, payload){
            const product = state.cartList.find(item => item.id === payload.id);
            product.count += payload.count;
        },
        //刪除購物車商品
        deleteCart(state, id){
            const index = state.cartList.findIndex(item => item.id === id);
            state.cartList.splice(index, 1)
        },
        //清空購物車
        emptyCart(state){
            state.cartList = [];
        },
        getUser(state, username){
            console.log('username',username)
            state.username = username;
        },
        getLoginStatus(state, flag){
            state.loginStatus = flag;
        }
    },
	actions: {
        //異步請求商品列表,暫且使用setTimeout
        getProductList(context){
            setTimeout(() => {
                context.commit('setProductList', product_data)
            }, 500);
        },
        //購買
        buy(context){
            //生產環境使用ajax請求服務端響應后再清空購物車
            return new Promise(resolve => {
                setTimeout(() => {
                    context.commit('emptyCart');
                    resolve();
                }, 500);
            });
        },
    }
});

后記

項目地址: 閱讀完本文如果對vue的理解有所幫助,請給顆star,謝謝~

筆者個人微信gm4118679254,歡迎加好友一起交流技術

參考資料

Vue.js實戰
Vue.js


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM