目录
一、vue基础语法
插值表达式
在dom标签中, 直接插入内容(声明式渲染/文本插值 )
语法:
{{ 表达式 }}
二、vue指令
给标签属性设置vue变量的值
1.v-bind
动态绑定属性:任何属性(标准属性 和 自定义属性都是可以!)
语法:
v-bind:属性名=“
vue变量”
简写:
:属性名=“
vue变量”
样式绑定:
:class 类名操作 v-bind:class
:style 行内样式操作 v-bind:style
1.1动态class
用v-bind给标签class设置动态的值
语法:
:class="{类名: 布尔值}"
给标签class属性动态赋值:
:class=“{类名: 布尔值}”, true使用, false不用
<template>
<div>
<p :class="{red_str: bool}">动态class</p>
</div>
</template>
<script>
export default {
data(){
return {
bool: true
}
}
}
</script>
<style scoped>
.red_str{
color: red;
}
</style>
1.2动态style
给标签动态设置style的值
语法:
:style="{css属性: 值}"
注: 动态style的key都是css属性名
<template>
<div>
<p :style="{backgroundColor: colorStr}">动态style</p>
</div>
</template>
<script>
export default {
data(){
return {
colorStr: 'red'
}
}
}
</script>
<style>
</style>
2.v-on绑定事件
2.1 语法:
v-on:事件名="要执行的少量代码"
v-on:事件名="methods中的函数"
v-on:事件名="methods中的函数(实参)"
2.2 简写:
@事件名="methods中的函数"
2.3 获取事件对象语法:
无传参, 通过形参直接接收
传参, 通过$event指代事件对象传给事件处理函数
<template>
<div>
<a @click="one" href="http://www.baidu.com">百度</a>
<hr />
<a @click="two(10, $event)" href="http://www.taobao.com">淘宝</a>
</div>
</template>
<script>
export default {
methods: {
// 1. 事件触发, 无传值, 可以直接获取事件对象是
one(e){
e.preventDefault()
},
// 2. 事件触发, 传值, 需要手动传入$event
two(num, e){
e.preventDefault()
}
}
};
</script>
<style>
</style>
2.4 修饰符
语法:
@事件名.修饰符="methods里函数"
修饰符:
.stop | 阻止事件冒泡 |
.prevent | 阻止默认行为 |
.once | 程序运行期间, 只触发一次事件处理函数 |
<template>
<div>
<div @click="fatherFn">
<p @click.stop="oneFn">阻止事件冒泡</p>
<a href="http://www.baidu.com" @click.prevent.stop>去百度</a>
<p @click.once="twoFn">点击观察事件处理函数执行几次</p>
</div>
</div>
</template>
2.5 按键修饰符
语法:
@键盘事件.按键修饰符="methods里的函数名"
修饰符:
.enter 只有按下回车才能触发这个键盘事件函数
.esc 只有按下取消键才能触发这个键盘事件函数
3.v-model:双向绑定
只能用在表单标签上: 把Vue的数据变量和表单的value属性双向绑定在一起
双向指两个方向
- 第一个方向:数据层 data ---------------->视图层 view!
- 第二个方向:数据层 data <----------------视图层 view!
<template>
<div>
<div>
<span>用户名:</span>
<input type="text" v-model="username">
</div>
<div>
<span>密码: </span>
<input type="password" v-model="pass">
</div>
</div>
</template>
<script>
export default {
data(){
return {
username: "",
pass: ""
}
}
}
</script>
<style>
</style>
3.1 绑定不同表单标签
Vue变量初始值会影响表单的默认状态 (双向数据绑定,互相影响 )
下拉菜单v-model写在 select上,value写在option上
<select v-model="from">
<option value="北京市">北京</option>
<option value="南京市">南京</option>
<option value="天津市">天津</option>
</select>
v-model用在复选框时,v-model的vue变量是:
-
非数组 :关联的是checked属性
-
数组 :关联的是value属性
<span>爱好: </span>
<input type="checkbox" v-model="hobby" value="游戏">游戏
<input type="checkbox" v-model="hobby" value="美食">美食
<input type="checkbox" v-model="hobby" value="旅行">旅行
<div>
<span>性别: </span>
<input type="radio" value="男" name="sex" v-model="gender">男
<input type="radio" value="女" name="sex" v-model="gender">女
</div>
3.2 修饰符
语法:
v-model.修饰符="vue数据变量"
修饰符:
.number | 以parseFloat转成数字类型 |
.trim | 去除首尾空白字符 |
.lazy | 在change时触发而非inupt时 |
4.v-text和v-html
DOM对象的innerText/innerHTML
语法:
v-text="vue数据变量"
v-html="vue数据变量"
注意: 会覆盖插值表达式
5.v-show和v-if的使用
控制标签的隐藏或出现
语法:
v-show="vue变量"
v-if="vue变量"
- v-show: display属性,显示隐藏,dom存在!
- v-if: 创建和删除dom
- 页面中:频繁出现隐藏显示,推荐使用v-show!
- v-if: ( if 控制分支语句)
v-else使用
<template>
<div>
<h1 v-show="isShow">我是h1</h1>
<h2 v-if="isOk">我是h2</h2>
<!-- v-if和v-else使用 -->
<p v-if="age >= 18">成年了</p>
<p v-else>未成年</p>
</div>
</template>
<script>
export default {
data(){
return {
isShow: false,
isOk: false,
age: 2
}
}
}
</script>
<style>
</style>
v-指令="初始化data内属性" 还可以写简单表达式 score > 600 , 三元表达式 && ||
表达式:能得到值,都是表达式
<input type="text" v-model="score">
//score:700
<div v-if="score>600">A类</div>
<div v-else-if="score>500">B类</div>
<div v-else>C类</div>
6.v-for
遍历数据:数据对象;
要把哪个HTML结构重复很多次,就把v-for写在该标签内部!
v-for="(值, 索引) in 目标结构"
v-for="值 in 目标结构"
6.1 更新监测
当v-for遍历的目标结构改变, Vue触发v-for的更新
- 数组变更方法, 就会导致v-for更新, 页面更新
- 数组非变更方法, 返回新数组, 就不会导致v-for更新, 可采用覆盖数组或 this.$set( )
这些方法会触发数组改变, v-for会监测到并更新页面
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
这些方法不会触发v-for更新
slice()
filter()
concat()
6.2 更新DOM就地更新
v-for
的默认行为会尝试原地修改元素而不是移动它们。
循环出新的虚拟DOM结构, 和旧的虚拟DOM结构对比, 尝试复用标签就地更新内容
三、虚拟DOM
.vue文件中的template里写的标签, 都是模板, 都要被vue处理成虚拟DOM对象, 才会渲染显示到真实DOM页面上
内存中生成一样的虚拟DOM结构( 本质是个JS对象 )
因为真实的DOM属性好几百个, 没办法快速的知道哪个属性改变了
比如template里标签结构
<template>
<div id="box">
<p class="my_p">123</p>
</div>
</template>
对应的虚拟DOM结构
const dom = {
type: 'div',
attributes: [{id: 'box'}],
children: {
type: 'p',
attributes: [{class: 'my_p'}],
text: '123'
}
}
1.vue数据更新
生成新的虚拟DOM结构 和旧的虚拟DOM结构对比
利用diff算法, 找不不同, 只更新变化的部分(重绘/回流)到页面 - 也叫打补丁
2.diff算法
2.1 根元素变了, 删除重建
旧虚拟DOM
<div id="box">
<p class="my_p">123</p>
</div>
新虚拟DOM
<ul id="box">
<li class="my_p">123</li>
</ul>
2.2 根元素没变, 属性改变, 元素复用, 更新属性
旧虚拟DOM
<div id="box">
<p class="my_p">123</p>
</div>
新虚拟DOM
<div id="myBox" title="标题">
<p class="my_p">123</p>
</div>
3.diff算法-key
根元素没变, 子元素没变, 元素内容改变
key值 唯一不重复的字符串或者数值
-
无key, 就地更新
-
有key, 按照key比较
有id用id, 无id用索引
1.无key - 就地更新
v-for不会移动DOM, 而是尝试复用, 就地更新,如果需要v-for移动DOM, 你需要用特殊 attribute key
来提供一个排序提示
<ul id="myUL">
<li v-for="str in arr">
{{ str }}
<input type="text">
</li>
</ul>
<button @click="addFn">下标为1的位置新增一个</button>
export default {
data(){
return {
arr: ["老大", "新来的", "老二", "老三"]
}
},
methods: {
addFn(){
this.arr.splice(1, 0, '新来的')
}
}
};
2.有key - 值为索引
因为新旧虚拟DOM对比, key存在就复用此标签更新内容, 如果不存在就直接建立一个新的
<ul id="myUL">
<li v-for="(str, index) in arr" :key="index">
{{ str }}
<input type="text">
</li>
</ul>
<button @click="addFn">下标为1的位置新增一个</button>
export default {
data(){
return {
arr: ["老大", "新来的", "老二", "老三"]
}
},
methods: {
addFn(){
this.arr.splice(1, 0, '新来的')
}
}
};