资讯专栏INFORMATION COLUMN

Vue+Vue-router+Vuex项目实战

zlyBear / 2413人阅读

摘要:实现电商网站效果展示下载代码安装依赖启动项目运行环境需求分析登录页面商品列表页网站首页购物车页实现结算商品详情页可按颜色品牌对商品进行筛选,单击选中,再次点击取消根据价格进行升序降序销量降序排列商品列表显示图片名称销量颜色单价实时显示

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
需求分析

登录页面、商品列表页(网站首页)、购物车页(实现结算)、商品详情页

可按颜色、品牌对商品进行筛选,单击选中,再次点击取消

根据价格进行升序降序、销量降序排列

商品列表显示图片、名称、销量、颜色、单价

实时显示购物车数量(商品类别数)

购物车页面实现商品总价、总数进行结算,优惠券打折

数据存储 & 数据处理

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102706.html

相关文章

  • Vue+Vue-router+Vuex项目实战

    摘要:实现电商网站效果展示下载代码安装依赖启动项目运行环境需求分析登录页面商品列表页网站首页购物车页实现结算商品详情页可按颜色品牌对商品进行筛选,单击选中,再次点击取消根据价格进行升序降序销量降序排列商品列表显示图片名称销量颜色单价实时显示 shopping vue + vue-router + vuex实现电商网站 效果展示 showImg(https://user-gold-cdn.xi...

    Chiclaim 评论0 收藏0
  • Vue+Vue-router+Vuex项目实战

    摘要:实现电商网站效果展示下载代码安装依赖启动项目运行环境需求分析登录页面商品列表页网站首页购物车页实现结算商品详情页可按颜色品牌对商品进行筛选,单击选中,再次点击取消根据价格进行升序降序销量降序排列商品列表显示图片名称销量颜色单价实时显示 shopping vue + vue-router + vuex实现电商网站 效果展示 showImg(https://user-gold-cdn.xi...

    Half 评论0 收藏0
  • 手挽手带你学VUE:四档 Vue-cli3 Vuex Vue-router

    摘要:安装过后到命令行执行检查版本,如果弹出版本的话恭喜你安装成功,我们开始进行下面的步骤了。全局安装的包名称由改成了。如果你已经全局安装了旧版本的或,你需要先通过卸载它。中的非常类似于事件每个都有一个字符串的事件类型和一个回调函数。 视频教程 由于思否不支持视频外链,视频请移步http://www.henrongyi.top 你能学到什么 在这一期的学习进度中,我们会开始学习在我们工作开...

    Sourcelink 评论0 收藏0
  • 手挽手带你学VUE:四档 Vue-cli3 Vuex Vue-router

    摘要:安装过后到命令行执行检查版本,如果弹出版本的话恭喜你安装成功,我们开始进行下面的步骤了。全局安装的包名称由改成了。如果你已经全局安装了旧版本的或,你需要先通过卸载它。中的非常类似于事件每个都有一个字符串的事件类型和一个回调函数。 视频教程 由于思否不支持视频外链,视频请移步http://www.henrongyi.top 你能学到什么 在这一期的学习进度中,我们会开始学习在我们工作开...

    AlphaWallet 评论0 收藏0
  • 前端面试题总结(js、html、小程序、React、ES6、Vue、算法、全栈热门视频资源)

    摘要:并总结经典面试题集各种算法和插件前端视频源码资源于一身的文档,优化项目,在浏览器端的层面上提升速度,帮助初中级前端工程师快速搭建项目。 本文是关注微信小程序的开发和面试问题,由基础到困难循序渐进,适合面试和开发小程序。并总结vue React html css js 经典面试题 集各种算法和插件、前端视频源码资源于一身的文档,优化项目,在浏览器端的层面上提升速度,帮助初中级前端工程师快...

    pumpkin9 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<