# super_mall **Repository Path**: fengshichen/super_mall ## Basic Information - **Project Name**: super_mall - **Description**: Vue CLI4搭建的一个商城购物系统 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-09-15 - **Last Updated**: 2021-06-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 一、项目准备阶段 #### 1. 划分目录结构 >>> 避免文件冗余后造成的混乱 assets >>> 资源文件 css >>> css样式文件 images >>> 图片 components >>> 组件 common >>> 公共组件 [完全公共, 即使到下一个项目也可以使用的组件] content >>> 当前项目的公共组件 [有一些逻辑代码在里面的] views >>> 视图目录 [大的视图文件] router >>> 前端路由目录 store >>> 状态管理目录 utils >>> 工具类型目录 [网络请求、时间戳封装等] common >>> 公共的js文件目录 [定义统一变量等] api >>> 后端API统一管理目录 #### 2. 引入"normalize.css"文件与"base.css"文件 #### 3. vue.config.js别名设置, 配置.editorconfig风格规范 ### 二、项目开始 #### 1. 封装一个公共的navbar组件 题外话: 函数调用的过程? 函数调用时 >>> 压入函数栈 [保存函数调用过程中所有的变量] 函数调用结束后 >>> 弹出函数函数栈 [释放掉函数所有变量] #### 2. 网络请求的封装 #### 3. banner轮播图组件的使用 #### 4. 推荐列表组件的封装与使用 #### 5. 本周流行组件的封装与使用 #### 6. 首页展示列表组件封装与使用 ### 三、导入滚动框架better-scroll #### 1. npm安装better-scroll [运行时依赖] npm install better-scroll --save Vue组件内使用 import BScroll from "better-scroll"; new BScroll('DOM元素标签>>>[wrapper]', {}); #### 2. 框架说明: 1) 使用better-scroll时必须要有一个大的wrapper来包裹可滚动区域 [必须给一个明确高度] 2) 且可滚动区域标签只能有一个 [可以在其内部放其它标签] #### 3. 解释一下为啥使用 better-scroll: '^1.15.2'? coderwhy老师用的就是这玩意,我TM用2.几版本的直接不能滚动,我人傻了。 #### 4. better-scroll的滚动bug描述: 1) 在better-scroll被创建出来后就会计算可滚动区域的高度, 由属性 >>> [scrollerHeight] 决定; 2) [scrollerHeight]属性高度是better-scroll的content内的子组件的高度; 3) 我们的首页中, 刚开始计算[scrollerHeight]属性时, 是没有将图片计算在内的, 所以可能会导致计算结果出错; 4) 后来图片加载进行之后就会存在新高度, 但是[scrollHeight]属性并没有进行更新, 我们的图片因网速而异, 网络快可能没什么问题, 但是在网络慢的时候可能就不行了, 我们是依靠图片来撑高盒子的, 所以最后滚动可能出现了问题; #### 5. better-scroll的滚动bug解决: 1) 监听每一张图片图片是否加载完成, 每当有一张图片加载完成了, 我就执行一次refresh(), 重新计算高度; 2) 如何监听图片加载完成? 原生js监听图片: img.onload = function() {} vue内部已经封装好了, 如下: @load="方法" 3) 调用scroll的refresh(), 但是现在问题又来了, 我们在GoodsItem组件中调不到Home组件的东西, 如果非要这样做的话就只能GoodsItem >>> Goods >>> Home 太繁琐了, 所以呢我们在这里引入一个新概念[事件总线]; ### 四、事件总线 #### 1. 事件总线实现大概思路? 1) 在vue组件中直接通过this.$bus.$emit("事件名")发射一个事件; 2) 在另一个组件中如果想要接收这个事件的话使用 this.$bus.$on("事件名", function() {}); 来处理这个事件; 3) 其实如果你用过mqtt的话就应该知道, 这就相当于mqtt中的[发布]与[订阅], 同一个服务器上, 我先订阅一个topic[主题]A, 然后你往该topic[主题]A上发一个消息[Hello], 这时我就能收到你发的Hello消息了, 牛吧, 哈哈哈哈嗝~ 4) 不过要注意this.$bug默认是undefined哦~ 需要在Vue的原型prototype中添加一个$bus, 我们可以new 一个Vue实例赋值给$bus, 这样它就能够去发射事件与监听了, 如下: Vue.prototype.$bug = new Vue({}); ### 五、防抖/节流 [debounce/throttle] [防抖概念] 在规定的时间内执行的如果有多次事件触发, 只执行最后一次。 ### 六、tabControl的吸顶效果 #### 1. 获取到tabControl的offsetTop 1) 必须知道滚动了多少像素时, 才开始有吸顶效果; 2) 我们使用 this.$ref.tabControl.$el 获取组件的Dom元素, 然后在获取该Dom元素的offsetTop即可; #### 2. 如何实现呢? 1) 还是之前的图片问题, 网络太快时图片无法正常加载, 会导致计算错误的情况发生, 这里我们使用轮播图的是否加载完成事件来获取, 因为是父子组件, 我们直接使用this.$emit()发送自定义事件即可, 而且我们只是计算高度, 只要轮播图加载好了一张就可以了, 所以在父组件监听这个事件的时候使用.once修饰符, 让这个事件只触发一次。 2) 我们可以通过狸猫换太子的手法, 直接写两个tab-control, 一个在本周流行下面, 一个固定在购物街这个标题下面; 3) 统计好了之后, 我们在之前监听页面滚动事件的函数中再加一个判断, 当滚动距离大于tab-control距离顶部距离时, 让购物街下面固定的tab-control显示, 从而将原来的tab-control覆盖, 这就是帽子戏法。 4) 还有一个问题就是两个tab-control点击的选项可能会不同步, 我们直接在任意一个tab-control触发点击事件时同时改变两个组件内的currentIndex, 让其保持一致即可。 ### 七、让Home[首页]组件保持原来的状态 #### 1. 让Home不要随意的被销毁掉 1) keep-alive #### 2. 让Home内容保持原来的位置 2) 使用两个回调事件, activated 与 deactivated, 这两个回调事件只有在组件被keep-alive包裹的时候才能使用, 一个为组件活跃时[显示]调用, 一个为组件不活跃时[隐藏]调用, 我们可以在该组件不活跃时获取scroll的Y轴滚动高度, 然后再活跃时设置滚动即可实现该功能。 ### 八、详情页 #### 1. 各种商品组件封装 #### 2. 数据类封装导出供详情页展示数据使用 1) 在杂乱无章的数据中将自己需要展示的数据提取出来, 封装至一个类中, 也相当于组件化抽取, 可以直接看到自己需要的参数名称等信息; 2) 在子组件内进行操作的时候需要注意数据是否已经加载进来了[props], 最好在根元素上添加一个v-if进行判断。 3) 商品店铺、详情、参数、评论信息封装。 ### 九、如何将服务器返回的时间戳转换为字符串(常用) #### 1. 将时间戳转成Date对象 1) const date = new Date(1537941077 * 1000); 如果返回了10位的时间戳[秒]就x1000, 如果是13位[毫秒]就不需要了。 #### 2. 封装一个格式化时间日期函数 ### 十、混入 mixin 1) 如果两个或以上的组件中存在一样的代码, 届时可以使用混入, 混入对象中也有生命周期函数与组件方法、计算属性等。 #### 1. 如何使用? 1) 创建混入对象: export conts mixin = {}; 2) vue组件内引入使用: mixins: [混入文件中对象], ### 十一、详情页剩余组件封装 #### 1. 联动效果 >>> 详情页nav-bar #### 2. 混入回到顶部图标 ### 十二、vuex管理购物车数据 #### 1. 增删改查 ### 十三、小细节补充 #### 1. fastClick能够解决300ms延时 1) npm安装: npm i fastclick --save 2) es6方式导入: import FastClick from 'fastclick'; 3) 调用attach方法使用: FastClick.attach(document.body); #### 2. vue-lazyload图片懒加载 >>> 用到时在加载 1) npm安装: npm i vue-lazyload -S 2) 导入: import VueLazyLoad from 'vue-lazyload'; 3) vue安装: Vue.use(VueLazyLoad); 4) 使用: 修改原始方式 src >>> v-lazy #### 3. 适配 移动端单位转换 postcsss.config.js 1) npm安装: npm install postcss-px-to-viewport --save-dev 2) 配置postcss.config.js文件即可 ``` // common.js 导出方式 module.exports = { plugins: { autoprefixer: {}, "postcss-px-to-viewport": { // 一般都是iphone6设计稿 750x1334 实际宽度 375x667 viewportWidth: 375, // 视窗的默认宽度, 对应我们设计稿的宽度 viewportHeight: 667, // 视窗的默认高度, 对应我们设计稿的高度 [也可以不配置] unitPrecision: 5, // 指定'px'转换为视窗单位值保留的小数位数 [很多时候无法整除] viewportUnit: 'vw', // 指定需要转换的视窗单位, px转vw, 也可以rem, 建议使用vw selectorBlackList: ['.ignore'], // 有这个类的元素, 它的单位不进行转换 minPixelValue: 1, // 最小转换单位值, 小于或等于'1px'不转换 mediaQuery: false, // 是否允许媒体查询 }, } } ``` ### 十四、nginx部署 [window/linux] #### 1. 下载 1) 官方网址: https://nginx.org 2) 版本说明: Mainline version : Mainline是Nginx目前主力在做的版本, 可以说是开发版; Stable version : 最新稳定版, 生产环境上建议使用的版本 Legacy version : 遗留的老版本的稳定版 3) 我们直接选择Stable version的最新稳定版本进行下载 #### 2. window 部署 1) 点击稳定window版的进行下载 [.zip] 2) 解压后, 点击nginx.exe执行文件, 在浏览器上输入 127.0.0.1 看到 welcome to nginx! 即为启动成功 3) 找到根目录下的 html/ 目录, 删除其文件, 将npm run build 打包好的dist/目录下的文件拷贝至该目录, 刷新浏览器即可 4) 修改配置, 直接将html的指向 改为dist/目录, 然后将dist文件夹扔到nginx根目录, 重启nginx服务即可 ``` location / { # root html; root dist; index index.html index.htm; } ``` 5) 几个nginx命令 立即停止, 不保存信息 ``` nginx -s stop ``` 正常退出, 保存信息 ``` nginx -s quit ``` 重启 [改变了配置时, 需要重启] ``` nginx -s reload ``` 6) 注!!! window部署时需要注意不要过多点击nginx.exe文件, 可能会打开多个nginx服务, 到时候使用命令时nginx可能找不到你要重启/停止哪一个?如果点击启动了多个, 可以去任务管理进行kill, 然后只打开一个就正常了。 #### 3. linux 部署 [ubuntu] 1) 安装: ``` sudo apt-get install nginx ``` 2) 查看版本 ``` nginx -v ``` 3) 配置nginx.conf ``` cd /etc/nginx vim nginx.conf http { server { listen 8001; server_name _; root /home/feng/chen/server/super_mall/dist; } } root >>> 配置你的打包好的dist文件目录的路径 ``` 4) 启动nginx服务 ``` systemctl start nginx.service ``` 5) 重启nginx服务 ``` systemctl restart nginx.service ``` 6) 关闭nginx服务 ``` systemctl stop nginx.service ``` # super_mall ## Project setup ``` npm install ``` ### Compiles and hot-reloads for development ``` npm run serve ``` ### Compiles and minifies for production ``` npm run build ``` ### Run your tests ``` npm run test ``` ### Lints and fixes files ``` npm run lint ``` ### Customize configuration See [Configuration Reference](https://cli.vuejs.org/config/).