[TOC]
商城项目
划分目录
├─assets 资源
│ ├─css
│ └─img
├─common 用于存放公共的js文件(变量、方法等)
├─components 用于存放公共的组件
│ ├─common 能复用的组件
│ └─content 能复用但只和内容相关的组件
├─network 网络请求
├─router 路由
├─store 状态(Vuex)
└─views 主要的视图
├─category
└─home
配置别名
vue.config.js 用于配置一些自定义的配置
// vue.config.js
module.exports = {
configureWebpack: {
resolve: {
// 配置别名
alias: {
// @ 别名在默认配置中已经有了 @: 'src'
'assets': '@/assets',
'common': '@/common',
'components': '@/components',
'network': '@/network',
'store': '@/store',
'view': '@/view',
}
}
}
}
编码风格
.editorconfig 文件用于统一编码风格
root = true
[*]
charset = utf-8
# 缩进风格
indent_style = space
# 缩进的大小为 2 个空格
indent_size = 2
# 在行尾换行
end_of_line = lf
# 在最后插入一个新的行
insert_final_newline = true
# 清除无效的空格
trim_trailing_whitespace = true
引入 CSS
- 引入 normalize.css 用于统一浏览器样式和一些默认样式
- 引入 base.css 一些基本样式
最后在 App.vue 中导入 base.css
/* base.css */
@import "./normalize.css";
:root {
--color-text: #666;
--color-high-text: #ff5777;
--color-tint: #ff8197;
--color-background: #fff;
--font-size: 14px;
--line-height: 1.5;
}
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","MIcrosoft YaHei","微软雅黑",Arial,sans-serif;
user-select: none; /* 禁止用户鼠标在页面上选中文字/图片等 */
-webkit-tap-highlight-color: transparent; /* webkit 是苹果浏览器引擎,tap点击,highlight 背景高亮,color 颜色,颜色用数值调节 */
background: var(--color-background);
color: var(--color-text);
width: 100vw;
}
a {
color: var(--color-text);
text-decoration: none;
}
.clear-fix::after {
clear: both;
content: '';
display: block;
width: 0;
height: 0;
visibility: hidden;
}
.clear-fix {
zoom: 1;
}
.left {
float: left;
}
:right {
float: right;
}
模块划分
例如该案例用于展现内容的主要视图分为首页、分类、购物车、我的,tab-bar 为公共组件
// App.vue
<template>
<div id="app">
// 用于展示划分好的 view
<router-view></router-view>
// 公共的 tab-bar 组件
<main-tab-bar></main-tab-bar>
</div>
</template>
<script>
import MainTabBar from "components/content/mainTabbar/MainTabBar";
export default {
name: "App",
components: {
MainTabBar,
},
};
</script>
路由映射
配置主视图(views)的路由关系
import Vue from 'vue';
import VueRouter from 'vue-router';
// 懒加载
const Home = () => import('../views/home/Home')
const Category = () => import('../views/category/Category')
const Cart = () => import('../views/cart/Cart')
const Profile = () => import('../views/profile/Profile')
Vue.use(VueRouter)
const routes = [
{
path: '',
redirect: '/home'
},
{
path: '/home',
component: Home
},
{
path: '/category',
component: Category
},
{
path: '/cart',
component: Cart
},
{
path: '/profile',
component: Profile
},
]
const router = new VueRouter({
routes,
mode: 'history'
})
export default router
网络请求
将 home 相关的网络请求封装起来,这样就能将网页和网络请求分离
// home.js
import { request } from "./request"
export function getHomeMultidata() {
return request({
url: '/home/multidata'
})
}
使用
// Home.vue
import { getHomeMultidata } from "network/home.js";
created() {
// 1.请求多个数据
getHomeMultidata().then((res) => {
this.banners = res.data.data.banner.list;
this.recommends = res.data.data.recommend.list;
});
},
首页开发
- navbar 的封装
- 轮播图
- 推荐信息
- 网络数据的请求
- 封装 axios 实例 ```javascript // network/request.js import axios from ‘axios’;
export function request(config) { // 1.创建 axios 实例 const instance = axios.create({ baseURL: ‘http://123.207.32.32:8000‘, timeout: 50000 })
// 2.axios 拦截器 instance.interceptors.request.use(config => { return config }, err => { console.log(err); })
instance.interceptors.response.use(res => { return res }, err => { console.log(err); })
// 3.发送真正的网络请求 return instance(config) }
- 将首页相关的网络请求单独封装
```javascript
// network/home.js
import { request } from "./request"
export function getHomeMultidata() {
return request({
url: '/home/multidata'
})
}
- 将请求的数据保存下来
```vue
// Home.vue
- **本周流行和推荐** - **tab-control** - 数据请求 - 单击切换 - 吸顶效果 - 状态同步 - better-scroll 封装 - 上拉加载 - better-scroll 的滑动 bug 处理(事件总线)、 - 防抖 - 封装 back-top - 保持 home 的状态 - keep-alive - 保存当前滚动位置的Y值 - activated 时还原状态 <a name="9JUqI"></a> ## 商品详情 - 通过 iid 获取数据 - navBar 复用 - swiper 的复用 - baseInfo 的封装(使用 class 进行汇总) - shopInfo 的封装 - goodsInfo 的封闭 - 图片加载完只发送一次事件 - paramInfo - commontInfo - 格式化时间 - 图片加载完成问题(mixin) - 标题和内容的联动效果 - index - offsetTop ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2332117/1609729117658-13df7a59-1520-4675-8070-eae205a41892.png#align=left&display=inline&height=206&margin=%5Bobject%20Object%5D&name=image.png&originHeight=206&originWidth=385&size=71295&status=done&style=none&width=385) - 底部工具栏的封装 - 回到顶部的抽取(mixin) - 点击加入购物车(Vuex) - Vuex 代码的重构 - 显示成功加入购物车(Promise) - 将 actions 映射到 methods <a name="6Rpru"></a> ## 购物车 - 导航栏 - 将 getters 映射到 computed - 商品展示 - 封装 checkButton - 商品的选中和不选中(修改模型对象) - 底部工具栏 - 合计 - 选择数量 - 全选按钮 <a name="3afddf73"></a> ## 封装 toast - 插件式 - 在 main.js 中安装插件(原理是会执行插件中的 install 函数) - 在 toast 组件目录下新建 js 文件 - 导入 toast 组件 - .... <a name="hsONx"></a> ## fastClick 减少移动端 300ms 延时 安装 > npm install fastclick --save 使用 ```javascript // main.js