基于vue-cli3 + axios 构建多页面应用H5移动端电商网站项目(上)X

本文介绍基于Vue CLI 3和Axios构建多页面H5移动端电商网站的技术栈及核心功能实现,涵盖首页轮播图、商品列表、详情页等模块。

基于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, // 关闭https      hotOnly: 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, // 生产环境自动删除debugger                    drop_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 } = response
    return 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, undefined            var i = 0            if (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;     },    // 页面单位rem  rem: 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接口规则等等。

 

未完待续。。。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值