014基于Vue.js的移动端购物商城网站(含源码课设报告)

Posted 宁小流

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了014基于Vue.js的移动端购物商城网站(含源码课设报告)相关的知识,希望对你有一定的参考价值。

文章目录

一、项目介绍

基于Vue.js的移动端购物商城网站(含源码、课设报告),代码获取放在文末了,码字不易,感谢点赞~

一、系统概述
本部分主要是对项目进行简要描述,包括开发背景、目的、内容及意义。
Vue.js是一个轻巧、高性能、可组件化的MVVM库,同时拥有非常容易上手的API,通过Vue.js开发微商城项目,以轻量级的框架,实现双向数据绑定,并进行模块化开发。该商城项目实现了基本的商品分类、商品导航栏首页、个人订单详情、个人信息界面。

二、开发环境
本部分介绍项目开发中使用的环境,包括使用的操作系统、代码编辑工具、项目调试工具、项目中使用的脚手架等。
操作系统:win10
编程软件:VSCODE、node.js
所用技术支持:Vue-cli+Node.js+Vue-router+VueX

三、系统分析
1.功能需求
主要实现一个商城平台,拥有商城首页、商品分类、购物车购买、个人详情页等主要界面。实现用户购买、分类选择、查看商品详情。项目以前端开发为主,使用Vue-cli脚手架和单页面组件化开发,通过脚手架vue-cli开发项目,每个 .vue单文件就是一个组件。在父组件中使用import 导入一个子组件,并在components中注册子组件,子组件需要数据,可以在props中接受定义。而子组件修改好数据后,通过$emit等方法触发自定义事件传递参数,把数据传递给父组件,最终将商品信息、购物车等信息展示到页面。

2.页面布局规划

页面布局说明:主要采用上中下三层布局,底部导航栏为Vue单页面组件,顶部标题则为通过tabname="$t(‘m.HeaderDetail’)"传入的参数而改变标题。商品以轮播图为主。
3.建设方案
1.先确定好页面的总体布局,初始样式等
2.创建好所有页面文件,并通过vue-router 写好各个页面的路由关系
3.逐个实现各个页面的样式和功能
4.通过vuex解决组件和页面之间的通信

四、系统设计与实现
1.准备工作
根据功能分析设计界面初始图,设定页面布局和前端的结构设计,采用vue-cli进行架构,通过路由路由懒加载,对组件进行映射与跳转,通过给主路由添加children 项,实现嵌套路由,完成零食商城单页面应用的路由页面管理。

  1. 主要文件目录说明

├── node_modules # 安装的包
├── public # 静态资源
│ ├── favicon.ico
│ └── index.html
└── src
├── api # 请求接口封装模块
├── assets # 资源目录
├── components # 组件目录
├── router # 路由模块
├── store # Vuex容器模块
├── styles # 样式目录
├── utils # 工具模块目录
├── views # 视图组件目录
└──address # 个人地址模块
| ├── address.vue
├─cart # 订单提交模块
| ├── cart.vue
├─category # 商品分类模块
| ├── category.vue
├─detail #商品详情模块
| ├── detail.vue
├─menber # 用户模块
| ├── menber.vue
└─Layout.vue # 公用布局组件
├── Home.vue # 根组件
└── main.js # 入口文件
├── .browserslistrc # 浏览器的约定
├── .editorconfig # 对本项目要用到编辑器的约定
├── .eslintrc.js # eslint 配置
├── .gitignore # git的忽略设置,哪些文件不需要git托管
├── babel.config.js # babel配置文件
├── package-lock.json # npm相关文件
├── package.json # npm相关文件
└── README.md # 项目说明文件


代码说明:该部分代码主要在Category.vue中,通过路由配置,设置好商品及其对应跳转详情页/detail,展示具体商品信息,页面结构以轮播列表为主,提供用户加入购物车和分类选择商品。



代码解释:根据用户的下单情况,将订单详情展示,订单支付金额、订单号等信息对应存在[“this. s t o r e . s t a t e . p a y s " , " t h i s . store.state.pays","this. store.state.pays","this.store.state.ordercur”, “this.$store.state.ordertab”],并将数据请求展示到页面。

五、总结
课程设计是我们专业课程知识综合应用的实践训练,这是我们迈向社会,从事职业工作前一个必不少的过程,通过这次课程设计,综合运用本专业所学课程的理论培养和提高我们独立工作能力,巩固与扩充了课程所学的内容,同时各科相关的课程都有了全面的复习,独立思考的能力也有了提高。
本次课设的主要技术为:Vue-cli+Node.js+Vue-router+VueX,这次设计过程中,我主要负责需求分析、代码测试,过程中体会了学以致用、从中发现自己平时学习的不足和薄弱环节,从而加以弥补。 通过这次课设,不仅提高了我对于Vue项目的理解,也更加深巩固对一个完整前端项目的创建与操作。对未来从事前端相关工作也有所帮助。

