1创建项目
2 引入 flexible.js 完成自适应(+rem)
(function flexible (window, document) {
var docEl = document.documentElement
var dpr = window.devicePixelRatio || 1
// adjust body font size
function setBodyFontSize () {
if (document.body) {
document.body.style.fontSize = (12 * dpr) + 'px'
}
else {
document.addEventListener('DOMContentLoaded', setBodyFontSize)
}
}
setBodyFontSize();
// set 1rem = viewWidth / 10
function setRemUnit () {
var rem = docEl.clientWidth / 10
docEl.style.fontSize = rem + 'px'
}
setRemUnit()
// reset rem unit on page resize
window.addEventListener('resize', setRemUnit)
window.addEventListener('pageshow', function (e) {
if (e.persisted) {
setRemUnit()
}
})
// detect 0.5px supports
if (dpr >= 2) {
var fakeBody = document.createElement('body')
var testElement = document.createElement('div')
testElement.style.border = '.5px solid transparent'
fakeBody.appendChild(testElement)
docEl.appendChild(fakeBody)
if (testElement.offsetHeight === 1) {
docEl.classList.add('hairlines')
}
docEl.removeChild(fakeBody)
}
}(window, document))
3 配置路由
4 tabBar
手写
高亮的显示:给当前的添加class
<img
:src="$route.path.includes(item.path) ? item.selected : item.active" alt=""/>
<span :class="$route.path.includes(item.path) ? 'active' : ''">{{item.title}}</span>
5配置@ 和代理
在vue.config.js:
let path = require('path')
module.exports = {
//代理
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
pathRewrite: {
'^/api': '/api'
}
}
}
},
configureWebpack: config => {
config.resolve = {
extensions: ['.js', '.json', '.vue'],
alias: {
'@': path.resolve(__dirname, './src')
}
}
}
}
6 头部搜索拆取出来
6.
6.1 引入iconfont
在main.js当中引入
6.2 布局
头部不动,使用固定定位
6.3 点击搜索,跳转
ly-tab 插件
头部topbar切换插件
1 下载插件
npm install ly-tab -S
2 引入插件
import LyTab from 'ly-tab'
Vue.use(LyTab)
3 使用
6.4 swiper
抽取组件,home进行引入
1 下载
npm install vue-awesome-swiper@3.1.3 -S
2
<swiper :options="swiperOption" ref="mySwiper" @someSwiperEvent="callback"> <!-- slides --> <swiper-slide>I'm Slide 1</swiper-slide> <swiper-slide>I'm Slide 2</swiper-slide> <swiper-slide>I'm Slide 3</swiper-slide> <swiper-slide>I'm Slide 4</swiper-slide> <swiper-slide>I'm Slide 5</swiper-slide> <swiper-slide>I'm Slide 6</swiper-slide> <swiper-slide>I'm Slide 7</swiper-slide> <!-- Optional controls --> <div class="swiper-pagination" slot="pagination"></div> <div class="swiper-button-prev" slot="button-prev"></div> <div class="swiper-button-next" slot="button-next"></div> <div class="swiper-scrollbar" slot="scrollbar"></div> </swiper>3
import 'swiper/dist/css/swiper.css' import { swiper, swiperSlide } from 'vue-awesome-swiper' export default { components: { swiper, swiperSlide }, data() { return { swiperOption: { autoplay: 3000, speed:1000 pagination: { el: '.swiper-pagination' } }, swiperSlides: [1, 2, 3, 4, 5] } },}
swiper.vue:
<template>
<div class="swiper-main">
<swiper :options="swiperOption">
<swiper-slide v-for="(item, index) in swiperList"
:key="index">
<img :src="item.imgUrl"
alt="" />
</swiper-slide>
</swiper>
<div class="swiper-pagination"></div>
</div>
</template>
<script>
import 'swiper/dist/css/swiper.css'
import { swiper, swiperSlide } from 'vue-awesome-swiper'
export default {
name: 'Swiper',
props: {
swiperList: Array
},
data() {
return {
swiperOption: {
//swiper3
autoplay: 3000,
speed: 1000,
pagination: {
el: '.swiper-pagination'
}
}
}
},
components: {
swiper,
swiperSlide
}
}
</script>
<style scoped>
.swiper-main {
position: relative;
width: 100%;
height: 4.4rem;
}
.swiper-container {
width: 100%;
height: 4.4rem;
}
.swiper-main img {
width: 100%;
height: 4.4rem;
}
.swiper-pagination {
width: 100%;
bottom: 0px;
}
::v-deep .swiper-pagination-bullet-active {
background-color: #b0352f;
}
::v-deep .swiper-pagination-bullet {
margin: 0 0.08rem;
}
</style>
6.5 icon
Icons组件:
6.6 火爆推荐
好多页面有标题,使用插槽
6.7 如何进行切换:
类型不同,展示不同的数据, 同时数据中包含类别,可以知道展示不展示轮播图等
没有使用二级路由, 少写一堆页面
6.8 better-scroll 滚动插件
修改定位
使用插件
1 下载插件
npm install better-scroll -S
2 引入配置
import BetterScroll from 'better-scroll'
let bs = new BetterScroll('.wrapper', {
movable: true,
zoom: true
})
子元素高度比父元素高度要高,必须添加在mounted中
vue中的ref : 获取dom
设置:<div ref='aaa'></div>
获取:this.$refs.aaa
不使用created, 使用mounted,mounted已经加载了盒子,可以拿到div
当dom都加载完毕了,再执行这个插件
当dom更新完在加载?
this.$nextTick(()=>{
})
7 搜索页面
拆分3部分
输入搜索的内容, 点击搜索按钮,进入 产品列表:产品列表和搜索列表是同级,再拆分一下
{
path: "/search",
name: "Search",
children:[
{
path: "/",
name: "index",
component: () =>
import("../views/search/Search-index.vue"),
},
{
path: "list",
name: "list",
component: () =>
import("../views/search/Search-list.vue"),
}
],
7.1 本地存储
需求: 搜索一个东西, 按回车或者点击搜索按钮,会跳转到产品页面, 同时新增历史记录
搜索一个东西,要放在本地存储当中
1注意 输入的东西是空的,不存
2 如果输入的没有就存储进去,如果有:去重,并放在第一个
搜索页面:
产品页面:
2 有无历史记录
3 删除历史记录
加一个弹框
mint-ui
1 下载
npm install mint-ui -S
2 引入
import MintUI from 'mint-ui'
import 'mint-ui/lib/style.css'
Vue.use(MintUI)
4 搜索跳转到列表页面, 头部的搜索应该携带内容
8 axios的二次封装
import { Indicator } from 'mint-ui';
import axios from 'axios'
import store from '@/store'
import router from '@/router'
export default{
common:{
method:'GET',
data:{},
params:{},
headers:{}
},
$axios( options={} ){
options.method = options.method || this.common.method;
options.data = options.data || this.common.data;
options.params = options.params || this.common.params;
options.headers = options.headers || this.common.headers;
//请求前==》显示加载中...
Indicator.open('加载中...');
//是否是登录状态
if( options.headers.token ){
options.headers.token = store.state.user.token;
if( !options.headers.token ){
router.push('/login');
}
}
return axios(options).then(v=>{
let data = v.data.data;
//如果token过期,重新登录
if( data.code == 1000 ){
Indicator.close();
return router.push('/login');
}
return new Promise((res,rej)=>{
if( !v ) return rej();
//结束===》关闭加载中
setTimeout(()=>{
Indicator.close();
},500)
res( data );
})
})
}
}
8 懒加载
修改图片 v-lazy
9分类
1 分左右两个部分, 用flex布局
高亮 定义一个active
2 数据
左侧一级 右次:二级+三级