VSCode代码片段✨
我们在前面练习Vue的过程中,有些代码片段是需要经常写的,我们再VSCode中我们可以生成一个代码片段,方便我们快速生成。VSCode中的代码片段有固定的格式,所以我们一般会借助于一个在线工具来完成
具体的步骤如下:
- 复制自己需要生成代码片段的代码;
- https://snippet-generator.app/在该网站中生成代码片段;
- 在VSCode中配置代码片段(文件——首选项——配置用户代码片段)
模版语法✨
- React的开发模式
- React使用的jsx,所以对应的代码都是
编写的类似js的一种语法
- 之后通过Babel将jsx编译成 React.createElement函数调用
- Vue的开发模式
- Vue也支持jsx的开发模式,后续会提到,但是大多数下,使用
基于HTML的模板语法
- 在模板中,允许开发者以声明式的方式将
DOM
和底层组件实例的数据
绑定在一起 - 在底层的实现中,Vue将
模板
编译成虚拟DOM渲染函数
;
1. Mustache插值语法✨
如果我们希望把数据显示到模板(template)中,使用最多的语法是 “Mustache”语法 (双大括号)
的文本插值:
- Mustache中,不仅仅可以是data中属性,也可以是一个
JavaScript的表达式
- 当·data中的数据发生改变时,对应的内容也会发生更新
<div id="app">
<!-- 1.基本使用 -->
<h2>{{ message }}</h2>
<h2>当前计数: {{ counter }} </h2>
<!-- 2.表达式 -->
<h2>计数双倍: {{ counter * 2 }}</h2>
<h2>展示的信息: {{ info.split(" ") }}</h2>
<!-- 3.三元运算符 -->
<h2>{{ age >= 18? "成年人": "未成年人" }}</h2>
<!-- 4.调用methods中函数 -->
<h2>{{ formatDate(time) }}</h2>
<!-- 5.注意: 这里不能定义语句 -->
<!-- <h2>{{ const name = "why" }}</h2> -->
</div>
错误使用;
2.常见基本指令(了解)✨
接下来的指令都是写在dom标签的属性一样写在标签里面
2.1 v-once⭐
作用:v-once用于指定元素或者组件只渲染一次:
-
当数据发生变化时,
元素或者组件以及其所有的子元素
将视为静态内容
并且跳过 -
如果是子节点,也是只会渲染一次
-
该指令可以用于
性能优化
<div id="app">
<!-- 指令: v-once -->
<h2 v-once>
{{ message }}
<span>数字: {{counter}}</span>
</h2>
<h1>{{message}}</h1>
<button @click="changeMessage">改变message</button>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
message: "Hello Vue",
counter: 100
}
},
methods: {
changeMessage: function() {
this.message = "你好啊, 李银河"
this.counter += 100
console.log(this.message, this.counter)
}
}
})
// 2.挂载app
app.mount("#app")
</script>
2.2 v-text⭐
作用:v-text主要用于更新对应标签的textContent,如果标签中已经有内容,那么就会把v-text指令绑定的内容替换
原有的内容,因此v-text使用较少,推荐使用Mustache语法更加灵活
2.3 v-html⭐
作用:在默认情况下,如果内容本身是html形式的字符串
,那么vue并不会对其进行特殊的解析
。如果我们希望这个内容可以被Vue解析,那么可以使用v-html来完成:
<div id="app">
<h2>{{ content }}</h2>
<h2 v-html="content"></h2>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
content: `<span style="color: red; font-size: 30px;">哈哈哈</span>`
}
},
})
// 2.挂载app
app.mount("#app")
</script>
2.4 v-pre⭐
作用:v-pre用于跳过元素和它的子元素的编译过程
,显示原始的Mustache标签,主要就是跳过不需要的编译结点,加快编译的速度。(若有子元素,则子元素也不会进行编译)
<div id="app">
<div v-pre>
<h2>{{ message }}</h2>
<p>当前计数: {{ counter }}</p>
<p>{{}}</p>
</div>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
message: "Hello Vue",
counter: 0
}
},
})
// 2.挂载app
app.mount("#app")
</script>
2.5 v-cloak⭐
作用:根据浏览器的渲染流程,会首先解析body标签中的dom元素,然后才开始解析script引用标签,最后才开始执行脚本。如果文件过大,执行时间过长,就会导致我们写的Mustache语法会以未编译的形式展示在页面中。
因此,这个指令保持在元素上直到关联组件实例结束编译
。
2.6 v-memo⭐
作用:缓存一个模板的子树。该指令需要传入一个固定长度的依赖值数组进行比较,只有当其中的某依赖值被更新时,被缓模版的子树才会重写渲染。 若与每个值都与最后一次的渲染相同(就是渲染的时候发现没变,就用原来的旧的),那么整个子树的更新将被跳过。
<div id="app">
<div v-memo="[name, age]">
<h2>姓名: {{ name }}</h2>
<h2>年龄: {{ age }}</h2>
<h2>身高: {{ height }}</h2>
</div>
<button @click="updateInfo">改变信息</button>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
name: "why",
age: 18,
height: 1.88
}
},
methods: {
updateInfo: function() {
// this.name = "kobe"
this.age = 20
}
}
})
// 2.挂载app
app.mount("#app")
</script>
3. v-bind绑定属性✨
上述常见的基本指令,主要是控制值插到模版内容中,但是处理内容需要动态来决定外,某些属性我们也希望动态来绑定
,比如:动态绑定a元素的href属性。
3.1 作用⭐
- v-bind用于
绑定一个或多个属性值
,或者向另一个组件传递props值
- 在开发中还有很多属性需要动态进行绑定,如:图片的链接src、网站的链接href、动态绑定一些类、样式等
- 语法糖 使用
:
3.2 切换图片的案例:⭐
<div id="app">
<div>
<button @click="switchImage">切换图片</button>
</div>
<!-- 1.绑定img的src属性 -->
<img v-bind:src="showImgUrl" alt="">
<!-- 语法糖: v-bind -> : -->
<img :src="showImgUrl" alt="">
<!-- 2.绑定a的href属性 -->
<a :href="href">百度一下</a>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
imgUrl1: "http://p1.music.126.net/agGc1qkogHtJQzjjyS-kAA==/109951167643767467.jpg",
imgUrl2: "http://p1.music.126.net/_Q2zGH5wNR9xmY1aY7VmUw==/109951167643791745.jpg",
showImgUrl: "http://p1.music.126.net/_Q2zGH5wNR9xmY1aY7VmUw==/109951167643791745.jpg",
href: "http://www.baidu.com"
}
},
methods: {
switchImage: function() {
this.showImgUrl = this.showImgUrl === this.imgUrl1 ? this.imgUrl2: this.imgUrl1
}
}
})
// 2.挂载app
app.mount("#app")
</script>
4. v-bind绑定class✨
4.1 作用⭐
开发中,有时候我们的元素class也是动态的:当数据为某个状态时,字体显示红色,另外一个状态下,字体显示黑色。
4.2 绑定class有两种方式:⭐
- 对象语法:我们可以传给 :class (v-bind:class 的简写) 一个对象,以动态地切换 class。
<!-- 1.基本绑定class -->
<h2 :class="classes">Hello World</h2>
<!-- 2.动态class可以写对象语法 -->
<button :class=" isActive ? 'active': '' " @click="btnClick">我是按钮</button>
<!-- 2.1.对象语法的基本使用(掌握) -->
<button :class="{ active: isActive }" @click="btnClick">我是按钮</button>
<!-- 2.2.对象语法的多个键值对 -->
<button :class="{ active: isActive, why: true, kobe: false }" @click="btnClick">我是按钮</button>
<!-- 2.3.动态绑定的class是可以和普通的class同时的使用 -->
<button class="abc cba" :class="{ active: isActive, why: true, kobe: false }" @click="btnClick">我是按钮</button>
<!-- 2.4.动态绑定的class是可以和普通的class同时的使用 -->
<button class="abc cba" :class="getDynamicClasses()" @click="btnClick">我是按钮</button>
- 数组语法:我们可以把一个数组传给 :class,以应用一个 class 列表;
<!-- 3.动态class可以写数组语法(了解) -->
<h2 :class="['abc', 'cba']">Hello Array</h2>
<h2 :class="['abc', className]">Hello Array</h2>
<h2 :class="['abc', className, isActive? 'active': '']">Hello Array</h2>
<h2 :class="['abc', className, { active: isActive }]">Hello Array</h2>
实例:
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
classes: "abc cba nba",
isActive: false,
className: "why"
}
},
methods: {
btnClick: function() {
this.isActive = !this.isActive
},
getDynamicClasses: function() {
return { active: this.isActive, why: true, kobe: false }
}
}
})
// 2.挂载app
app.mount("#app")
</script>
5.v-bind绑定style✨
5.1 作用⭐
- 因为某些样式我们需要根据
数据
动态来决定,比如某段文字的颜色,大小。通过使用v-bind:style
来绑定一些CSS内联样式
- CSS property名可以用
驼峰式(camelCase)
或短横线分隔(kebab-case,记得用引号括起来)
来命名。
5.2 其中绑定style也有两种方式:⭐
1. 对象语法
<!-- 1.普通的html写法 -->
<h2 style="color: red; font-size: 30px;">哈哈哈哈</h2>
<!-- 2.style中的某些值, 来自data中 -->
<!-- 2.1.动态绑定style, 在后面跟上 对象类型 (重要)-->
<h2 v-bind:style="{ color: fontColor, fontSize: fontSize + 'px' }">哈哈哈哈</h2>
<!-- 2.2.动态的绑定属性, 这个属性是一个对象 -->
<h2 :style="objStyle">呵呵呵呵</h2>
2. 数组语法
<!-- 3.style的数组语法 -->
<h2 :style="[objStyle, { backgroundColor: 'purple' }]">嘿嘿嘿嘿</h2>
实例:
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
fontColor: "blue",
fontSize: 30,
objStyle: {
fontSize: '50px',
color: "green"
}
}
},
})
// 2.挂载app
app.mount("#app")
</script>
5.3 动态绑定属性名⭐
在某些情况下,我们属性的名称可能也不是固定的:
- 前端我们无论绑定src、href、class、style,属性名称都是固定的
- 如果属性名称不是固定的,我们可以使用
:[属性名]=“值”
的格式来定义
这种绑定的方式,属性名会动态变化
,我们称之为动态绑定属性名
5.4 绑定一个对象⭐
如果我们希望把一个对象中的所有key:value都绑定到元素或者组件上
,绑定的对象会被拆解作为绑定元素或组件上的属性
。
<div id="app">
<h2 :name="name" :age="age" :height="height">Hello World</h2>
<!-- v-bind绑定对象: 给组件传递参数 -->
<h2 v-bind="infos">Hello Bind</h2>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
infos: { name: "why", age: 18, height: 1.88, address: "广州市" },
name: "why",
age: 18,
height: 1.88
}
},
})
// 2.挂载app
app.mount("#app")
</script>
6. v-on绑定事件✨
在前面我们知道了如何用v-bind和Mustache插值语法来绑定来元素的内容和属性
,在前端开发中另外一个非常重要的特性就是交互
,在Vue中我们可以使v-on
指令
6.1 v-on的基本使用
- 基本写法
<!-- 1.基本的写法 -->
<div class="box" v-on:click="divClick"></div>
- v-on绑定事件的
语法糖
(重点掌握)
<!-- 2.语法糖写法(重点掌握) -->
<div class="box" @click="divClick"></div>
- 绑定的方法位置,直接写表达式(一般不推荐使用)
<!-- 3.绑定的方法位置, 也可以写成一个表达式(不常用, 不推荐) -->
<h2>{{ counter }}</h2>
<button @click="increment">+1</button>
<button @click="counter++">+1</button>
- 绑定多个事件,对象写法和一般写法
<!-- 5.元素绑定多个事件(掌握) -->
<div class="box" @click="divClick" @mousemove="divMousemove"></div>
<!-- <div class="box" v-on="{ click: divClick, mousemove: divMousemove }"></div> -->
<!-- <div class="box" @="{ click: divClick, mousemove: divMousemove }"></div> -->
案例-vue实例
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
counter: 0
}
},
methods: {
divClick() {
console.log("divClick")
},
increment() {
this.counter++
},
divMousemove() {
console.log("divMousemove")
}
}
})
// 2.挂载app
app.mount("#app")
</script>
6.2 v-on的参数传递
当通过methos的方法,以供事件调用时,需要注意:
- 无传参:
- 在绑定事件时,可以
省略 ()
- 如果methos里的方法本身有一个参数,那么会默认将原生事件event参数传进去
- 在绑定事件时,可以
<!-- 1.默认传递event对象 -->
<button @click="btn1Click">按钮1</button>
<!-- 2.只有自己的参数 -->
<button @click="btn2Click('why', age)">按钮2</button>
- 传入参数,并且需要event事件对象:
- 需要传入多个参数且希望event也有时,我们需要在绑定事件那里用
$event
来指定哪一个是event
- 需要传入多个参数且希望event也有时,我们需要在绑定事件那里用
<!-- 3.自己的参数和event对象 -->
<!-- 在模板中想要明确的获取event对象: $event -->
<button @click="btn3Click('why', age, $event)">按钮3</button>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
message: "Hello Vue",
age: 18
}
},
methods: {
// 1.默认参数: event对象
// 总结: 如果在绑定事件的时候, 没有传递任何的参数, 那么event对象会被默认传递进来
btn1Click(event) {
console.log("btn1Click:", event)
},
// 2.明确参数:
btn2Click(name, age) {
console.log("btn2Click:", name, age)
},
// 3.明确参数+event对象
btn3Click(name, age, event) {
console.log("btn3Click:", name, age, event)
}
}
})
// 2.挂载app
app.mount("#app")
</script>
6.3 v-on的修饰符
v-on支持修饰符,修饰符相当于对事件进行了一些特殊的处理:
修饰符 | 作用 |
---|---|
.stop | 调用 event.stopPropagation() |
.prevent | 调用 event.preventDefault() |
.capture | 添加事件侦听器时使用 capture 模式 |
.self | 只当事件是从侦听器绑定的元素本身触发时才触发回调 |
.{keyAlias} | 仅当事件是从特定键触发时才触发回调 |
.once | 只触发一次回调 |
.left | 只当点击鼠标左键时触发 |
.right | 只当点击鼠标右键时触发 |
.middle | 只当点击鼠标中键时触发 |
.passive | { passive: true } 模式添加侦听器 |
7. Vue的条件渲染✨
在某些情况下,我们需要根据当前的条件决定某些元素或组件是否渲染,这个时候我们就需要进行条件判断了
7.1 v-if、v-else、v-else-if
这三个指令与JavaScript的条件语句if、else、else if 类似,只有在条件为true时,才会被渲染出来。
<!-- 模板语法 -->
<div id="app">
<ul v-on:click="" v-if="names.length > 3">
<li v-for="item in names">{{item}}</li>
</ul>
<h2 v-else-if="0 < names.length <3">当前names长度在0到3</h2>
<h2 v-else>当前names没有数据, 请求获取数据后展示</h2>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function () {
return {
names: [1, 2, 3, 4]
}
},
})
// 2.挂载app
app.mount("#app")
</script>
v-if的渲染原理是惰性的:
- 当条件为false时,其判断的内容完全不会被渲染或者会被销毁掉
- 当条件为true时,才会真正渲染条件块中的内容
可以看到只有 “优秀”的h1元素才被渲染了,其他的内容连dom结构都是不存在的,完全没有加载
<div id="app">
<h1 v-if="score > 90"> 优秀</h1>
<h2 v-else-if="score > 80">良好</h2>
<h3 v-else-if="score >= 60">及格</h3>
<h4 v-else>不及格</h4>
</div>
7.2 template元素
为什么要有temple元素:
- 因为v-if是一个指令,所以必须将其添加到一个元素上,让其是一个整体。
- 但如果这个元素是一个div那么就
存在一个弊端
:最外层的div在每次渲染出来都是没有存在的必要的 - 在vue2就必须要用div包起来,而vue3就用template元素
template元素:
- 目的是将一个整体包裹在一起,元素本身没有特殊含义,最终template是不会渲染的,总结作用就是可以当做不可见的包裹元素,并且在v-if上使用,但是最终template不会被渲染出来,类似于小程序中的block
<div id="app">
<!-- v-if="条件" -->
<div class="info" v-if="Object.keys(info).length">
<h2>个人信息</h2>
<ul>
<li>姓名: {{info.name}}</li>
<li>年龄: {{info.age}}</li>
</ul>
</div>
<!-- v-else -->
<div v-else>
<h2>没有输入个人信息</h2>
<p>请输入个人信息后, 再进行展示~</p>
</div>
</div>
阶段案例:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
img {
width: 200px;
height: 200px;
}
</style>
</head>
<body>
<div id="app">
<div>
<button @click="toggle">切换</button>
</div>
<template v-if="isShowCode">
<img src="https://game.gtimg.cn/images/yxzj/web201706/images/comm/floatwindow/wzry_qrcode.jpg" alt="">
</template>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data() {
return {
isShowCode: true
}
},
methods: {
toggle() {
this.isShowCode = !this.isShowCode
}
}
})
// 2.挂载app
app.mount("#app")
</script>
</body>
</html>
7.3 v-show
v-show和v-if的用法看起来是一致的,也是根据一个条件决定是否显示元素或者组件
<div v-show="isShowCode">
<img src="https://game.gtimg.cn/images/yxzj/web201706/images/comm/floatwindow/wzry_qrcode.jpg" alt="">
</div>
7.4 v-if和v-show的区别
- 用法上的区别:
- v-show是不支持template元素的
- v-show不可以和v-else一起使用
- 本质的区别:
- v-show元素无论是否需要显示到浏览器上,它的DOM实际都是有存在的,只是通过CSS的display属性来进行切换
- v-if当条件为false时,其对应的原生压根不会被渲染到DOM中
- 开发时如何选择:
- 如果我们的原生需要在显示和隐藏之间频繁的切换,那么使用v-show
- 如果不会频繁的发生切换,那么使用v-if