二、代码及报告获取

百度云链接:https://pan.baidu.com/s/1pKJPGaouK6e4h4TA3YLztg?pwd=wnfi
提取码:wnfi

基于nodejs手机网页端购物电商系统.rar(含源码)

该商城shop是一个nodejs写的商城系统,。目前功能首页,商品搜索,购物车,我的,登录,商品详情,结算等,网站手机端网页程序,适合毕业设计以及商用二次开发,前端:weui.cssjqueryjquery.spinnerrequirejsswiper-4.1.6vuevue-resource;后端:koa2koa-bodyparserkoa-routernunjucksmimemzkoa-compresssequelizemysqlkoa-session2log4jsmoment

数据库相关代码:

var config = {
    dialect: 'mysql',
    database: 'zshop',
    username: 'root',
    password: 'root',
    host: 'localhost',
    port: 3306,
    rootpath: '/zshop'
};

module.exports = config;

配置文件

// config files:
const defaultConfig = './config-default.js';
const overrideConfig = './config-override.js';
const testConfig = './config-test.js';

const fs = require('fs');

var config = null;

if (process.env.NODE_ENV === 'test') {
    console.log(`Load ${testConfig}...`);
    config = require(testConfig);
} else {
    console.log(`Load ${defaultConfig}...`);
    config = require(defaultConfig);
    try {
        if (fs.statSync(overrideConfig).isFile()) {
            console.log(`Load ${overrideConfig}...`);
            config = Object.assign(config, require(overrideConfig));
        }
    } catch (err) {
        console.log(`Cannot load ${overrideConfig}.`);
    }
}

module.exports = config;

部分页面截图:

代码如下:

//购物车ctrl
const cartService = require('../service/cart-service');
const APIError = require('../middleware/rest').APIError;

module.exports = {
    'GET /user/cart': async (ctx, next) => {
        var userCartProds = await cartService.getUserCartProd(ctx.session.user); 
        
        ctx.render('cart.html', userCartProds);
    },

    'POST /userapi/delCartProd': async (ctx, next) => {
        //console.log(JSON.stringify(ctx.request.body));
        var cid = ctx.request.body.cid || '';
        await cartService.deleteCardProd(cid); 
        //ctx.rest();
        ctx.rest({code: 'system:success', message: '成功'});
    },

    'POST /userapi/chgCartProdCount': async (ctx, next) => {
        var cid = ctx.request.body.cid || '';
        var newValue = ctx.request.body.newValue || '';
        await cartService.updateCardProdCount(cid, newValue); 
        ctx.rest();
    },

    'POST /userapi/addCartProd': async (ctx, next) => {
        var pid = ctx.request.body.pid || '';
        var pcount = ctx.request.body.pcount || '1';
        if (!pid || pid.trim() == '') {
            throw new APIError('cart:empty_pid', '商品ID不能为空');
        }
        let cartSize = await cartService.addCartProd(pid, pcount, ctx.session.user.userId); 
        ctx.rest({cartSize: cartSize});
    }
};




代码如下:

//首页ctrl
const productService = require('../service/product-service');
const adService = require('../service/ad-service');
const orderService = require('../service/order-service');
const userService = require('../service/user-service');
const APIError = require('../middleware/rest').APIError;
const fs = require('mz/fs');
const uuid = require('node-uuid');

