# Class 与 Style 绑定
# 绑定 Class
# 对象语法
我们可以传给 v-bind:class
一个对象,以动态地切换 class
<div v-bind:class="{ active: isActive }"></div>
上面的active
类名,而isActive
是一个变量,它有布尔特性
什么布尔特性?
''
隐式解析为false0
隐式解析为falsenull
隐式解析为falsefalse
undefined
隐式解析为falseNaN
隐式解析为false- 比较运算也产生布尔值
综合例子
<style>
button.active{
color: red;
}
</style>
<div id="root">
<button
v-for="p in 5"
v-bind:class="{active:p==page}"
v-on:click="goPage(p)"
>{{p}}</button>
</div>
<script>
var root = new Vue({
el:'#root',
data: {
page: 3
},
methods:{
goPage(p){
this.page = p;
}
}
})
</script>
综合例子2
<style>
div.box{
width: 220px;
height: 500px;
background-color: #000;
transition: all .3s ease-in;
}
div.box.active{
width: 0;
transition: all .3s ease-out;
}
button{
position: fixed;
right: 20px;
top: 20px;
}
</style>
<div id="root">
<div class="box" :class="{active:opened}"></div>
<button v-on:click="opened = !opened">切换导航</button>
</div>
<script>
var root = new Vue({
el:'#root',
data: {
opened: false
}
})
</script>
# 绑定 Style 样式
# 对象语法
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
综合例子
<div id="root">
<h4 :style="h4Style">标题</h4>
<input type="number" v-model="size">
<select v-model="font">
<option value="">请选择</option>
<option value="华文行楷">华文行楷</option>
<option value="方正舒体">方正舒体</option>
</select>
</div>
<script>
var root = new Vue({
el:'#root',
data: {
font: '',
size: 24
},
computed: {
h4Style(){
return {fontSize: this.size+'px',fontFamily: this.font};
}
}
})
</script>
拖拽效果演示
<style>
.box{
position: fixed;
background-color: red;
}
</style>
<div id="root">
<div
class="box"
:style="boxStyle"
@mousedown = "drag"
></div>
</div>
<script>
var root = new Vue({
el:'#root',
data: {
width: 100,
height: 100,
left: 20,
top: 20
},
computed: {
boxStyle(){
return {
width: this.width+'px',
height: this.height+'px',
left: this.left+'px',
top: this.top+'px'
}
}
},
methods:{
drag(e){
var startX = e.clientX;
var startY = e.clientY;
var left = this.left;
var top = this.top;
var maxLeft = window.innerWidth - this.width;
var maxTop = window.innerHeight - this.height;
document.onmousemove = function(e){
e.preventDefault();
var distX = left + (e.clientX - startX);
var distY = top + (e.clientY - startY);
if(distX<=0)distX=0;
if(distY<=0)distY=0;
if(distX>=maxLeft)distX=maxLeft;
if(distY>=maxTop)distY=maxTop;
this.left = distX;
this.top = distY;
}.bind(this);
document.onmouseup = function(){
document.onmousemove = null;
document.onmouseup = null;
}
}
}
})
</script>
滑块效果演示
<style>
.range{
position: relative;
background-color: #ccc;
overflow: hidden;
}
.range i,
.range b{
display: block;
}
.range b{
height: 100%;
background-color: green;
}
.range i{
position: absolute;
height: 100%;
background-color: black;
}
</style>
<div id="root">
<div class="range" :style="rangeStyle">
<i :style="iStyle" @mousedown="drag"></i>
<b :style="bStyle"></b>
</div>
</div>
<script src="js/vue.js"></script>
<script>
var root = new Vue({
el:'#root',
data: {
radius: false,
rWidth: 800,
rHeight: 100,
iWidth: 100,
left: 0
},
computed: {
rangeStyle(){
return {
borderRadius: this.radius && (this.rHeight/2 + 'px'),
width: this.rWidth+'px',
height: this.rHeight+'px',
}
},
iStyle(){
return {
borderRadius: this.radius && '50%',
width: this.iWidth+'px',
left: this.left+'px'
}
},
bStyle(){
return {
width: this.left+(this.iWidth/2)+'px'
}
}
},
methods:{
drag(e){
var startX = e.clientX;
var left = this.left;
var maxLeft = this.rWidth - this.iWidth;
document.onmousemove = function(e){
var _left = left + (e.clientX - startX);
if(_left<=0)_left=0;
if(_left>=maxLeft)_left=maxLeft;
this.left = _left;
}.bind(this)
document.onmouseup = function(){
document.onmousemove = null;
document.onmouseup = null;
}
}
}
})
</script>
# 条件渲染
<div id="root">
<h2 v-if="visible">标题2</h2>
<button @click="visible = !visible">显隐</button>
</div>
<script>
var root = new Vue({
el:'#root',
data:{
visible: false
}
})
</script>
# v-if 和 v-show的区别
v-if
会重建节点,它是惰性的,也就是说如果条件为假,那么它什么也不做,不会渲染节点。
v-show
无论条件真或假,它都会渲染节点。
一般来说,v-if
性能开销大一点,v-show
性能开销少一些。
<div id="root">
<h2 v-if="visible">标题v-if</h2>
<h2 v-show="visible">标题v-show</h2>
<button @click="visible = !visible">显隐</button>
</div>
<script>
var root = new Vue({
el:'#root',
data:{
visible: false
}
})
</script>
# v-else 否则
否则语句,注意不需要条件
v-else
元素必须紧跟在带v-if
或者v-else-if
的元素的后面,否则它将不会被识别。
# v-else-if 否则如果
否则如果
类似于
v-else
,v-else-if
也必须紧跟在带v-if
或者v-else-if
的元素之后。
# template 标签在条件语句中的应用
template
标签不会被浏览器解析出来,它在v-if
和v-for
中很实用。
<div id="root">
<template v-if="num==0">
<h2>标题1</h2>
<p>段落1</p>
</template>
<template v-if="num==1">
<h2>标题2</h2>
<p>段落2</p>
</template>
</div>
<script>
var root = new Vue({
el:'#root',
data:{
num: 0
}
})
</script>
# key 特性
Vue
会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做使 Vue
变得非常快。
但这样也不总是符合实际需求,所以 Vue
为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们,那就是定义key
。
<div id="root">
<button @click="type='email'">邮箱</button>
<button @click="type='mobile'">手机</button> <br><br>
<div v-if="type=='email'">
<label>邮箱登录</label>
<input type="text" placeholder="请输入邮箱" key="emial">
</div>
<div v-if="type=='mobile'">
<label>手机登录</label>
<input type="text" placeholder="请输入手机" key="mobile">
</div>
</div>
<script>
var root = new Vue({
el:'#root',
data:{
type: 'email'
}
})
</script>
# 循环语句
# 循环数字
循环从1开始计数,注意不支持小数步进
<div id="root">
<button v-for="p in 5">{{p}}</button>
</div>
<script>
var root = new Vue({
el:'#root'
})
</script>
# 循环数组
<div id="root">
<ul>
<li v-for="item in ['苹果','香蕉']">{{item}}</li>
</ul>
</div>
<script>
var root = new Vue({
el:'#root'
})
</script>
上面的代码让模板变得过重,难于阅读,应该把数组提取到data中去
<div id="root">
<ul>
<li v-for="item in shuiguo">{{item}}</li>
</ul>
</div>
<script>
var root = new Vue({
el:'#root',
data: {
shuiguo: ['苹果','香蕉']
}
})
</script>
# 如何拿到数组的索引值
<div id="root">
<ul>
<li v-for="item,index in shuiguo">
{{index}} - {{item}}
</li>
</ul>
</div>
<script>
var root = new Vue({
el:'#root',
data: {
shuiguo: ['苹果','香蕉']
}
})
</script>
一个非常典型的循环数据示例
<div id="root">
<ul>
<li v-for="item in navs">
<a :href="item.url">{{item.title}}</a>
</li>
</ul>
</div>
<script>
var root = new Vue({
el:'#root',
data: {
navs: [
{ id:1, title:'首页', url: 'index.html'},
{ id:2, title:'关于我们', url: 'about.html'},
{ id:3, title:'联系我们', url: 'contact.html'}
]
}
})
</script>
# 循环对象
<div id="root">
<p v-for="val,key,index in person">
{{index}} - {{key}} - {{val}}
</p>
</div>
<script>
var root = new Vue({
el:'#root',
data: {
person: {
name: '李四',
age: 33,
habby: '骑行'
}
}
})
</script>
# template在循环中的应用
<div id="root">
<template v-for="item in person">
<h2>{{item.name}}</h2>
<p>
年龄:{{item.age}}<br>
爱好:{{item.habby}}
</p>
</template>
</div>
<script>
var root = new Vue({
el:'#root',
data: {
person: [
{
name: '张三',
age: 28,
habby: '唱歌'
},
{
name: '李四',
age: 33,
habby: '骑行'
}
]
}
})
</script>
# 数组更新检测
# 数组变异的方法有那些
push
尾部追加,返回数组长度。unshift
开头追加,返回数组长度。pop
删除尾部成员,返回被删除的成员。shift
删除头部成员,返回被删除的成员。sort
排序,返回排序后的数组。splice
集增删改
数组管理reverse
反转,返回改变后的数组。
# 数组非变异的方法有那些
concat
连接数组,返回新数组。slice
切割数组,切割出新数组。map
映射数组,映射出新数组。filter
筛选数组,筛选出新数组。
# 事件处理
<div id="root">
<button v-on:click="count++">❤ {{count}}</button>
</div>
<script>
var root = new Vue({
el:'#root',
data:{
count: 1
}
})
</script>
# html5本地存储
# 应用场景
- 购物车
- 浏览记录
- 记住密码或者用户名
- 保存登录令牌
token
- 离线缓存数据
# sessionStorage 会话存储
指页面打开的时候数据都在,一旦页面关闭,数据清除。
# sessionStorage.setItem 设置存储
sessionStorage.setItem('存储名','存储值');
# sessionStorage.getItem 获取已经存储的值
sessionStorage.getItem('存储名');
# sessionStorage.removeItem 移除已经存储的值
sessionStorage.removeItem('存储名');
# sessionStorage.clear 清空所有的值
sessionStorage.clear();
# localStorage 会话存储
本地永久存储,也就是说除非你人为手动去清除,一般它都在。
# localStorage.setItem 设置存储
localStorage.setItem('存储名','存储值');
# localStorage.getItem 获取已经存储的值
localStorage.getItem('存储名');
# localStorage.removeItem 移除已经存储的值
localStorage.removeItem('存储名');
# localStorage.clear 清空所有的值
localStorage.clear();
综合示例
<div id="root">
<button @click="add()">添加</button>
<button @click="clear()">清空</button>
<ul>
<li v-for="item,index in list">
{{item.name}} ---- {{item.age}} <button @click="del(index)">移除</button>
</li>
</ul>
</div>
<script>
var list = localStorage.getItem('list');
var root = new Vue({
el:'#root',
data:{
list: list ? JSON.parse(list):[]
},
methods:{
add(){
var name = prompt('请输入商品!');
var age = prompt('请输入价格!');
this.list.push({name,age});
},
del(index){
// alert(index)
this.list.splice(index,1);
},
clear(){
this.list = [];
}
},
updated(){
//注意如果是对象的话,要转成字符串,不然会出问题
var str = JSON.stringify( this.list );
localStorage.setItem('list', str );
}
})
</script>
# 事件修饰符
# once 只触发一次
<div id="root">
<button v-on:click.once="danji">按钮</button>
</div>
<script>
var root = new Vue({
el:'#root',
methods:{
danji(){
alert('只能弹出一次哦!');
}
}
})
</script>
# capture 使用捕获模式
<div id="root">
<button @click.capture="dj1">
<b @click="dj2">按钮</b>
</button>
</div>
<script>
var root = new Vue({
el:'#root',
methods:{
dj1(){
console.log('btn');
},
dj2(){
console.log('b');
}
}
})
</script>
# self 只在当前元素触发
<div id="root">
<button >
<b @click.self="dj1">按钮</b>
</button>
</div>
<script>
var root = new Vue({
el:'#root',
methods:{
dj1(){
console.log('btn');
}
}
})
</script>
# 按键修饰符
enter
:回车键tab
:换行键
<div id="root">
<input type="text" ref="msg" @keyup.enter="submit">
</div>
<script>
var clipboard = new Clipboard('#btn');
var root = new Vue({
el:'#root',
methods:{
submit(){
this.$refs.msg.select();
}
}
})
</script>
← 插槽 Vue单页面应用(SPA)开发 →