参考文档:mint UI ,swiper
- index.html 标签解释
<link rel="dns-prefetch" href="#"> DNS预解析,可以减少图片的解析时间。
- Vue 相关知识
- vue实例挂载点,不能是 body 或 html , 所以要加一层容器,包裹想要挂载的地方。
- 单vue文件,template 是必需的而且只能有一个根节点,style 可以有多个。
- Vue组件库:自行查找
Mint UI 对比 Element UI
首页
- Mint UI :基于 Vue.js 的移动端组件库
- 1. npm安装
$ npm i mint-ui -S
- 2. 引入 Mint UI
- 1. 完整引入
- 2. 按需引入
1.需要安装babel-plugin-component:
$ npm install babel-plugin-component -D
2.然后,将 .babelrc 修改为:
{
"presets": [
["es2015", { "modules": false }]
],
"plugins": [
// 主要是这部分 , 实际使用时,大括号外的中括号需去掉(代码复制于官网)
["component", [
{
"libraryName": "mint-ui",
"style": true
}
]]
// 到这部分
]
}
- 3. 选择想要引入的组件按指令操作即可。
- 触底加载更多数据———Infinite scroll:无限滚动指令
- 1. 引入
import { InfiniteScroll } from 'mint-ui';
Vue.use(InfiniteScroll);
- 2. 例子
为 HTML 元素添加 v-infinite-scroll 指令即可使用无限滚动。滚动该元素,
当其底部与被滚动元素底部的距离小于给定的阈值(通过 infinite-scroll-distance 设置)时,
绑定到 v-infinite-scroll 指令的方法就会被触发。
<ul
v-infinite-scroll="getLists" // 绑定到 v-infinite-scroll 指令的方法就会被触发
infinite-scroll-disabled="loading" // 若为真,则无限滚动不会被触发
infinite-scroll-distance="10"> // 触发加载方法的滚动距离阈值(像素)
<li v-for="item in list">{{ item }}</li>
</ul>
- 3. bug: 触发绑定的方法期间,若再次触发,则仍会触发该方法,这是不合理的。
设置loading值:在触发方法时先设置loading=true ,方法完成后设置loading=false
- 4. bug: 每次触发方法只刷新数据,原数据被覆盖,这不符合商品列表的期望。
得到当前的商品列表(curLists)时,判断商品列表(lists)是否为空:
空则直接赋值 this.lists = curLists
非空则使用数组拼接方法连接数据 this.lists = this.lists.concat(curLists)
- bottom-nav
- 1. 将 bottom-nav 单独拿出来,放在新建的 Foot.vue 中, 并且抽出对应的css 放入style中。
- 2. 点击底部按钮时,要完成两个任务
- 1. 点击按钮,切换页面,切换样式
- 1. 将四个按钮使用v-for渲染,let navConfig = [],存放四个按钮的 name,href,icon
- 2. 使用 index === curIndex 法渲染 active 效果。
发现:切换页面后,渲染的效果失效
方法: 切换页面时传递index参数: location.href = `${list.href}?index=${index}`
渲染界面时,解析href得到index:
let {index} = qs.parse(location.search.substr(1))
curIndex: parseInt(index) || 0
需要引入 qs ,解析 location 。
- swiper
将 swiper-container 拿出来,放在新建的 Swipe.vue 中
使用swiper组件:
- 1. 下载并安装swiper
$ npm install swiper
- 2. 分析:除首页需要轮播,商品详情页需要轮播,所以把轮播组件单独拿出来,
使用的时候只需要传递不同的数据(参数)即可。
- 3. 在 index.html 中引入 Swipe
- 1. 在 api.js 中加入 轮播图的路径: banner: '/index/banner'
- 2. 在 index.js 的 methods 中 写 getBanner 方法,并且放入 created 中
- 3. 在 index.js 中引入 Swipe.vue ,并放入 components 中
- 4. 在 index.html 中对应位置写<Swipe></Swipe>
- 4. 把数据传递给给组件,让组件进行渲染 ———— props(Vue-组件-prop 查看 props的数组形式、对象形式)
- 1. 在 Swipe.vue 中 写props对象形式(对象形式能进行 prop验证 )
对象形式:
props:{
lists:{
type: 指定输出类型
required: true时,必须符合 type 的类型
}
}
- 2. 当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。
注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的属性
(如 data、computed 等) 在 default 或 validator 函数中是不可用的。
- 5. 使用 Swiper 组件时,要遵守人家给出的页面格式:
<!-- Slider main container 滑块主容器 -->
<div class="swiper-container">
<!-- Additional required wrapper 附加所需包装器 -->
<div class="swiper-wrapper">
<!-- Slides 幻灯片 -->
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
...
</div>
<!-- If we need pagination 如果我们需要分页 -->
<div class="swiper-pagination"></div>
<!-- If we need navigation buttons 如果我们需要导航按钮 -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<!-- If we need scrollbar 如果我们需要滚动条 -->
<div class="swiper-scrollbar"></div>
</div>
所以按照此格式,在 index.html-Swpie 中补充 class ,加入分页器
- 6. v-for 列表渲染 swiper-slide , 并且动态绑定url、img
- 7. swiper是对dom节点进行操作的,dom节点什么时候生成?
生命周期:mounted
- 1. index.html 中
<Swipe :lists="bannerLists" v-if="bannerLists"></Swipe>
只有获得了数据,才会渲染
- 2. Swipe.vue 中 (此时不需要限制 lists 的类型)
对数据进行监听
created() {
// console.log('created: ',document.querySelectorAll(".swiper-slide"));
},
mounted() {
// console.log('mounted: ',document.querySelectorAll(".swiper-slide"));
},
watch: {
lists(value, oldValue) {
console.log('value, oldValue: ',value, oldValue);
console.log('before nextTick: ',document.querySelectorAll(".swiper-slide"));
this.$nextTick(() => {
console.log('after nextTick: ',document.querySelectorAll(".swiper-slide"));
});
}
}
结果:
created: NodeList []
mounted: NodeList []
value, oldValue: (3) [{…}, {…}, {…}, __ob__: Observer] null
before nextTick: NodeList []
after nextTick:
NodeList(3) [div.swp-page.swiper-slide, div.swp-page.swiper-slide, div.swp-page.swiper-slide]
注意:项目中选择了 1 方法,以下代码都是按照 1 方法进行。
- 8. 引入 Swiper ,并引入 Swiper 的样式:
import Swiper from 'swiper'
import 'swiper/dist/css/swiper.css'
- 9. 配置Swiper(参考官方文档)
在mounted中:
var mySwiper = new Swiper(".swiper-container", {
direction: "horizontal", // 水平方向轮播
loop: true, // 设置为true以启用连续循环模式
pagination: { // 分页器
el: ".swiper-pagination"
},
autoplay: { // 自动轮播,延迟5s
delay: 5000
}
});
分类页
- 基础处理
- 1. 将 category.html category.css 放入新建的 pages/category 文件夹,
并创建 category.js ,引入响应的css,引入Vue、axios、Foot、url 。
并将 category.html 中Foot对应的部分删除,切换为 <Foot></Foot>
用div(id=app) 包裹整个页面,用来挂载vue实例
- 2. 找到右边商品列表的容器:class="main-content",在对应的css上写 overflow-y: scroll;
overflow:定义当一个元素的内容太大而无法适应 块级格式化上下文 时候该做什么
是 overflow-x、overflow-y 的简写
属性:
- 1. visible:默认值。内容不会被修剪,可以呈现在元素框之外。
- 2. hidden:如果需要,内容将被剪裁以适合填充框。 不提供滚动条。
- 3. scroll:如果需要,内容将被剪裁以适合填充框,浏览器一直显示滚动条
- 4. auto:取决于用户代理。如果内容适合填充框内部,则它看起来与可见内容相同,
但仍会建立新的块格式化上下文。 如果内容溢出,桌面浏览器会提供滚动条。
注意:
- 1. 除visible外的值均会创建一个新的快格式化上下文。
- 2. 为使 overflow 有效果,块级容器必须有一个指定的高度(height或者max-height)
或者将white-space设置为nowrap。
- 3. 设置一个轴为visible(默认值),同时设置另一个轴为不同的值,会导致设置visible
的轴的行为会变成auto。
- 4. 即使将 overflow 设置为 hidden ,也可以使用JavaScript Element.scrollTop
属性来滚动HTML元素。
- 页面分析
- 1. 侧边的一级分类的数据也是获得的,
data-cid="xx" 是什么意思?
- 获得 一级分类 的数据并渲染
- 1. 在 api.js 中 url写入:topList: '/category/topList'
- 2. 在 category.js 中 创建vue实例,并绑定在 div(app) 上,
data 中声明 topLists: null
- 3. methods 中写 getTopList(){axios.get(url.topList).then(res => {this.topLists = res.data.lists})}
并在 created 中 调用该方法 created() { this.getTopList() }
- 4. 在 category.html 中
找到一级分类,在 li 上使用v-for进行列表渲染 v-for="(list,index) in topLists"
此处有两个问题:
1. 点击不同的li,渲染不同的标签(实际上只有综合排行为一种,剩下的分类为一种)
- 1. category.html 中
在 <li> 上绑定事件 @click="getSubList(index,list.id)"
在综合排行对应的div上写 v-show="topIndex===0" (后更改为v-if)
在其余分类对应的div上写 v-show="topIndex>0" (后更改为v-if)
- 2. category.js 中
data:{ topIndex: 0 // 此处按照下标进行区分,综合排行为0,其余均大于0 }
methods: { getSubList(index,id) { this.topIndex = index} }
2. 点击不同的li,切换 class"active"(焦点状态切换问题)
- 1. 在<li>上添加 :class="{active:index===topIndex}"
由 getSubList() 方法可知,点击哪个li就会使得topIndex等于被点击li的index
当点击 li 时,就会使得条件成立,渲染clas"active"
此时其余的未被点击的 li 的index是不等于topIndex的
所以就实现了切换 active 的需求。
- 获得 二级分类(综合排行、普通分类) 的数据并渲染
- 1. 在 api.js 中 url写入:
subList:'/category/subList',
rank:'/category/rank',
- 2. 在 category.js 中 创建vue实例,并绑定在 div(app) 上,
data 中声明 topLists: null
- 3. methods 中写 getTopList(){axios.get(url.topList).then(res => {this.topLists = res.data.lists})}
并在 created 中 调用该方法 created() { this.getTopList() }
- 4. 在 category.html 中
找到对应的 li 使用 v-for 进行渲染,并对数据进行替换
- 5. 问题:subData、rankData 初始值为null,再页面刚打开时就渲染会报错。
办法:在对应的 ul 上写 v-if="subData" 或者 v-if="rankData"
当获取数据后,才渲染。
- 6. 将价格变为带两位小数的浮点数:
使用filter,结合toFixed()方法即可。
- 问题补充:null 和 undefined
列表页
- sku
- 为什么data要return数据:在单vue页面下,多个组件可能会共享数据,为了保持数据的独有性,就把数据return出去。
- qs: querything 是一个增加了一些安全性的查询字符串解析和序列化字符串的库。
qs.parse()
- 点击热门品牌、热门分类下的 item ,会跳转到 search.html ,且传递点击 tiem 的 id 和 name
location.href = `search.html?keyword=${list.name}&cate_id=${list.id}`
- search 中
search.js 中
- 1. getSearchList(){} 发请求获取searchLIst
- 2. let { keyword, id } = qs.parse(location.search.substr(1)) 接收 keyword,id
search.html 中
- 1. input中接收keyword:`:value="keyword"`
- 2. 对应 li 上v-for 渲染数据。
- 发现:foot组件复用,formatePrice 方法复用,所以引入 mixin.js
- 1. src/modules/js/mixin.js 中
import Foot from '@/components/Foot.vue'
let mixin = {
filters: {
formatePrice(value) {
return value.toFixed(2)
}
},
components: {
Foot
}
}
export default mixin
将引入 foot 、formatePrice 方法均放入 mixin.js 中
- 2. 在需要引入 mixin.js 的文件中
import mixin from 'js/mixin.js'
new Vue({
···
mixins:[mixin]
···
})
- 回到顶部
使用第三方库:velocity
过渡
- 过渡的概念
- 在哪些场景使用过渡
- 怎么用
- 涉及到的知识点
- 组件的封装
- slot--组件
- 组件的通讯
- 父子
- 兄弟
- vuex
- slot
- fullpage
- 静态数据:mounted
- 异步数据:this.$nextTick
详情页
- 入口、数据获取和渲染
- 商品详情和本店成交
- 选择规格弹框:过渡效果、数据增减
- 加入购物车:购物车按钮显示、信息提示
知识点:
- v-cloak
- v-html
- 过渡效果