文章目录
- 一安装Vue
- 二 做移动端应用注意
-
- 2.1 在index.html中修改mate设置
- 2.2 reset.css重新设置样式,在入口文件中引入
- 2.3 引入border.css 解决一像素边框的问题
- 2.4 解决click延迟300ms的问题 fastclick插件
- 2.5 在style中引入其他样式,需要这样 ~@
- 2.6 对全局事件的解绑
- 2.7 解决么面滑动影响其他页面的问题
- 3 插件使用
-
- 3.1 stylus和stylus-loader
- 3.2 轮播图组件 vue-awesome-swiper
-
- 3.2.1 使用vue代码
- 3.2.2 swiper自定义图片轮播组件
- 3.3 数据请求 axios
- 3.4 页面跳转路由
- 3.5 Better-scroll 滚动插件
- 3.6 Vuex实现数据共享
- 3.6 本地存储 localStorage
- 3.7 keep-alive优化网页性能
- 3.8 递归组件的使用
- 4 样例
-
- 4.1 头部渐隐渐现的效果组件
- 4.2 渐影渐现的动画组件
一安装Vue
//全局安装 vue-cli
npm install --global vue-cli
//创建一个基于 webpack 模板的新项目
vue init webpack my-project
//安装依赖
cd my-project
npm install
//运行
npm run dev
- 安装过程中的问题解决
- npm构建保存 code ELIFECYCLE解决办法
进入工作目录
rm -rf node_modules
rm -rf package-lock.json
npm cache clear --force
npm install
二 做移动端应用注意
2.1 在index.html中修改mate设置
<meta name="viewport" content="width=device-width,initial-scale=1.0,
minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
2.2 reset.css重新设置样式,在入口文件中引入
@charset "utf-8";html{background-color:#fff;color:#000;font-size:12px}
body,ul,ol,dl,dd,h1,h2,h3,h4,h5,h6,figure,form,fieldset,legend,input,textarea,button,p,blockquote,th,td,pre,xmp{margin:0;padding:0}
body,input,textarea,button,select,pre,xmp,tt,code,kbd,samp{line-height:1.5;font-family:tahoma,arial,"Hiragino Sans GB",simsun,sans-serif}
h1,h2,h3,h4,h5,h6,small,big,input,textarea,button,select{font-size:100%}
h1,h2,h3,h4,h5,h6{font-family:tahoma,arial,"Hiragino Sans GB","微软雅黑",simsun,sans-serif}
h1,h2,h3,h4,h5,h6,b,strong{font-weight:normal}
address,cite,dfn,em,i,optgroup,var{font-style:normal}
table{border-collapse:collapse;border-spacing:0;text-align:left}
caption,th{text-align:inherit}
ul,ol,menu{list-style:none}
fieldset,img{border:0}
img,object,input,textarea,button,select{vertical-align:middle}
article,aside,footer,header,section,nav,figure,figcaption,hgroup,details,menu{display:block}
audio,canvas,video{display:inline-block;*display:inline;*zoom:1}
blockquote:before,blockquote:after,q:before,q:after{content:"\0020"}
textarea{overflow:auto;resize:vertical}
input,textarea,button,select,a{outline:0 none;border: none;}
button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}
mark{background-color:transparent}
a,ins,s,u,del{text-decoration:none}
sup,sub{vertical-align:baseline}
html {overflow-x: hidden;height: 100%;font-size: 50px;-webkit-tap-highlight-color: transparent;}
body {font-family: Arial, "Microsoft Yahei", "Helvetica Neue", Helvetica, sans-serif;color: #333;font-size: .28em;line-height: 1;-webkit-text-size-adjust: none;}
hr {height: .02rem;margin: .1rem 0;border: medium none;border-top: .02rem solid #cacaca;}
a {color: #25a4bb;text-decoration: none;}
2.3 引入border.css 解决一像素边框的问题
在入口文件中引入
@charset "utf-8";
.border,
.border-top,
.border-right,
.border-bottom,
.border-left,
.border-topbottom,
.border-rightleft,
.border-topleft,
.border-rightbottom,
.border-topright,
.border-bottomleft {
position: relative;
}
.border::before,
.border-top::before,
.border-right::before,
.border-bottom::before,
.border-left::before,
.border-topbottom::before,
.border-topbottom::after,
.border-rightleft::before,
.border-rightleft::after,
.border-topleft::before,
.border-topleft::after,
.border-rightbottom::before,
.border-rightbottom::after,
.border-topright::before,
.border-topright::after,
.border-bottomleft::before,
.border-bottomleft::after {
content: "\0020";
overflow: hidden;
position: absolute;
}
/* border
* 因,边框是由伪元素区域遮盖在父级
* 故,子级若有交互,需要对子级设置
* 定位 及 z轴
*/
.border::before {
box-sizing: border-box;
top: 0;
left: 0;
height: 100%;
width: 100%;
border: 1px solid #eaeaea;
transform-origin: 0 0;
}
.border-top::before,
.border-bottom::before,
.border-topbottom::before,
.border-topbottom::after,
.border-topleft::before,
.border-rightbottom::after,
.border-topright::before,
.border-bottomleft::before {
left: 0;
width: 100%;
height: 1px;
}
.border-right::before,
.border-left::before,
.border-rightleft::before,
.border-rightleft::after,
.border-topleft::after,
.border-rightbottom::before,
.border-topright::after,
.border-bottomleft::after {
top: 0;
width: 1px;
height: 100%;
}
.border-top::before,
.border-topbottom::before,
.border-topleft::before,
.border-topright::before {
border-top: 1px solid #eaeaea;
transform-origin: 0 0;
}
.border-right::before,
.border-rightbottom::before,
.border-rightleft::before,
.border-topright::after {
border-right: 1px solid #eaeaea;
transform-origin: 100% 0;
}
.border-bottom::before,
.border-topbottom::after,
.border-rightbottom::after,
.border-bottomleft::before {
border-bottom: 1px solid #eaeaea;
transform-origin: 0 100%;
}
.border-left::before,
.border-topleft::after,
.border-rightleft::after,
.border-bottomleft::after {
border-left: 1px solid #eaeaea;
transform-origin: 0 0;
}
.border-top::before,
.border-topbottom::before,
.border-topleft::before,
.border-topright::before {
top: 0;
}
.border-right::before,
.border-rightleft::after,
.border-rightbottom::before,
.border-topright::after {
right: 0;
}
.border-bottom::before,
.border-topbottom::after,
.border-rightbottom::after,
.border-bottomleft::after {
bottom: 0;
}
.border-left::before,
.border-rightleft::before,
.border-topleft::after,
.border-bottomleft::before {
left: 0;
}
@media (max--moz-device-pixel-ratio: 1.49), (-webkit-max-device-pixel-ratio: 1.49), (max-device-pixel-ratio: 1.49), (max-resolution: 143dpi), (max-resolution: 1.49dppx) {
/* 默认值,无需重置 */
}
@media (min--moz-device-pixel-ratio: 1.5) and (max--moz-device-pixel-ratio: 2.49), (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 2.49), (min-device-pixel-ratio: 1.5) and (max-device-pixel-ratio: 2.49), (min-resolution: 144dpi) and (max-resolution: 239dpi), (min-resolution: 1.5dppx) and (max-resolution: 2.49dppx) {
.border::before {
width: 200%;
height: 200%;
transform: scale(.5);
}
.border-top::before,
.border-bottom::before,
.border-topbottom::before,
.border-topbottom::after,
.border-topleft::before,
.border-rightbottom::after,
.border-topright::before,
.border-bottomleft::before {
transform: scaleY(.5);
}
.border-right::before,
.border-left::before,
.border-rightleft::before,
.border-rightleft::after,
.border-topleft::after,
.border-rightbottom::before,
.border-topright::after,
.border-bottomleft::after {
transform: scaleX(.5);
}
}
@media (min--moz-device-pixel-ratio: 2.5), (-webkit-min-device-pixel-ratio: 2.5), (min-device-pixel-ratio: 2.5), (min-resolution: 240dpi), (min-resolution: 2.5dppx) {
.border::before {
width: 300%;
height: 300%;
transform: scale(.33333);
}
.border-top::before,
.border-bottom::before,
.border-topbottom::before,
.border-topbottom::after,
.border-topleft::before,
.border-rightbottom::after,
.border-topright::before,
.border-bottomleft::before {
transform: scaleY(.33333);
}
.border-right::before,
.border-left::before,
.border-rightleft::before,
.border-rightleft::after,
.border-topleft::after,
.border-rightbottom::before,
.border-topright::after,
.border-bottomleft::after {
transform: scaleX(.33333);
}
}
修改里面边框颜色的方法可以在样式中这样写
.border-topbottom
&:before
border-color #cccccc
&after
border-color #cccccc
.border-bottom
&:before
border-color #cccccc
2.4 解决click延迟300ms的问题 fastclick插件
引入fastclick
在项目目录下,在终端中写入 --save表示开发环境还是上线打包都需要,用–save
//表示将此插件安装到项目中
npm install fastclick --save
使用
在main.js中
//引入
import fastClick from 'fastclick'
//使用
fastClick.attach(document.body)
2.5 在style中引入其他样式,需要这样 ~@
@import '~@/assets/styles/varibles.styl';
2.6 对全局事件的解绑
//绑定,作用于全局,不用时一定要解绑
window.addEventListener('scroll', this.handleScroll)
//解绑
// 使用keep-alive后出现的方法,页面即将被影藏时会执行
deactivated() {
window.removeEventListener('scroll', this.handleScroll)
}
2.7 解决么面滑动影响其他页面的问题
在路由里面添加这句就解决了
// 解决页面滑动影响其他页面效果的问题
scrollBehavior (to, from, savedPosition) {
return {x:0 ,y:0}
}
3 插件使用
3.1 stylus和stylus-loader
可以快速帮助编写css代码
npm install stylus --save
3.2 轮播图组件 vue-awesome-swiper
官网地址:https://www.swiper.com.cn/
github地址:https://github.com/surmon-china/vue-awesome-swiper
安装:npm install [email protected] --save,使用2.6.7这个版本
//使用
import Vue from 'vue'
import VueAwesomeSwiper from 'vue-awesome-swiper'
// require styles
import 'swiper/dist/css/swiper.css'
Vue.use(VueAwesomeSwiper, /* { default global options } */)
3.2.1 使用vue代码
<template>
<div class="wrapper">
<swiper :options="swiperOption">
<!-- slides -->
<swiper-slide v-for="item of swiperList" :key="item.id" data-swiper-autoplay="1500">
<img class="swiper-img" :src="item.imgUrl">
</swiper-slide>
<div class="swiper-pagination" slot="pagination"></div>
</swiper>
</div>
</template>
<script>
export default {
name: 'HomeSwiper',
data () {
return {
swiperOption: {
pagination: '.swiper-pagination',
// 支持循环轮播
loop: true,
// 自动播放
autoplay: true
},
swiperList: [{
id: '0001',
imgUrl: 'http://img1.qunarzz.com/piao/fusion/1609/b5/43a1ba885cbdd802.jpg_750x200_d70aa046.jpg'
}, {
id: '0002',
imgUrl: 'http://img1.qunarzz.com/piao/fusion/1805/f2/503916bba911f502.jpg_750x200_b12d0184.jpg'
}, {
id: '0003',
imgUrl: 'http://img1.qunarzz.com/piao/fusion/1809/fc/5e4ea3c336a86b02.jpg_750x200_62bf515a.jpg'
}, {
id: '0004',
imgUrl: 'http://mp-piao-admincp.qunarzz.com/mp_piao_admin_mp_piao_admin/admin/20196/818f6cc784ae6669b74bbbb255414a53.jpg_750x200_66ca5873.jpg'
}, {
id: '0005',
imgUrl: 'http://mp-piao-admincp.qunarzz.com/mp_piao_admin_mp_piao_admin/admin/20193/87a224d0349d94a11e97f31aa1aba4f5.jpg_750x200_1f78af87.jpg'
}]
}
}
}
</script>
<style scoped>
// 样式进行穿透
.wrapper >>> .swiper-pagination-bullet-active
background #ffffff
.wrapper
overflow hidden
width 100%
height 0
padding-bottom 26.5%
background #cccccc
.swiper-img
width 100%
</style>
3.2.2 swiper自定义图片轮播组件
<template>
<div class="container" @click="handlerGallarlyClick">
<div class="wrapper">
<swiper :options="swiperOption">
<!-- slides -->
<swiper-slide v-for="(item, index) in imgs" :key="index">
<img class="gallarly-img" :src="item">
</swiper-slide>
<div class="swiper-pagination" slot="pagination"></div>
</swiper>
</div>
</div>
</template>
<script>
export default {
name: 'CommonGallary',
props: {
imgs: {
type: Array,
default () {
return []
}
}
},
data () {
return {
swiperOption: {
pagination: '.swiper-pagination',
paginationType: 'fraction',
// 组件有变化时,轮播会自动加载一遍
observer:true,
observeParents:true
}
}
},
methods: {
handlerGallarlyClick () {
this.$emit('close')
}
},
}
</script>
<style scoped>
.container >>> .swiper-container
overflow inherit
.container
display flex
flex-direction column
justify-content center
z-index 99
position fixed
left 0
right 0
top 0
bottom 0
background #000
.wrapper
width 100%
height 0
padding-bottom 100%
.gallarly-img
width 100%
.swiper-pagination
color #ffffff
bottom -1rem
</style>
3.3 数据请求 axios
1 安装
npm install axios --save
2 使用
//导入
import axios from 'axios'
//请求
axios.get('/api/index.json').then(this.getHomeInfoSucc)
//接收返回值的方法
getHomeInfoSucc (res) {
console.log(res)
}
3 注意 配置地址代理
在 config - index.js里面这么配置
// 代理配置
proxyTable: {
'/api': {
target: 'http://localhost:8080',
pathRewrite: {
// 将API 替换为 /static/mock
'^/api': '/static/mock'
}
}
},
3.4 页面跳转路由
1 路由配置
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/pages/home/Home'
import City from '@/pages/city/City'
Vue.use(Router)
// 导出去的内容 是一个路由
// 当用户访问根路径时,我给用户展示HelloWorld这个组件
export default new Router({
// 路由配置
routes: [
{
path: '/',
name: 'Home',
component: Home
}, {
path: '/city',
name: 'City',
component: City
}
]
})
2 路由跳转
<router-link to="/city">
<div class="header-right">
{{ this.city }}
<span class="iconfont arrow-icon"></span>
</div>
</router-link>
3 跳转 router
this.$router.push('/')
3.5 Better-scroll 滚动插件
github地址:https://github.com/ustbhuangyi/better-scroll
1 安装
npm install better-scroll --save
2 使用
//代码结构要符合要求
<div class="wrapper">
<ul class="content">
<li>...</li>
<li>...</li>
...
</ul>
<!-- you can put some other DOMs here, it won't affect the scrolling
</div>
样例代买
<template>
<div class="list" ref="wrapper">
<div>
<div class="area">
<div class="title border-topbottom">当前城市</div>
<div class="button-list">
<div class="button-wraper"><div class="button">北京</div></div>
</div>
</div>
<div class="area">
<div class="title border-topbottom">热门城市</div>
<div class="button-list">
<div class="button-wraper"><div class="button">北京</div></div>
<div class="button-wraper"><div class="button">北京</div></div>
<div class="button-wraper"><div class="button">北京</div></div>
<div class="button-wraper"><div class="button">北京</div></div>
<div class="button-wraper"><div class="button">北京</div></div>
</div>
</div>
<div class="area">
<div class="title border-topbottom">A</div>
<div class="item-list">
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
</div>
<div class="title border-topbottom">A</div>
<div class="item-list">
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
</div>
<div class="title border-topbottom">A</div>
<div class="item-list">
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
<div class="item border-bottom">阿拉尔</div>
</div>
</div>
</div>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
name: 'CityList',
mounted () {
this.scroll = new BScroll(this.$refs.wrapper)
}
}
</script>
<style scoped>
@import '~styles/varibles.styl';
.list
overflow hidden
position absolute
top 1.58rem
left 0
right 0
bottom 0
.border-topbottom
&:before
border-color #cccccc
&after
border-color #cccccc
.border-bottom
&:before
border-color #cccccc
.title
line-height .44rem
background #eee
padding-left .2rem
color #666
font-size .26rem
.button-list
overflow hidden
padding .1rem .6rem .1rem .1rem
.button-wraper
float left
width 33.33%
.button
margin .1rem .1rem
padding .1rem 0
text-align center
border .02rem solid #cccccc
border-radius .06rem
.item-list
.item
line-height .76rem
color #666
padding-left .2rem
</style>
3 滚动到某一个元素处
this.scroll.scrollToElement(element)
3.6 Vuex实现数据共享
官方推荐
安装:
npm install vuex --save
使用:
//1 创建store 存储值的文件index.js
import Vue from 'vue'
import Vuex from 'vuex'
// 使用插件
Vue.use(Vuex)
// 导出vuex 创建的仓库
export default new Vuex.Store({
state: {
city: '北京'
},
//这个可以被跳过,直接调用commit
actions: {
//接收修改值的请求
changeCity (ctx, city) {
// 执行mutations,来修改需要修改的值
ctx.commit('changeCity', city)
}
},
mutations: {
//修改值
changeCity (state, city) {
state.city = city
}
}
})
//2 在main.js中引入
import store from './store'
new Vue({
el: '#app',
//数据共享
store,
})
// 3 在用的地方直接调用
{{ this.$store.state.city }}
//4 改变里面值的方法,发送请求
handleCityClick (city) {
this.$store.dispatch('changeCity', city)
}
vuex映射值,简单使用
import { mapState } from 'vuex'
//将值映射到计算属性中
computed: {
// ... 展开属性
...mapState(['city'])
}
然后直接 this.city 就可以了
3.6 本地存储 localStorage
使用
//存值
localStorage.city = city
//取用
localStorage.city || '默认值'
3.7 keep-alive优化网页性能
//用这个包裹了以后,就会有缓存,不在重新加载数据,Detail组件不被缓存
<keep-alive exclude="Detail">
<!-- 显示的是当前路由地址所对应的内容 -->
<router-view/>
</keep-alive>
使用了 keep-alive后,会多出一个生命周期函数,可以用来做一些操作
// 使用了 keep-alive后,会多出一个生命周期函数,可以用来做一些操作
activated() {
},
3.8 递归组件的使用
数据
list: [{
title: '成人票',
children: [{
title: '成人三馆联票',
children: [{
title: '成人三馆联票-某一连锁店销售'
}]
}, {
title: '成人五馆联票'
}]
}, {
title: '学生票'
}, {
title: '儿童票'
}, {
title: '特惠票'
}]
组件的自身去调用组件自身
<template>
<div>
<router-link tag="div" to="/" class="header-abs" v-show="showAbs">
<div class="iconfont header-abs-back"></div>
</router-link>
<div
class="header-fixed"
v-show="!showAbs"
:style="opacityStyle"
>
景点详情
<router-link to="/"><div class="iconfont header-fixed-back"></div></router-link>
</div>
</div>
</template>
<script>
export default {
name: 'DetailHeader',
data () {
return {
showAbs: true,
opacityStyle: {
opacity: 0
}
}
},
methods: {
// 滚动监听事件
handleScroll () {
const top = document.documentElement.scrollTop
if (top > 60) {
let opacity = top / 140
opacity = opacity > 1 ? 1 : opacity
this.opacityStyle = { opacity }
this.showAbs = false
} else {
this.showAbs = true
}
}
},
activated () {
window.addEventListener('scroll', this.handleScroll)
},
// 使用keep-alive后出现的方法,页面即将被影藏时会执行
deactivated () {
window.removeEventListener('scroll', this.handleScroll)
}
}
</script>
<style scoped>
@import '~styles/varibles.styl';
.header-abs
position absolute
left .2rem
top .2rem
width .8rem
height .8rem
line-height .8rem
border-radius .4rem
text-align center
background rgba(0, 0, 0, .8)
.header-abs-back
color #ffffff
font-size .4rem
.header-fixed
z-index 2
position fixed
top 0
left 0
right 0
height $headerHeight
line-height $headerHeight
text-align center
color #ffffff
background $bgColor
font-size .32rem
.header-fixed-back
position absolute
top 0
left 0
width .64rem
text-align center
font-size .4rem
color #ffffff
</style>
4 样例
4.1 头部渐隐渐现的效果组件
<template>
<div>
<router-link tag="div" to="/" class="header-abs" v-show="showAbs">
<div class="iconfont header-abs-back"></div>
</router-link>
<div
class="header-fixed"
v-show="!showAbs"
:style="opacityStyle"
>
景点详情
<router-link to="/"><div class="iconfont header-fixed-back"></div></router-link>
</div>
</div>
</template>
<script>
export default {
name: 'DetailHeader',
data () {
return {
showAbs: true,
opacityStyle: {
opacity: 0
}
}
},
methods: {
// 滚动监听事件
handleScroll () {
const top = document.documentElement.scrollTop
if (top > 60) {
let opacity = top / 140
opacity = opacity > 1 ? 1 : opacity
this.opacityStyle = { opacity }
this.showAbs = false
} else {
this.showAbs = true
}
}
},
activated () {
window.addEventListener('scroll', this.handleScroll)
}
}
</script>
<style scoped>
@import '~styles/varibles.styl';
.header-abs
position absolute
left .2rem
top .2rem
width .8rem
height .8rem
line-height .8rem
border-radius .4rem
text-align center
background rgba(0, 0, 0, .8)
.header-abs-back
color #ffffff
font-size .4rem
.header-fixed
position fixed
top 0
left 0
right 0
height $headerHeight
line-height $headerHeight
text-align center
color #ffffff
background $bgColor
font-size .32rem
.header-fixed-back
position absolute
top 0
left 0
width .64rem
text-align center
font-size .4rem
color #ffffff
</style>
4.2 渐影渐现的动画组件
<template>
<transition>
<slot></slot>
</transition>
</template>
<script>
export default {
name: 'FadeAnimation'
}
</script>
<style scoped>
.v-enter, .v-leave-to
opacity 0
.v-enter-active, .v-leave-active
transition opacity .5s
</style>
使用
//在使用的地方用它包裹即可
<fade-animation>
<common-gallary
:imgs="bannerImgs"
v-show="showGallarly"
@close="handlerGallaryClose"
></common-gallary>
</fade-animation>