Vue的基本使用(要点)
一、插值、指令
1. 插值
即模板语法,括号内仅能使用
js
表达式,不能写js
语句
2. 指令、动态属性
- 指令:以
v-
开头的的模板指令 - 动态属性:在模板中以
v-bind
或冒号:
表示,可以写js
变量
3. v-html
v-html
会有XSS
风险,会覆盖子组件
二、computed和watch
1. computed
- 具有缓存功能,依赖的数据发生变化时才会重新计算,否则直接读取缓存,因此可提高性能;
- 具有
set
和get
方法,如果读取缓存时,get
不会被调用。
2. watch
watch
的handler
方法有oldVal
和newVal
两个参数- 深度监听,针对的是引用监听。
watch
默认浅监听,只监听引用对象的一层属性变化,使用deep
属性,将deep
设置为true
可设置为深度监听 - 如果监听的是一个引用类型,修改对象的内容时,
oldVal
参数值与newVal
参数值一样,因为oldVal
和newVal
指向的是同一个地址。如果重新赋值新对象,则oldVal
和newVal
正常。
三、class和style
- 使用动态属性
style
中的css
属性使用驼峰式写法class
可以对象和数组的形式,style
为对象。
<div :class="{ active: flag }"></div>
<div :class="[ active, selected ]"></div>
<div :style="backgroundStyle"</div>
export default {
data(){
return {
active: 'active',
selected: 'selected',
backgroundStyle: {
fontSize: '12px',
backgroundColor: '#ffffff'
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
四、条件渲染
v-if
、v-elseif
和v-else
,可以使用变量,也可以中===
表达式v-show
,使用同v-if
v-if
和v-show
的区别是什么?
- 区别:如果
v-show
和v-if
条件为true
,节点都会渲染,都会被加入到dom
树中。如果条件为false
,v-if
节点不会被渲染,v-show
节点还是会被渲染,只是把它设置为display: none
。 - 使用场景:如果频繁切换条件,则使用
v-show
,可以减少性能开销。如果不频繁更改条件,则使用v-if
,因为如果频繁的改变条件,dom
节点被频繁的装载和卸载销毁,会消耗不必要的性能。
五、循环(列表)渲染
1. v-for遍历数组和对象
<ul>
<!-- 数组遍历 -->
<li v-for="(item, index) in array" :key="item.id">{item}</li>
<!-- 对象遍历 -->
<li v-for="(val, key, index) in array" :key="key">{val}</li>
</ul>
1
2
3
4
5
6
7
2
3
4
5
6
7
2. key的重要性
- 使用
v-for
时,为什么要使用key
属性? - 为什么
key
尽量使用与数据相关的属性,不要使用index
和random
?
为什么? 没有key
时,Vue
会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。key
是vnode
的唯一标识,通过key
,diff
算法操作更准确、更快速。
- 更准确:带
key
时就不是“就地复用”,通过key
判断新旧节点可以避免“就地复用”的情况。 - 更快速:
diff
算法利用key
的唯一性,存储于map
中,通过唯一标识获取对应的节点,比遍历方式更快
3. v-for和v-if不能同时使用
因为v-for
的优先级比v-if
优先级高,每一次循环都要进行一次判断,会使渲染速度减慢。
六、事件
1. event参数、自定义参数
<!--无参数时,默认带有event-->
<div @click="handleClick1"></div>
<!--多个参数,需要event参数-->
<div @click="handleClick2(2, $event)"></div>
export default {
methods: {
handleClick1(e) {
// e
// 1. 原生event对象
// 2. 监听被挂在当前元素
},
handleClick2(param, e) {
// e 同上
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2. 事件修饰符,按键修饰符
(1)事件修饰符
click
单击事件stop
阻止事件继续传播prevent
capture
添加事件监听器时使用事件捕获模式,即内部元素触发时先在这里处理,然后才交由内部元素处理submit
self
只当event.target
自身元素触发时生效,内部元素触发无效修饰符可以串联使用,如下:
<div v-on:click.stop.prevent="handler"></div>
1
- 无处理函数,只有修饰符,如下:
<div v-on:submit.prevent></div>
1
(2)按键修饰符
enter
回车键按下时触发ctrl.exact
只有ctrl
按下时触发click.exact
没有任何系统修饰符被按下时触发
。。。
3. 【观察】事件被绑定到哪里
event.target event.currentTarget
4. v-model
v-model
在各个表单控件中的使用v-model.trim
去空格v-model.number
限制只能输入数字
七、组件的基本使用
1. props和$emit
(1)props
export default {
// 方式一:无类型声明
props: ['param'],
// 方式二:类型声明
props: Array,
// 方式三:其他限制参数的属性
props: {
type: Array,
required: true, // true or false
default: () => [], // 默认值
validator: () => boolean, // 参数校验
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(2)$emit
$emit
配合props
可以进行父子组件的通信
2. 组件间通讯
(1) 父子组件通信
$emit
和props
(2) 全局通信
let event = new Vue();
// 发射事件
event.$emit('flag', param)
// 事件监听
event.$on('flag', handler)
// 事件注销,一定要注销事件,否则会重复添加处理函数,导致多次调用处理函数的bug和内存泄漏
event.$off(handler)
1
2
3
4
5
6
7
2
3
4
5
6
7
(3) 与子孙组件的通信
通过使用provide
和inject
,可以跨越多层级的组件进行通信
// 提供依赖
provide() {
return {
key: value
}
}
// 依赖注入
inject: ['key']
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
3. 组件的生命周期
八、Vue的高级特性
1. 自定义v-model
<!--组件A-->
<template>
<input type="text" :value="param" @input="$emit('change', $event.target.value)"/>
</template>
<!--
1. 上面的 input 使用 :value
2. 上面的 $emit的change,对应model选项的event
3. 上面的 :valute的param,对应props的param
-->
<!--组件B-->
<template>
<A v-model="name" />
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
// 组件A
export default {
model: {
prop: 'param', // 对应props param
event: 'change'
},
props: {
param: {
type: String,
default: () => ''
}
}
}
// 组件B
export default {
data() {
return {
name: ''
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2. $nextTick
- Vue是异步渲染
- data改变之后,DOM不会立即渲染
- $nextTick会在DOM渲染之后触发,此时才能获取数据更新渲染完成后的最新DOM
总结:
- 异步渲染,$nextTick 待 DOM 渲染完成后回调
- 在同一个tick内,不管data更改多少次,Vue最后会收集整合data,之后只进行一次渲染
3. slot插槽
(1)插槽的基本使用
(2)具名插槽
(3)作用域插槽
<!-- A组件 -->
<template>
<div>
<slot v-bind:user="user"></slot>
</div>
</template>
<!-- B组件 -->
<template>
<!-- 拥有具名插槽时 -->
<A>
<!-- 默认插槽 -->
<template v-slot:default="userProps">
{{ userProps.user.firstName }}
</template>
<!-- 具名插槽 -->
<template v-slot:xxx="xxxProps">
</template>
</A>
<!-- 只有默认插槽时 -->
<A v-slot="userProps">
{{ userProps.user.firstName }}
</A>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
4. 动态组件和异步组件
(1)动态组件
<!--
三个要素:
1. <component />组件
2. 动态属性 :is
3. 组件名称
-->
<component :is="componentName"></component>
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
(2)异步组件
- 使用异步组件时,不会将异步组件的代码打包到bundle里,需要使用时再请求组件代码,可以有效的减少首次加载时的加载时间,提高加载性能。
import
函数的使用
5. keep-alive
6. mixin
(1)抽离多个组件的相同逻辑,可以复用
(2)mixin的合并策略
- 组件和mixin中data和methods具有相同变量时,组件的变量会覆盖mixin中的变量;
- 组件和mixin中具有相同的生命周期钩子时,mixin的钩子先于组件的钩子被调用。
(3)mixin具有的一些问题
- 变量来源不明,不利于阅读和追溯
- 变量命名冲突
- 复杂度变高
(4)Vue3 的Composition API旨在解决mixin的上述缺点
九、Vue生态
1. vuex
考点:
- vuex的基本概念、vuex的基本使用和常用API
- 考察state数据结构的设计
(1)基本概念
- state
- getters
- action
- mutation
(2)常用API
- dispatch
- commit
- mapState
- mapGetters
- mapMutations
- mapActions
(3)vuex逻辑图
注意:只有在action中才可以进行异步操作
2. vue-router
(1)路由模式
- hash模式(默认),如http://abc.com/#/user/10
- H5 history模式,如http://abc.com/user/10
H5 history模式需要server端支持,如无特殊情况使用前者
(2)路由配置
- 动态路由参数,
path:user/:id
- 组件懒加载,
component: () => import('./compoentA')