# vue2商城
**Repository Path**: hfuuwy/vue2-mall
## Basic Information
- **Project Name**: vue2商城
- **Description**: 移动端商城项目
项目基于Vue2全家桶,技术栈包括,移动端布局,axios,promise,vue-router
VueX状态管理,fastclick等等
- **Primary Language**: JavaScript
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2023-07-30
- **Last Updated**: 2023-09-12
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 项目启动
首先克隆: git clone https://gitee.com/hfuuwy/vue2-mall.git
下载项目所需依赖:npm install
运行项目:npm run serve
# 项目打包
npm run build
# 项目简要
# 1、划分目录结构
assets->css,img (共用的样式和图片,normalize.css重置样式)
components->content,common (项目组件)
network -> 网络接口 (request 封装api)
router -> 路由
store -> 状态管理(actions,getters,mutations-type,mutations,state)
utils -> 工具类(utils,mixin,const)
Views -> 视图(组件视图)
# 2、引入css文件
这里只解释 伪类 和 变量
:root {
--color-text: #666;
--color-high-text: #ff5777;
--color-tint: #ff8198;
--color-background: #fff;
--font-size: 14px;
--line-height: 1.5;
}
使用方法:
例子1:: color: var(--color-text)
例子2:: background: var(--color-background)
# 3、vue.config.js 和 editorconfig
配置别名:vue.config.js 可以进行默认合并
configureWebpack: {
resolve: {
alias: {
"assets": '@/assets',
"common": '@/common',
"components": '@/components',
"views": '@/views',
"network": '@/network',
}
}
}
editorconfig 编码风格统一
# 4、导入组件已经抽取的tabbar
回顾:
Promise:
基本使用:异步操作如何放入到Promise中
resolve/reject => .then/.catch
Promise 的链式调用 直接return Promise.resolve("")
也可以直接抛出异常
Promise.All() 可以直接保存信息
# 5、slot 插槽
- 普通插槽
- 直接在插槽中间写
- 具名插槽
- 添加 name 属性
- 插槽的作用域
- 父的访问父的,子的访问子的
- 在父组件访问子组件的 slot 时,可以让子组件的 slot 绑定一个属性名,在父组件调用子组件时添加 template 模块并绑定 v-slot 属性随后 slot.属性名就可以调用
- 内容相差很大的时候使用插槽,只是文字类型的简单类型可以不适用插槽
- history
1. history.go(Number) 前进或后退
2. history.pushState({}, '', 'url') 推
3. history.replaceState({}, '', 'url') 替换
4. history.back() 后退一次
5. history.forward() 前进一次
# 6、router 的配置
- `routes: [ { path: '/about', component: About'}, {path: '', redirect: '/home'}]`
- `redirect`:重定向路由的位置
- VueRouter 实例的属性/方法
- 路由默认使用的是 hash 路由在配置里面添加 `mode: 'history'` 就可以切换路由的方式
- 设置`linkActiveClass: 'name'` 统一设置 active 中的按钮样式,不用一直写 `active-class`(可以代替 router-link 的属性)
- `$router` 可以操作路由的状态 类型 H5 的`history` 如: push replace
- `$route` 谁在 active 状态就能获取到对应的 router 可以获取路由的值 params search state
- query 绑定
```
this.$router.push/replace.({
path:'/data',
query:{
id
}})
```
- 动态绑定
```
在路由组件:
rotes: [{
path: '/detail/:id',
component: Detail
}]
```
- `用户`
- ``: 该标签是一个 vue-router 中已经内置的组件, 它会被渲染成一个``标签.
- `to` 跳转路由的参数
- `tag` 设置标签如 button li 等 不再只是单一个 a 标签
- `replace` 替换,不会留下 history 记录,不可以回退
- `router-link-active` 自带类名属性设置样式(可以被 VueRouter 实例的方法代替) -- `router-link-exact-active` 自带的另一个类名
- 不想要过长的类名可以使用`active-class='name'`来修改类名属性的名字
- 路由的嵌套
- 在需要嵌套的主路由下添加 children:[]方法 子路由直接写名称即可前面不需要加 /
router 会自动添加 然后去对应的主路由组件上添加 子路由的 跳转 还需``要`` 让它显示(站)出来
- ``: 该标签会根据当前的路径, 动态渲染出不同的组件.网页的其他内容, 比如顶部的标题/导航, 或者底部的一些版权信息等会和``处于同一个等级.
在路由切换时, 切换的是``挂载的组件, 其他内容不会发生改变.
- 路由懒加载
1. Webpack 结合 Vue 异步组件: `const Home = resolve => { equire.ensure(['../components/Home.vue'], () => { resolve(require('../components/Home.vue')) })};`
2. AMD 写法: `const About = resolve => require(['../components/About.vue'], resolve);`
3. ES6 组织 Vue 异步组件: `const Home = () => import('../components/Home.vue')`
- 路由的参数传递: `query/params` 传递参数的两种方式
- URL: 协议://主机:端口号/路径?查询
- scheme://host:port/path?query#fragment
- `params` 配置路由的格式 /router/:id 传递方式:path 后面跟上对应的值 形成的路径: /router/Lys
- `query` 配置路由的格式 /router/{} 传递方式:对象中使用 query 的 key 作为传递方式 形成的路径: /router?id=Lys&age=18
- `$route/$router`的区别:
- 同为 VueRouter 实例的方法:`$router` 路由跳传方法 参数的设置 `$route` active 中的路由状态
- 所有的组件继承于 Vue 类的原型
- router 的导航守卫
- router.beforeEach((to, from, next) => {}) : 全局守卫,路由更新完成前调用
- router.afterEach((to, from) => {}) : 全局守卫,路由更新完成后调用
- keep-alive 保存组件的状态而不是切换路由后直接销毁
- `activated` 状态 active 时调用的 Vue 实例的方法 `deactivated`状态:notActive
- 这两个函数,只有该组件被保持了状态使用了 keep-alive 时,才有效的
- 别名的配置 路径太长
```
webpack
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'@': resolve('src'),
'components': resolve('src/components'),
'assets': resolve('src/assets'),
'views': resolve("src/views")
}
}
```
# 7、VueX
- 状态管理: 1. 创建一个公共对像保存到 Vue.prototype 中此时所有的组件都可以访问一个公共的对象实现资料的分享,但不是响应式的
- npm install vuex --save 下载插件依赖
- Vue -> Mutations -> State : 同步任务
- Vue -> Actions -> Mutations -> State : 异步任务
- store -> mutations 定以方法 -> 组件的调用 `this.$store.commit('increment');`
- State 单一状态树(数据源) (single Source of Truth)
- 保持只有一个 sot
- getters 得到某一些数据 |数据 | |方法 | | 根标签 |
- getters 里的方法: fn(store, getters, rootState) {} 第一个参数是 store(状态) 第二个参数是 getters 本身 第三个参数 rootState(根元素/标签)
- 如需要接收 store,getters 以外的参数需要 return 一个 function 以此来接收第三个参数
- 直接导入到组件的计算属性不用使用$sotre.getters 来获取 需要导入 : import {mapGetters} from 'vuex'
- mutations: 改变 State 数据必须通过 mutations 来操作 只能处理同步任务,异步任务需要用 Actions 来调用 mutations
name(state(Vuex 状态), payload(传来的数据))
- 调用的方式: `this.$store.commit(INCREMENT)`
- type(state) -> 事件类型 () {fn} -> 回调函数 ::--> 事件类型:fnName (state) {fn}:回调函数
- 传递第二个参数用逗号分割 组件调用自己的方法来调用 mutations 的方法 addCount(count) {this.$store.commit('incrementCount', count) }
- 提交风格:
- 普通风格: this.$store.commit('incrementCount', count) }
- 特殊风格: 添加 type 属性 this.$store.commit({type: 'incrementCount', // 类型 count}) mutations 的接收需要用到 payload
- 本来存储并设置的属性是可以做到响应式的,但后来添加进去的没有响应式的效果 如果后来添加的也需要响应式的效果,可以用 Vue.set() 删除的响应式可以使用 Vue.dalete()
- 方法的名字创建一个文件来定以常量,再用常量的名字替换原来的名字(保证有约束)
- Actions 处理异步任务,mutation 只能完成同步任务
name(context(上下文), payload(传来的数据))
- 调用方法: `this.$store.dispatch(INCREMENT)`
- 特殊提交/异步方法的对象方式需要用到 payload 接收参数
- 被组件调用,可以返回一个 Promise 对象给组件操作.then 谁调用 Promise 就返回给谁
- context : 调用此方法处理完成异步任务进入同步任务 context.commit('data')
- context 方法: commit dispatch getters rootGetters rootState state
- modules 模块分发
- 定以模块分割功能: state actions getters mutations
- 最后会合并到 state 状态里面 获取的方法: `$store.state.modules:name.name`
- modules 模块的提交也是直接`this.$store.commit("Name", "data')`和 state 的提交一样
- vuex 可以将方法映射到组件中 import {mapGetters, mapActions} from 'vuex'
# 8、axios 网络请求
- API 接口: http://123.207.32.32:7888/api/hy66
- axios.get/post(url, {})
* axios.all([]) 并发请求
* Vue 项目的准备工作
1. 划分目录的结构
2. 引用两个 CSS 文件
3. 配置相关文件如 路径的别名: { vue.config.js -> configureWebpack:{ alias:{} (配置别名) }(覆盖配置文件) } - .editorconfig
4. 项目模块划分: TabBar -> router 的映射关系
* 导航栏的封装
- {左(60px)中右(60px)}ling-height: 44px
* 网络模块
- 一个页面的网络请求封装对应的 network 再用这 network 访问 network(顶层封装) 相当于多了一个中间层方便管理
* Home 组件
- created() 当组件创建完成后发送 axios(网络请求) 通过.then 提取数据 (因为顶层封装的 axios 返回的是一个 Promise)
-
* BScroll
- 图片异步加载导致高度不对问题:使用 scroll.refresh() 重新计算高度
- 原生 JS: img.onload() 图片加载完成
- Vue: @load=''
* Vue 事件总线
- 祖孙通信 使用 bus 事件总线
- 在 Vue 的原型上添加$bus
- 在事件总线里面发送一个方法 然后可以接受一个事件
- Vue.prototype.$bus = new Vue()
- this.$bus.$emit('Load')
- this.$bus.$on('Load')
- $emit 和 $on 来收取数据
* 防抖的函数
- 多次调用 只让最后一个函数生效 防止频繁刷新操作
- debounce函数
* 真实数据抽取:
- result(信息) -> itemInfo(商品信息) -> topImages(轮播图片)
* 判断是否时空对象
- Object.key(obj).length
* 组件中有的一个属性取出两个名,可以使用 computed:计算属性 || :return this.goodsItem.image || this.goodsItem.show.img
* mixin 混入 和组件的生命周期合并
* Toast 弹窗 吐司
* fastclick 移动端 300ms 延迟
* 解决移动端点击的300ms延迟
* 图片赖加载
- vue-lazyload
- 安装
- 引入
- Vue.use(VueLazyLoad)注册
- src="" -> v-lazy="""
- 第二个参数: loading(占位图->图片没有完成加载时显示)等等