Vue3速成
Vue简介
渐进式框架
Vue是一个框架,也是一个生态,其功能覆盖了大部分前端开发常见的需求。
Vue的设计非常注重灵活性和"可以被逐步集成"这个特点。根据不同的需求场景,你可以用不同的方式使用Vue:
- 无需构建步骤,渐进式增强静态的HTML
- 在任何页面中作为Web Components嵌入
- 单页应用(SPA)
- 全栈/服务端渲染(SSR)
- Jamsstack/静态站点生成(SSG)
- 开发桌面端、移动端、WebGL、甚至是命令行终端中的界面
Vue版本
Vue3涵盖了Vue2的知识体系,当然Vue3也增加了很多新特性
官网文档:https://cn.vuejs.org/
淘宝npm镜像改成了https://registry.npmmirror.com
Vue API风格
Vue的组件可以按照两种不同的风格书写:
- 选项式API —-> 偏向于Vue2
- 组合式API —-> 偏向于Vue3
Vue项目项目结构
1
2
3
4
5
6
7
8
|
.vscode ----> VSCode工具的配置文件
node_modules ----> Vue项目的运行依赖文件夹
public ----> 资源文件夹(浏览器图标)
src ----> 源码文件夹
.gitnore ----> git忽略文件
index.html ----> 入口HTML文件
package.json ----> 信息描述文件
vite.config.js ----> Vue配置文件
|
模板语法
Vue使用一种基于HTML的模板语法,是我们能够声明式地将其组件实例的数据绑定到呈现的DOM上。所有的Vue模板都是语法层面合法的HTML,可以被符合规范的浏览器和HTML解析器解析
文本插值
最基本的数据绑定形式是文本插值,使用的是"Mustache"语法(即双大括号)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<template>
<h3>模板语法</h3>
<p>{{ msg }}</p>
</template>
<script>
export default{
data(){
return{
msg:"神奇的语法"
}
}
}
</script>
|
使用JS表达式
每个绑定仅支持单一表达式,也就是一段能够被求值的JavaScript代码。一个简单的判断方法是是否可以合法地写在return后面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<template>
<h3>模板语法</h3>
<p>{{ msg }}</p>
<p>{{ number + 1 }}</p>
<p>{{ msg.split('').reverse().join('') }}</p>
</template>
<script>
export default{
data(){
return{
msg:"神奇的语法",
ok:true,
number:10
}
}
}
</script>
|
无效
1
2
3
4
5
|
<!-- 这是一个语句,而非表达式 -->
{{var a = 1}}
<!-- 条件控制也不支持,请使用三元表达式 -->
{{if(ok){return message} }}
|
原始HTML
双大括号将会将数据插值为纯文本,而不是HTML。若想插入HTML,你需要使用v-html指令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<template>
<h3>模板语法</h3>
<p>{{ msg }}</p>
<p>{{ number + 1 }}</p>
<p>{{ msg.split('').reverse().join('') }}</p>
<p>{{ rawHtml }}</p>
<p v-html="rawHtml" ></p>
</template>
<script>
export default{
data(){
return{
msg:"神奇的语法",
ok:true,
number:10,
rawHtml:"<a href='https://bilibili.com'>哔哩哔哩</a>"
}
}
}
</script>
|
属性绑定
双大括号不能在HTML attributes中使用。想要响应式地绑定一个attribute,应该使用v-bind指令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<script>
export default{
data(){
return{
dynamicClass:"active",
dynamicId:"appid"
}
}
}
</script>
<template>
<div v-bind:id="dynamicId" v-bind:class="dynamicClass">测试</div>
</template>
|
v-bind指令指示Vue将元素的idattribute与组件的dynamicId属性保持一致。如果绑定的值是null或者undefined,那么该attribute将会从渲染的元素上移除
简写
因为v-bind非常常用,我们提供了特定的简写语法
1
|
<div :id="dynamicId":class="dynamicClass">测试</div>
|
布尔型Attribute
布尔型attribute依据true/false值来决定attribute是否应该存在于该元素上,disabled就是最常见的例子之一
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<script>
export default{
data(){
return{
dynamicClass:"active",
dynamicId:"appid",
isButtonDisabled:false
}
}
}
</script>
<template>
<div v-bind:id="dynamicId" v-bind:class="dynamicClass">测试</div>
<button :disabled="isButtonDisabled">Button</button>
</template>
|
动态绑定多个值
如果你有像这样的一个包含多个attribute的JavaScript对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<script>
export default{
data(){
return{
objectOfAttrs:{
id:'container',
class:'wrapper'
}
}
}
}
</script>
<template>
<div v-bind="objectOfAttrs">测试</div>
</template>
|
条件渲染
在vue中,提供了条件渲染,这类似于JavaScript中的条件语句
v-if
v-else
v-else-if
v-show
v-if
v-if指令用于条件性地渲染一块内容,这块内容只会在指令的表达式返回真值时才被渲染
v-else
可以使用v-else为v-if添加一个"else区块"
v-else-if
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<template>
<h3>条件渲染</h3>
<div v-if="flag">你看得见我吗</div>
<div v-else>那你看得见我吗</div>
<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div>
<div v-else-if="type === 'C'">C</div>
<div v-else>Not A/B/C</div>
</template>
<script>
export default{
data(){
return{
flag:false,
type:"D"
}
}
}
</script>
|
v-show
另一个可以用来按条件显示一个元素地指令是v-show,其用法基本一样
v-if Vs v-show
v-if是"真实的"按条件渲染,因为他确保了在切换时候,条件区块内的事件监听器和子组件都会被销毁与重建
v-if也是惰性的:如果在初次渲染时条件值为false,则不会做任何事情。条件区块只有当条件首次变为true的时候才会被渲染
相比之下,v-show简单许多,元素无论初始条件如何,始终会被渲染,只有CSSdisplay属性会被切换
总的来说,v-if有更高的切换开销,而v-show有更高的初始渲染开销。因此,如果需要频繁切换,则使用v-show较好;如果在运行时绑定条件很少改变,则v-if会更合适
列表渲染
我们可以使用v-for指令基于一个数组来渲染一个列表。v-for指令的值需要使用item in items形式的特殊语法,其中items是源数据的数组,而item是迭代项的别名(类似于for each)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<template>
<h3>列表渲染</h3>
<p v-for="item in names">{{ item }}</p>
</template>
<script>
export default{
data(){
return{
names:["百战程序员","尚学堂","IT"]
}
}
}
</script>
|
复杂数据
大多数情况下,我们渲染的数据源来源于网络请求,也就是JSON格式