module.exports = {
    //首页
    'GET /': async (ctx, next) => {
        ctx.logger.info('===index in===');
        var products = await productService.getRecomProduct(1); //精品推荐
        var headAds = await adService.getAdByPosition(1); //头部广告
        var midAds = await adService.getAdByPosition(2); //中部广告
        //let userId = null;
        //if (ctx.session.user) userId = ctx.session.user.userId;
        //let orderCount = await orderService.countOrder("1111", userId);
        
        console.log('===index mid===');
        ctx.render('index.html', { 
            prods: products, 
            hAds: headAds, 
            mAdImg: midAds[0].image,
            user: ctx.session.user
            //orderCount: orderCount
        });
        ctx.logger.info('===index out===');
    },

    //商品搜索
    'GET /api/search/:key/:limit/:offset/:ordertype': async (ctx, next) => {
        var skey = ctx.params.key;
        if (!skey || skey.trim() == '') {
            throw new APIError('sproduct:empty_key', '搜索关键字不能为空');
        }
        var products = await productService.searchProduct(skey, ctx.params.limit, ctx.params.offset, ctx.params.ordertype);
        ctx.rest({
            prods: products
        });
    },

    'GET /user/userPage': async (ctx, next) => { 
        let user = await userService.getOneUser({userId: ctx.session.user.userId});
        ctx.render('user.html', {
            userId: user.userId,
            name: user.name,
            email: user.email,
            headImage: user.headImage
        });
    },

    'POST /userapi/checkUserInfo': async (ctx, next) => {
        let email = ctx.request.body.email || '';
        let userId = ctx.request.body.userId || '';

        let result = await userService.checkUserInfo(email, userId, ctx.session.user.id);

        ctx.rest(result);
    },

    'POST /userapi/uptUserInfo': async (ctx, next) => {
        let noImage = ctx.query.noImage;
        let user = await userService.getOneUser({userId: ctx.session.user.userId});

        let name = null;
        let userId = null;
        let email = null;
        if (noImage) {
            name = ctx.request.body.name || '';
            userId = ctx.request.body.userId || '';
            email = ctx.request.body.email || '';
        } else {
            name = ctx.request.body.fields.name || '';
            userId = ctx.request.body.fields.userId || '';
            email = ctx.request.body.fields.email || '';
        }

        let userValue = new Object();
        if (name != user.name) {
            userValue.name = name;
        }
        if (userId != user.userId) {
            if (await userService.countUser({userId: userId}) >= 1) {
                throw new APIError('uptUserInfo:repeat_userId', '该用户ID已被占用');
            }
            userValue.userId = userId;
        } 
        if (email.trim() != '' && email != user.email) {
            if (await userService.countUser({email: email}) >= 1) {
                throw new APIError('uptUserInfo:repeat_email', '该电子邮箱已被占用');
            }
            userValue.email = email;
        } 

        if (!noImage) {
            let file = ctx.request.body.files.uploaderInput; // 获取上传文件
            let reader = fs.createReadStream(file.path); // 创建可读流
            let ext = file.name.split('.').pop(); // 获取上传文件扩展名
            let filePath = `static/images/head/${uuid.v4().replace(/-/g, "")}.${ext}`;
            let upStream = fs.createWriteStream(filePath); // 创建可写流
            reader.pipe(upStream); // 可读流通过管道写入可写流 

            userValue.headImage = '/' + filePath;
        }

        await userService.uptUser({id: user.id, version: user.version}, userValue);

        if (userValue.name) {
            ctx.session.user.name = userValue.name;
        }
        if (userValue.userId) {
            ctx.session.user.userId = userValue.userId;
        }
        if (userValue.email) {
            ctx.session.user.email = userValue.email;
        }
        if (userValue.headImage) {
            ctx.session.user.headImage = userValue.headImage;
        }

        if (!noImage && user.headImage.indexOf("bear.jpg") == -1) {
            let delFilePath = user.headImage.substr(1, user.headImage.length - 1);
            fs.unlink(delFilePath, function (err) {
                if(err) {
                    console.log(user.headImage + '删除失败:' + err);
                }
            })
        }

        ctx.rest({});
    },

    'GET /user/uptPassPage': async (ctx, next) => { 
        ctx.render('upt-pass.html');
    },

    'POST /userapi/checkPassword': async (ctx, next) => {
        let oldPassword = ctx.request.body.oldPassword || '';
        let user = await userService.getOneUser({userId: ctx.session.user.userId});

        if ( oldPassword != user.passwd ) {
            throw new APIError('index:error_password', '原的密码错误');
        }

        ctx.rest({});
    },

    'POST /userapi/uptPass': async (ctx, next) => {
        let oldPassword = ctx.request.body.oldPassword || '';
        let password = ctx.request.body.password || '';
        //let passwordConfirm = ctx.request.body.passwordConfirm || '';
        let user = await userService.getOneUser({userId: ctx.session.user.userId});

        if ( oldPassword != user.passwd ) {
            throw new APIError('index:error_password', '原的密码错误');
        }

        let userValue = new Object();
        await userService.uptUser({id: user.id, version: user.version}, {passwd: password});

        ctx.rest({});
    }
};




相关文档视频说明:点击观看

完整源码下载地址:请点击》》》

以上是关于014基于Vue.js的移动端购物商城网站(含源码课设报告)的主要内容,如果未能解决你的问题,请参考以下文章

身份证识别基于matlab GUI身份证号码识别含Matlab源码 014期

基于html化妆品购物商城项目的设计与实现.rar(含源码30个页面左右及毕业设计论文)

djangorestframework开发最完美手机购物商城APP带前后端源码

djangorestframework开发最完美手机购物商城APP带前后端源码

前端静态页面html珠宝首饰电商平台网站购物商城系统.rar含源码

二.移动端组件库