基于vue-cli3 + axios 构建多页面应用H5移动端电商网站(上)
github源码地址:
https://github.com/jackchen0120/woyouzhe
项目架构
│ vue.config.js // webpack配置│ vue.util.js // 打包多页面配置├─public│ favicon.ico // 图标│ index.html // 入口html文件│ share.png // 微信分享提示├─src│ ├─assets│ │ ├─css│ │ │ common.css // 公共样式文件│ │ ├─img // 存放公共图片文件夹│ │ └─js│ │ api.js // 封装所有API接口调用方法│ │ common.js // 常用JS方法│ │ export.js // 外部调用统一出口│ │ fastclick.js // 移动端点击延迟事件处理│ │ network.js // axios封装与拦截器配置│ │ url.js // 自动部署服务器环境│ ├─components│ │ backTop.vue // 返回顶部组件│ │ categoryList.vue // 商品分类组件│ │ errNotice.vue // 错误弹框提示信息组件│ │ jumpCoupon.vue // 跳转优惠券│ │ loading.vue // 页面初始化加载数据的动画组件│ │ qrcodePop.vue // 生成二维码弹框│ │ shopList.vue // 商品列表组件│ │ soldOut.vue // 请求数据错误展示占位图│ ├─mock│ │ index.js // 引入mockjs模拟数据│ └─pages│ ├─coupon│ │ coupon.html // 领券页面结构│ │ coupon.js // 领券页面入口文件,加载各种公用组件│ │ coupon.vue // 领券页│ ├─detail│ │ detail.html // 商品详情结构│ │ detail.js // 商品详情入口文件,加载各种公用组件│ │ detail.vue // 商品详情页│ ├─index│ │ index.html // 首页结构│ │ index.js // 首页入口文件,加载各种公用组件│ │ index.vue // 首页│ └─search│ search.html // 商品分类/关键词搜索页面结构│ search.js // 商品搜索入口文件,加载各种公用组件│ search.vue // 商品搜索页└─static // 存放静态资源文件夹└─img // 静态图片文件夹
技术栈
-
vue2.6
-
axios
-
webpack
-
ES6/7
-
flex
-
rem
-
mockjs
功能模块
-
首页轮播图
-
商品列表
-
返回顶部
-
类目、模糊搜索
-
生成二维码公众号
-
详情页展示
-
猜你喜欢
-
查看、领取优惠券
-
复制优惠券链接
-
朋友圈分享提示
部分截图
首页
![]()

商品列表页(含搜索功能)

生成二维码公众号

商品详情页

查看优惠券

复制优惠券链接

领取优惠券

准备工作
-
windows 7/10系统
-
nodejs v9+下载安装,官网地址:https://nodejs.org/zh-cn/
-
代码编辑器工具 sublime text 2/3
搭建开发环境(1-4如上文)
5. 开发配置
在使用vue-cli3脚手架创建项目后,因为webpack的配置均被隐藏,当你需要覆盖原有的配置时,则需要在项目的根目录下,新建vue.config.js文件,来配置新的配置如下(含注解):
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')const isProduction = process.env.NODE_ENV === 'production'module.exports = {publicPath: isProduction ? '/dist/' : '/', // 部署生产环境和开发环境下的URL:可对当前环境进行区分lintOnSave: false, // 是否在代码保存时进行eslint检测productionSourceMap: false, // 是否在构建生产包时生成sourceMap文件,false将提高构建速度devServer: { // webpack-dev-server 相关配置port: '8090', // 端口号https: false, // 关闭httpshotOnly: false, // 取消热更新// proxy: { // 使用代理// '/api': {// target: '//www.woyouzhe.com', // 目标代理服务器地址// changeOrigin: true, // 允许跨域// pathRewrite:{// '^/api': '' // 重写路径,需要设置重写的话,要在后面的调用接口前加上/api来代替target// }// }// }},// webpack手动配置configureWebpack: (config) => {if (isProduction) {// 取消webpack警告的性能提示config.performance = {hints: 'error',maxAssetSize: 300000, // 生成文件的最大体积,整数类型(以字节为单位)maxEntrypointSize: 500000, // 入口起点的最大体积,整数类型(以字节为单位)assetFilter: function(assetFilename) { // 只给出js文件的性能提示return assetFilename.endsWith('.js');}}config.plugins.push(new UglifyJsPlugin({uglifyOptions: {compress: {drop_debugger: true, // 生产环境自动删除debuggerdrop_console: true, // 生产环境自动删除console},warnings: false // 删除无用代码,不提示警告},sourceMap: false, // 关闭错误消息位置映射到模块parallel: true, // 启用多进程并行运行}))}}}
多页面配置,在项目根目录新建vue.util.js文件,如下:
const path = require('path')const glob = require('glob')const startPath = '/src/pages/'const pagePath = path.resolve(__dirname, '.' + startPath)exports.pages = function () {let entryFiles = glob.sync(pagePath + '/**/*.html')let obj = {}entryFiles.forEach(filePath => {let dirPath = filePath.substring(0, filePath.lastIndexOf('/'))let dirName = dirPath.substring(dirPath.lastIndexOf('/') + 1)let filename = filePath.substring(filePath.lastIndexOf(startPath) + startPath.length, filePath.lastIndexOf('/'))if (filename.endsWith(dirName)) {obj[filename] = {entry: filePath.substring(0, filePath.lastIndexOf('.html')) + '.js',template: filePath.substring(0, filePath.lastIndexOf('.html')) + '.html'}}})return obj}
配置完成,在vue.config.js文件引入vue.util.js,如下图:

多页面配置完成后,在src文件夹下创建pages文件夹,里面放每个页面模块,每个界面由html、js、vue三部分组成,如下图:

6. 公共样式,图片,JS,统一存放在/src/assets/文件夹下,如下图:

js文件夹里面的每个js文件的作用,如下:
url.js是自动部署生产环境和开发测试环境服务器地址,代码如下:
let baseUrl = ''if (process.env.NODE_ENV == 'development') {console.log('dev')//开发、测试环境baseUrl = '//yapi.demo.qunar.com/mock/95397/api'} else if (process.env.NODE_ENV == 'production') {console.log('prod')// 生产环境baseUrl = '//www.woyouzhe.com/api'}export {baseUrl}
network.js是axios封装与拦截器配置,先安装axios,再引入到network.js,代码如下:
import axios from 'axios'import { baseUrl } from './url'let service = axios.create({baseURL: baseUrl, // 请求前缀timeout: 55000, // 请求超时时间})// 设置 post 默认 Content-Typeservice.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';// 添加请求拦截器service.interceptors.request.use(config => {// 这里可以添加head 部分return config},err => {// 请求错误处理return Promise.reject(err)})// 添加响应拦截器service.interceptors.response.use(response => {let { data } = responsereturn data},err => {// 响应错误处理return Promise.reject(err)})export default service
api.js是封装所有API接口调用方法,后面会具体讲解怎么调用这些方法,获取服务端返回的数据,代码如下:
import network from './network'import { baseUrl } from './url'// 商品列表接口export function getShopList(params) {return network({url: '/shoplist',method: 'get',params});}
common.js是常用JS方法,代码如下:
let Rxports = {// 遍历数组与对象,回调的第一个参数为索引或键名,第二个或元素或键值each: function (obj, fn) {var me = this;if (obj) { // 排除null, undefinedvar i = 0if (me.isArrayLike(obj)) {for (var n = obj.length; i < n; i++) {if (fn(i, obj[i]) === false)break}} else {for (i in obj) {if (obj.hasOwnProperty(i) && fn(i, obj[i]) === false) {break}}}}},// 获取url参数getUrlParam: function () {var url = window.location.search, // 获取url中"?"符后的字串theRequest = new Object();if (url.indexOf("?") != -1) {var str = url.substr(1), strs = str.split("&");for(var i = 0; i < strs.length; i ++) {theRequest[strs[i].split("=")[0]] = decodeURI(strs[i].split("=")[1]);}}return theRequest;},// 页面单位remrem: function () {var docEl = document.documentElement,resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',recalc = function () {var clientWidth = docEl.clientWidth;if (!clientWidth) return;if (clientWidth >= 750) {docEl.style.fontSize = '100px';} else {docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';}};recalc();window.addEventListener(resizeEvt, recalc, false);},// 自定义模态框modalHelper: {scrollTop: '',bodyCls: 'modal-open',srcollBody: (document.scrollingElement || document.body),afterOpen: function() {var me = this;this.scrollTop = this.srcollBody.scrollTop;document.body.classList.add(me.bodyCls);document.body.style.top = -this.scrollTop + 'px';},beforeClose: function () {var me = this;document.body.classList.remove(me.bodyCls);this.srcollBody.scrollTop = this.scrollTop;document.body.style.top = '0';}},// 去除空格trim: function (strs) {return strs.replace(/(^\s*)|(\s*$)/g, '');}}export default Rxports
fastclick.js是处理移动端点击事件之后,出现300ms延迟,可以直接安装引入使用,我是直接下载js插件到本地再引入。
// 安装npm install -S fastclick// 引入import FastClick from 'fastclick'// 使用FastClick.attach(document.body);
export.js是外部调用模块统一出口,代码如下:
import '../css/common.css'import C from './common'// 解决click点击300毫秒延时问题import FastClick from './fastclick'// FastClick.attach(document.body);!(function(){new FastClick(document.body)})export default C
以上基本架构搭建完成,下面终于要进入页面功能开发。一般开发项目之前,需要先分析页面需求,有哪些功能模块,技术选型,有无技术难点(是否可替代),哪些组件可复用,手机适配,前端性能考虑,是否多人协作开发,与后端约定API接口规则等等。
未完待续。。。
本文介绍基于Vue CLI 3和Axios构建多页面H5移动端电商网站的技术栈及核心功能实现,涵盖首页轮播图、商品列表、详情页等模块。
2780

被折叠的 条评论
为什么被折叠?



