vue指令
vue指令, 实质上就是特殊的 html 标签属性, 特点: v- 开头
每个 v- 开头的指令, 都有着自己独立的功能, 将来vue解析时, 会根据不同的指令提供不同的功能
# v-bind指令
- 描述:插值表达式不能用在html的属性上,如果想要动态的设置html元素的属性,需要使用v-bind指令
- 作用:动态的设置html的属性
- 语法:
v-bind:title="msg"
- 简写:
:title="msg"
<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>
# v-on指令
# 基本使用
语法: 1. v-on:事件名=“要执行的少量代码" 2. v-on:事件名=“methods中的函数名" 3. v-on:事件名=“methods中的函数名(实参)"
最基本的语法
<button v-on:事件名="事件函数">按钮</button>
,需要在methods中提供事件处理函数
<button v-on:click="fn">搬砖</button> <button v-on:click="fn1">卖房</button> // 提供方法 methods: { fn () { console.log('你好啊') // console.log(this) this.money++ }, fn1 () { this.money += 10000 }, }
需要传递参数
<button v-on:事件名="事件函数(参数)">按钮</button>
,需要在methods中提供事件函数,接受参数
<button v-on:click="addMoney(1)">搬砖</button> <button v-on:click="addMoney(10000)">卖房</button> methods: { addMoney (money) { this.money += money } }
如果事件的逻辑足够简单,可以不提供函数
<button v-on:click="money++">搬砖</button>
<button v-on:click="money += 10000">卖房</button>
# vue中获取事件对象(了解)
需求: 默认a标签点击会跳走, 希望阻止默认的跳转, 阻止默认行为 e.preventDefault()
vue中获取事件对象
(1) 没有传参, 通过形参接收 e
(2) 传参了, 通过$event指代事件对象 e
<template>
<div id="app">
<a @click="fn" href="http://www.baidu.com">去百度</a>
<a @click="fn2(100, $event)" href="http://www.baidu.com">去百度2</a>
</div>
</template>
<script>
export default {
methods: {
fn(e) {
e.preventDefault()
},
fn2(num, e) {
e.preventDefault()
}
}
}
</script>
# v-on 事件修饰符
vue中提供的事件修饰符
.prevent 阻止默认行为
.stop 阻止冒泡
<div id="app">
<a @click.prevent="fn" href="http://www.baidu.com">去百度</a>
</div>
# 按键修饰符
需求: 用户输入内容, 回车, 打印输入的内容
在监听键盘事件时,我们经常需要判断详细的按键。此时,可以为键盘相关的事件添加按键修饰符
@keyup.enter 回车
@keyup.esc 返回
<div id="app">
<input type="text" @keyup="fn"> <hr>
<input type="text" @keyup.enter="fn2">
</div>
# v-if 和 v-show
# 基本使用
v-show 和 v-if 功能: 控制盒子的显示隐藏
v-show
语法: v-show="布尔值" (true显示, false隐藏)
原理: 实质是在控制元素的 css 样式,
display: none;
v-if
语法: v-if="布尔值" (true显示, false隐藏)
原理: 实质是在动态的创建 或者 删除元素节点
应用场景:
如果是频繁的切换显示隐藏, 用 v-show
v-if, 频繁切换会大量的创建和删除元素, 消耗性能
如果是不用频繁切换, 要么显示, 要么隐藏的情况, 适合于用 v-if
v-if 是惰性的, 如果初始值为 false, 那么这些元素就直接不创建了, 节省一些初始渲染开销
<template>
<div id="app">
<h1 v-show="isShow">v-show盒子-{{ msg }}</h1>
<h1 v-if="isShow">v-if盒子-{{ msg }}</h1>
</div>
</template>
# v-else 和 v-else-if
<div id="app">
<h1 v-if="isLogin">尊敬的超级vip, 你好</h1>
<h1 v-else>你谁呀, 赶紧登陆~</h1>
<hr>
<h1 v-if="age >= 60">60岁以上, 广场舞</h1>
<h1 v-else-if="age >= 30">30岁以上, 搓麻将</h1>
<h1 v-else-if="age >= 20">20岁以上, 蹦迪</h1>
<h1 v-else>20岁以下, 唱跳rap篮球</h1>
</div>
# 案例-折叠面板
需求: 点击展开或收起时,把内容区域显示或者隐藏
静态结构:
<template>
<div id="app">
<h3>案例:折叠面板</h3>
<div class="box">
<div class="title">
<h4>芙蓉楼送辛渐</h4>
<!-- 按钮位置 -->
<span class="btn">
收起
</span>
</div>
<!-- 切换显示隐藏的部分 -->
<div class="container">
<p>寒雨连江夜入吴,</p>
<p>平明送客楚山孤。</p>
<p>洛阳亲友如相问,</p>
<p>一片冰心在玉壶。</p>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
}
}
}
</script>
<style lang="less">
body {
background-color: #ccc;
#app {
width: 400px;
height: 320px;
margin: 20px auto;
background-color: #fff;
border: 4px solid blueviolet;
border-radius: 1em;
box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.5);
padding: 1em 2em 2em;
h3 {
text-align: center;
}
.box {
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.5);
border-radius: 4px;
border: 1px solid #ebeef5;
background-color: #fff;
overflow: hidden;
color: #303133;
transition: .3s;
}
.title {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 20px;
}
.title h4 {
line-height: 2;
margin: 0;
}
.container {
padding: 0 20px;
border-top: 1px solid #ccc;
}
.btn {
/* 鼠标改成手的形状 */
cursor: pointer;
}
}
}
</style>
完整代码:
<template>
<div id="app">
<h3>案例:折叠面板</h3>
<div class="box">
<div class="title">
<h4>芙蓉楼送辛渐</h4>
<!-- 按钮位置 -->
<span class="btn" @click="isShow = !isShow">
{{ isShow ? '收起' : '展开' }}
</span>
</div>
<!-- 切换显示隐藏的部分 (数据驱动) -->
<div v-show="isShow" class="container">
<p>寒雨连江夜入吴,</p>
<p>平明送客楚山孤。</p>
<p>洛阳亲友如相问,</p>
<p>一片冰心在玉壶。</p>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isShow: true
}
}
}
</script>
<style lang="less">
body {
background-color: #ccc;
#app {
width: 400px;
height: 320px;
margin: 20px auto;
background-color: #fff;
border: 4px solid blueviolet;
border-radius: 1em;
box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.5);
padding: 1em 2em 2em;
h3 {
text-align: center;
}
.box {
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.5);
border-radius: 4px;
border: 1px solid #ebeef5;
background-color: #fff;
overflow: hidden;
color: #303133;
transition: .3s;
}
.title {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 20px;
}
.title h4 {
line-height: 2;
margin: 0;
}
.container {
padding: 0 20px;
border-top: 1px solid #ccc;
}
.btn {
/* 鼠标改成手的形状 */
cursor: pointer;
}
}
}
</style>
# v-model
# 基本使用
**作用: 给表单元素使用, 双向数据绑定 **
数据变化了, 视图会跟着变
视图变化了, 数据要跟着变
输入框内容变化了(监听用户的输入, 监听input事件), 数据要跟着变
语法: v-model='值'
<input type="text" v-model="msg">
# v-model 处理其他表单元素
v-model 会忽略掉表单元素原本的value, checked等初始值
textarea, select, checkbox
# v-model 修饰符
number
如果想自动将用户的输入值, 用parseFloat转成数字类型, ,可以给
v-model
添加number
修饰符:<input v-model.number="age" type="number">
如果这个值如果这个值无法转数字,则会返回原始的值。
trim
如果要自动过滤用户输入的首尾空白字符,可以给
v-model
添加trim
修饰符:<input v-model.trim="msg">
lazy
在
change
时而非input
时更新,可以给v-model
添加lazy
修饰符:<input v-model.lazy="msg">
# v-text 和 v-html
# v-text指令
- 解释:更新元素的
textContent/innerText
。如果要更新部分的textContent
,需要使用插值。
<h1 v-text="msg"></h1>
# v-html指令
- 解释:更新DOM对象的
innerHTML
,html标签会生效
<h1 v-html="msg"></h1>
在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击 (opens new window)。
只在可信内容上使用 v-html
,永不用在用户提交的内容上。
# v-for
# 基本使用
v-for 作用: 遍历对象和数组
- 遍历数组 (常用)
v-for="item in 数组名" item每一项
v-for="(item, index) in 数组名" item每一项 index下标
注意:item和index不是定死的,可以是任意的名字,但是需要注意 第一项是值 第二项是下标
- 遍历对象 (一般不用)
<!--
v-for也可以遍历对象(不常用)
v-for="(值, 键) in 对象"
-->
<ul>
<li v-for="value in user" :key="value">{{value}}</li>
</ul>
<ul>
<li v-for="(value, key) in user" :key="key">{{value}} ---{{key}}</li>
</ul>
- 遍历数字
<!--
遍历数字
语法: v-for="(item, index) in 数字"
作用:遍历具体的次数 item从1开始 index下标从0开始的
-->
<ul>
<li v-for="(item, index) in 10" :key="item">{{item}} ---{{index}}</li>
</ul>
# 虚拟DOM 和 diff算法
**vue就地复用策略:**Vue会尽可能的就地(同层级,同位置),对比虚拟dom,复用旧dom结构,进行差异化更新。
虚拟dom: 本质就是一个个保存节点信息, 属性和内容的 描述真实dom的 JS 对象
diff算法:
策略1:
先同层级根元素比较,如果根元素变化,那么不考虑复用,整个dom树删除重建
先同层级根元素比较,如果根元素不变,对比出属性的变化更新,并考虑往下递归复用。
策略2:
对比同级兄弟元素时,默认按照下标进行对比复用。
对比同级兄弟元素时,如果指定了 key,就会 按照相同 key 的元素 来进行对比。
# v-for 的key的说明
设置 和 不设置 key 有什么区别?
- 不设置 key, 默认同级兄弟元素按照下标进行比较。
- 设置了key,按照相同key的新旧元素比较。
key值要求是?
- 字符串或者数值,唯一不重复
- 有 id 用 id, 有唯一值用唯一值,实在都没有,才用索引
key的好处?
key的作用:提高虚拟DOM的对比复用性能
以后:只要是写到列表渲染,都推荐加上 key 属性。且 key 推荐是设置成 id, 实在没有,就设置成 index
# 样式处理
# v-bind 对于class的增强
v-bind 对于类名操作的增强, 注意点, :class 不会影响到原来的 class 属性
:class="对象/数组"
<template>
<div>
<!--
v-bind: 作用:设置动态属性
v-bind针对 class和style 进行增强
允许使用对象或者数组
对象:如果键值对的值为true,那么就有这个,否则没有这个类
数组:数组中所有的类都会添加到盒子上
-->
<!-- <div class="box" :class="isRed ? 'red': ''">123</div> -->
<!-- <div class="box" :class="{red: isRed, pink: isPink}">123</div> -->
<div class="box" :class="arr">123</div>
</div>
</template>
# v-bind对于style 的增强
<template>
<div>
<!--
:style也可以使用对象或者数组
-->
<div class="box" :style="[styleObj1, styleObj2]">123</div>
</div>
</template>