v-for也支持使用可选的第二个参数表示当前项的位置索引
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<template>
<h3>列表渲染</h3>
<p v-for="(item,index) in names">{{ item }}-{{ index }}</p>
</template>
<script>
export default{
data(){
return{
names:["百战程序员","尚学堂","IT"]
}
}
}
</script>
|
也可以使用of来代替in
v-for="item of names"
v-for与对象
也可以使用v-for来遍历一个对象的所有属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<template>
<h3>列表渲染</h3>
<p v-for="(item,index) in names">{{ item }}-{{ index }}</p>
<p v-for="(value,key,index) of userInfo">{{ value }}-{{ key }}-{{ index }}</p>
</template>
<script>
export default{
data(){
return{
names:["百战程序员","尚学堂","IT"],
userInfo:{
name:"iwen",
age:20,
sex:"男"
}
}
}
}
</script>
|
通过key管理状态
Vue默认按照"就地更新"的策略来更新通过v-for渲染的元素列表。当数据项的顺序改变时,Vue不会随之移动DOM元素的顺序,而是==就地更新每个元素==,确保它们在原本指定的索引位置上渲染
为了给Vue一个提示,以便它可以跟踪每个节点的标识,从而重用和重新排序现有的元素,你需要为每个元素对应的块提供一个唯一的keyattribute:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<template>
<h3>Key属性添加</h3>
<p v-for="(item,index) of names" :key="index">{{ item }}</p>
</template>
<script>
export default {
data(){
return {
names:["111","222","333"]
}
}
}
</script>
|
补充:
key在这里是一个通过v-bind绑定的特殊attribute,推荐在任何可行的时候为v-for提供一个keyattribute,key绑定的值期望是一个基础类型的值,例如字符串或者number类型
key的来源
请不要使用index作为key的值,要确保每一条数据的唯一索引不会发生变化
事件处理
我们可以使用v-on指令(简写为@)来监听DOM事件,并在事件触发时执行对应的Javascript。用法:v-on:click="methoodName"或@click="handler"
事件处理器的值可以是:
- 内联事件处理器:事件被触发时执行的内联JavaScript语句(与
onclick类似)
- 方法事件处理器:一个指向组件上定义的方法的属性名或者路径
内联事件处理器
内联事件处理器通常用于简单场景
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<template>
<h3>内联事件处理器</h3>
<button @click="count++">Add</button>
<p>{{ count }}</p>
</template>
<script>
export default {
data(){
return {
count:0
//双向绑定
}
}
}
</script>
|
方法事件处理器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<template>
<h3>内联事件处理器</h3>
<button @click="addCount">Add</button>
<p>{{ count }}</p>
</template>
<script>
export default {
data(){
return {
count:0
}
},
methods:{
addCount(){
//读取到data里的数据
this.count++;
}
}
}
</script>
|
事件传参
事件参数可以获取event对象和通过事件传递数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<template>
<h3>事件传参</h3>
<p @click="getNameHandler(item,$event)" v-for="(item,index) of names" :key="index">{{ item }}</p>
</template>
<script>
export default {
data(){
return {
names:["iwen","ime","frank"]
}
},
methods:{
//如果定义的函数中既有传参又有事件,那么在标签中应该在形参中添加$event
getNameHandler(name,e){
console.log(name);
console.log(e);
}
}
}
</script>
|
事件修饰符
在处理事件时调用event.preventDefault()或event.stopPropagation()是很常见的。尽管可以直接在方法内调用,但如果方法能更关注于数据逻辑而不用去处理DOM事件的细节会更好
为解决这一问题,Vue为v-on提供了事件修饰符,常用有以下几个:
.stop
.prevent
.once
.enter
- ···
阻止默认事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<template>
<h3>事件修饰符</h3>
<a @click.prevent="clickHandle" href="https://bilibili.com">b站</a>
</template>
<script>
export default {
data(){
return {
}
},
methods:{
clickHandle(e){
//阻止默认事件
// e.preventDefault();
console.log("点击了")
}
}
}
</script>
|
阻止事件冒泡
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
28
29
30
31
32
33
|
<template>
<h3>事件修饰符</h3>
<a @click.prevent="clickHandle" href="https://bilibili.com">b站</a>
<div @click="clickDiv">
<p @click.stop="clickP">测试冒泡</p>
</div>
</template>
<script>
export default {
data(){
return {
}
},
methods:{
clickHandle(e){
//阻止默认事件
// e.preventDefault();
console.log("点击了")
},
clickDiv(){
console.log("Div")
},
clickP(e){
//阻止事件冒泡
// e.stopPropagation();
console.log("P")
}
}
}
</script>
|
数组变化侦测
变更方法
Vue能够侦听响应式数组的变更方法,并在他们被调用时触发相关的更新。这些变更方法包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
替换一个数组
变更方法,顾名思义就是对调用它们的原数组进行变更。相对地,也有一些不可变方法,例如filter(),concat(),slice(),这些都不会更改原数组,而是返回一个新数组。当遇到的是非变更方法时,我们需要将旧的数组替换新的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<template>
<button @click="addUI">click</button>
<ul>
<li v-for="(item,index) of names" :key="index">{{ item }}</li>
</ul>
</template>
<script>
export default{
data(){
return{
names:["iwen","ime","frank"]
}
},
methods:{
addUI(){
//引起UI自动更新
//this.names.push("sakura")
//不会引起UI自动更新
this.names = this.names.concat(["sakura"])
}
}
}
</script>
|
计算属性
模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。因此我们推荐使用计算属性来描述依赖响应式状态的复杂逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<template>
<h3>{{ it.names }}</h3>
<p>{{ itbaizhan }}</p>
</template>
<script>
export default{
data(){
return{
it:{
names:"百战程序员",
content:["前端","Java","python"]
}
}
},
//计算属性
computed:{
itbaizhan(){
return this.it.content.length>0?'Yes':'No'
}
}
}
</script>
|
计算属性缓存VSmethod
重点区别:
计算属性:计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算
方法:方法调用总是会在重渲染发生时再次执行函数
Class绑定
数据绑定的一个常见需求场景是操纵元素的CSS class列表,因为class是attribute,我们可以和其他attribute一样使用v-bind将它们和动态的字符串绑定。但是,在处理比较复杂的绑定时,通过拼接生成字符串是麻烦且出错的。因此,Vue专门为class的v-bind用法提供了特殊的功能增强。除了字符串外,表达式的值也可以是对象或数组
绑定对象
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
|
<template>
<p :class="{'active':isActive,'textError':hasError}">Class样式绑定</p>
<p :class="classObject">Class样式绑定2</p>
</template>
<script>
export default{
data(){
return{
isActive:true,
hasError:true,
classObject:{
'active':true,
'textError':true
}
}
}
}
</script>
<style>
.active{
color: red;
}
</style>
|
绑定数组
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
28
29
|
<template>
<p :class="{'active':isActive,'textError':hasError}">Class样式绑定</p>
<p :class="classObject">Class样式绑定2</p>
<p :class="[arrActive,arrHasError]">Class样式绑定3</p>
<p :class="[isActive?'active':'']">Class样式绑定4</p>
</template>
<script>
export default{
data(){
return{
isActive:true,
hasError:true,
classObject:{
'active':true,
'textError':true
},
arrActive:"active",
arrHasError:"text-Error"
}
}
}
</script>
<style>
.active{
color: red;
}
</style>
|
数组和对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<template>
<div :class="[{'active':isActive},errorClass]">11</div>
</template>
<script>
export default{
data(){
return{
isActive:true,
errorClass:"text-danger"
}
}
}
</script>
<style>
.active{
color: red;
}
</style>
|
温馨提示:
数组和对象嵌套使用的时候,只能数组嵌套对象,不能反其道而行
Style绑定
与上文中的Class绑定类似
侦听器
我们可以使用watch选项在每次响应式属性发生变化的时候触发一个函数
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
28
|
<template>
<h3>侦听器</h3>
<p>{{ message }}</p>
<button @click="onUpdated">修改数据</button>
</template>
<script>
import { onUpdated } from 'vue';
export default{
data(){
return {
message:"Hello"
}
},
methods:{
onUpdated(){
this.message = "World"
}
},
watch:{
//函数名需要和侦听的变量保持一致
message(newValue,oldValue){
//数据发生变化,自动执行的函数
console.log(newValue,oldValue);
}
}
}
</script>
|
表单输入绑定
在前端处理表单时,我们常常需要将表单输入框的内容同步给JavaScript中相应的变量。手动连接值绑定和更改事件监听器可能会很麻烦,v-model指令帮我们简化了这一步骤
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<template>
<h3>表单输入绑定</h3>
<form>
<input type="text" v-model="message">
<p>{{ message }}</p>
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
</form>
</template>
<script>
export default {
data() {
return {
message:" ",
checked:false
}
}
}
</script>
|