Vue 前端开发(上篇)
❖ 认识Vue.js
❖ Vue常用指令
❖ Vue常用属性
❖ Vue常用指令之流程控制
1 认识 vue
Vue.js(简称 Vue) 是一套用于构建用户界面的渐进式前端框架。
Vue.js 核心实现:
-
响应式的数据绑定:当数据发生改变,视图可以自动更新,不用关心 DOM(可以理解为一个页面) 操作,而专心数据操作。
-
可组合的视图组件:把视图按照功能切分成若干基本单元,可维护,可重用,可测试等特点。
而且当我们后端 api 的数据发生变化就会实时的更新,vue 是一个 js 库
1.1 引入 Vue
使用Vue的四种方式:
-
在 HTML 中以 CDN 包的形式导入
-
下载 JS 文件保存到本地再导入
-
使用 npm 安装
-
使用官方 VueCli 脚手架构建项目(不建议新手直接用)
参考文档:https://v3.cn.vuejs.org/guide/installation.html
1.1.2 hello world 示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试vue</title>
<!-- 导入 vue 库-->
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="hello-vue">
<!-- 两个大括号中间引用在 data 字段里的 massage、hello 变量 -->
<p>{{ message }}</p>
<p>{{ hello }}</p>
</div>
<script>
// 通过 const 关键字定义一个 vue 实例
// data、return 都是 vue 固定语法
const HelloVueApp = {
data(){
return{
// 定义变量
message: 'hello-vue!',
hello: "老张!",
}
}
}
// 创建一个 vue 实例,并将 HelloVueApp 函挂载至上面 id=hello-vue 的 div 标签中
Vue.createApp(HelloVueApp).mount('#hello-vue')
</script>
</body>
</html>
浏览器输出
1.1.3 声明式渲染
Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试vue</title>
<!-- 导入 vue 库-->
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="counter">
<!-- 两个大括号中间引用在 data 字段里的 unter 变量 -->
Counter: {{ counter }}
</div>
<script>
// 通过 const 关键字定义一个 vue 实例
// data、return 都是 vue 固定语法
const HelloVueApp = {
data(){
return{
// 定义变量
counter: 0
}
},
// 实例生命周期中的一个钩子
mounted() {
//
setInterval(()=>{// js 语法,定时器,()=>{} 为匿名箭头函数
this.counter++ // counter 变量每一秒加一,1000 = 1000 毫秒,动态改变 counter 的值
},1000)
}
};
// 创建一个 vue 实例,并将 HelloVueApp 函挂载至上面 id=hello-vue 的 div 标签中
Vue.createApp(HelloVueApp).mount('#counter')
</script>
</body>
</html>
通过浏览器访问可以看到 counter 每次都会动态变化,这就能够说明 vue 是一个响应式的,只要 counter 变量的值改动浏览器的值也会随之变化,因为这里操作的是 vue 实例中的数据,而非操作 html 静态文本
1.2 模板语法
Vue.js 使用了基于 HTML
的模板语法,允许开发者声明式地将 DOM 绑定至底层组件实例的数据。所有 Vue.js 的模板都是合法的 HTML
,所以能被遵循规范的浏览器和 HTML 解析器解析。
数据绑定最常见的形式就是使用“双大括号” 语法在HTML中插入文本:
<span>Message: {{ msg }}</span>
{{msg}}
将被替代对应组件实例中msg属性的值。无论何时,绑定的组件实例上msg属性发生改变,插值处内容都会更新。
2 Vue 常用指令
-
指令介绍
-
v-text
-
v-html
-
v-bind
-
v-on
-
指令缩写
2.1 指令介绍
指令:带有 v- 前缀的特殊属性。只要在 html 标签中带有 v- 那么这就是一个指令
指令的作用:当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM,实际上是与 vue 中的数据产生关系
2.1.1 v-text
v-text 作用与双大花括号作用一样,将数据填充到标签中。但没有闪烁问题(这种一般是数据准备较慢,出现这种问题使用 v-text 即可解决)!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试vue</title>
<!-- 导入 vue 库-->
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="counter">
<!-- 添加 v-text 指定调用 message -->
<p v-text="message"></p>
</div>
<script>
// 通过 const 关键字定义一个 vue 实例
// data、return 都是 vue 固定语法
const HelloVueApp = {
data(){
return{
// 添加 message 变量
message: "v-text 指令"
}
},
};
// 创建一个 vue 实例,并将 HelloVueApp 函挂载至上面 id=hello-vue 的 div 标签中
Vue.createApp(HelloVueApp).mount('#counter')
</script>
</body>
</html>
2.1.2 v-html
某些情况下,从服务端请求的数据本身就是一个HTML代码,如果用双大括号会将数据解释为普通文本,而非HTML代码,为了输出真正的HTML,需要使用v-html指令:
未使用 v-html
指令得到文本格式的 html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试vue</title>
<!-- 导入 vue 库-->
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="counter">
{{msg}}
</div>
<script>
// 通过 const 关键字定义一个 vue 实例
// data、return 都是 vue 固定语法
const HelloVueApp = {
data(){
return{
// 添加 msg 变量,并写入 html 代码
msg: "<span style='color: red'>Hello Vue!</span>"
}
},
};
// 创建一个 vue 实例,并将 HelloVueApp 函挂载至上面 id=hello-vue 的 div 标签中
Vue.createApp(HelloVueApp).mount('#counter')
</script>
</body>
</html>
可以看到 msg 原有的 html 代码直接通过文本格式输出
使用了 v-html
指令解析 html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试vue</title>
<!-- 导入 vue 库-->
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="counter">
<!-- span 标签添加 v-html 指定调用 msg -->
<span v-html="msg"></span>
</div>
<script>
// 通过 const 关键字定义一个 vue 实例
// data、return 都是 vue 固定语法
const HelloVueApp = {
data(){
return{
// 添加 msg 变量,并写入 html 代码
msg: "<h1 style='color: red'>Hello Vue!</h1>"
}
},
};
// 创建一个 vue 实例,并将 HelloVueApp 函挂载至上面 id=hello-vue 的 div 标签中
Vue.createApp(HelloVueApp).mount('#counter')
</script>
</body>
</html>
可以看到字体已经被渲染
2.1.3 v-on
在前端开发中,我们经常监听用户发生的事件,例如点击、拖拽、键盘事件等。在 Vue 中如何监听事件呢?使用 v-on
指令
示例:监听按钮的点击事件
当我们点击这个按钮的时候,能够触发一个操作,该操作能直接调用 js 代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试vue</title>
<!-- 导入 vue 库-->
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="counter">
<!-- 通过 v-on 指令 :click= counter 变量并且 ++ 实现点击按钮每次+1-->
<button v-on:click="counter++">按钮</button>
Counter:{{ counter }}
</div>
<script>
// 通过 const 关键字定义一个 vue 实例
// data、return 都是 vue 固定语法
const HelloVueApp = {
data(){
return{
// 定义 counter 变量
counter:0
}
},
};
// 创建一个 vue 实例,并将 HelloVueApp 函挂载至上面 id=hello-vue 的 div 标签中
Vue.createApp(HelloVueApp).mount('#counter')
</script>
</body>
</html>
默认为 0
当我们点击按钮之后可以看到变为 1,只要点击多次就会累加
2.1.4 v-bind:介绍
v-bind
:用于动态绑定一个或多个属性值,或者向另一个组件传递 props 值(这个后面再介绍)
应用场景:图片地址 src、超链接 href、动态绑定一些类、样式等等
2.1.4.1 绑定 url
在下面的示例中通过在 url 上点击点我,实现跳转至百度
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试vue</title>
<!-- 导入 vue 库-->
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="counter">
<!-- 通过 vue 的 v-bind 指令绑定下面 url 变量实现动态修改 href -->
<a v-bind:href="url">点我</a>
</div>
<script>
// 通过 const 关键字定义一个 vue 实例
// data、return 都是 vue 固定语法
const HelloVueApp = {
data(){
return{
url: "https://www.baidu.com"
}
},
};
// 创建一个 vue 实例,并将 HelloVueApp 函挂载至上面 id=hello-vue 的 div 标签中
Vue.createApp(HelloVueApp).mount('#counter')
</script>
</body>
</html>
点击
跳转成功
2.1.4.2 绑定 Class
操作元素(标签)的 class 和 style 属性是数据绑定的一个常见需求。
例如希望动态切换 class,为 div 显示不同背景颜色,也就是说当用户触发某个操作就实现了其他的页面样式
这个示例中实现绑定一个 class
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试vue</title>
<!-- 导入 vue 库-->
<script src="https://unpkg.com/vue@3"></script>
<!-- 定义 style 然后添加 cc class 并指定背景为 orange,宽高为 200 -->
<style>
.cc{
background: orange;
width: 200px;
height: 200px;
}
/* 定义 active class 颜色为 red ,等会用于下面动态绑定 */
.active {
background: red;
}
</style>
</head>
<body>
<div id="counter" >
<!-- 这里默认绑定了 cc ,但是通过 v-bind 指定 active=isActive isActive=true 的时候实现绑定 active class 从而替换样式-->
<div class="cc" v-bind:class="{active: isActive}">
</div>
<button v-on:click="btn()">新增样式</button>
</div>
<script>
// 通过 const 关键字定义一个 vue 实例
// data、return 都是 vue 固定语法
const HelloVueApp = {
data(){
return{
// 定义 isActive 变量默认为 false,用于下面 btn() 函数中进行判断
isActive: false
}
},
methods:{
btn(){
// this 表示当前 vue 实例,通过 this 后面加上变量名就可以改变对应变量的值
// 判断如果 this.isActive 为真就将其设置为 false
if(this.isActive){
this.isActive = false
// 如果为假就设置为真
} else {
this.isActive = true
}
}
}
};
// 创建一个 vue 实例,并将 HelloVueApp 函挂载至上面 id=hello-vue 的 div 标签中
Vue.createApp(HelloVueApp).mount('#counter')
</script>
</body>
</html>
默认为橘色
点击新增样式变为红色
再次点击变为橘色
2.1.4.3 v-bind:绑定Style
v-bind:style
的对象语法看着非常像 CSS,但其实是一个JavaScript 对象。CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试vue</title>
<!-- 导入 vue 库-->
<script src="https://unpkg.com/vue@3"></script>
<!-- 定义 style 然后添加 cc class 并指定背景为 orange,宽高为 200 -->
<style>
.cc{
background: orange;
width: 200px;
height: 200px;
}
/* 定义 active class 颜色为 red ,等会用于下面动态绑定 */
.active {
background: red;
}
</style>
</head>
<body>
<div id="counter" >
<!-- 通过 v-bind 标签绑定 style 并且元素绑定的是下面 vue 中定义的 background 变量-->
<div v-bind:style="{background: background}" class="cc">
</div>
</div>
<script>
// 通过 const 关键字定义一个 vue 实例
// data、return 都是 vue 固定语法
const HelloVueApp = {
data(){
return{
// 定义 background 变量职位 blue 蓝色
background: "blue",
}
},
};
// 创建一个 vue 实例,并将 HelloVueApp 函挂载至上面 id=hello-vue 的 div 标签中
Vue.createApp(HelloVueApp).mount('#counter')
</script>
</body>
</html>
通过这种方式就实现了对 style 的绑定,并实现了对后端 background 的绑定
2.2 指令缩写
v- 前缀作为一种视觉提示,用来识别模板中 Vue 特定的 属性。
但对于一些频繁用到的指令来说,就会感到使用繁琐。
因此,Vue 为 v-bind 和 v-on 这两个最常用的指令,提供了特定简写:
- v-bind缩写 :
<!-- 完整语法 -->
<a v-bind:href="url"> ... </a>
<!-- 缩写 :href 即可,其他标签写法相同 -->
<a :href="url"> ... </a>
<!-- 动态参数的缩写 -->
<a :[key]="url"> ... </a>
示例:
- v-on缩写:
<!-- 完整语法 -->
<a v-on:click="doSomething"> ... </a>
<!-- 缩写 @click 即可-->
<a @click="doSomething"> ... </a>
<!-- 动态参数的缩写 -->
<a @[event]="doSomething"> ... </a>
示例:
3 Vue 常用属性
-
数据属性
-
方法
-
计算属性
-
监听属性
3.1 数据属性
组件的 data 选项是一个函数。Vue 会在创建新组件实例的过程中调用此函数。它应该返回一个对象,然后 Vue 会通过响应性系统将其包裹起来,并以 $data
的形式存储在组件实例中。为方便起见,该对象的任何顶级“属性”也会直接通过组件实例暴露出来:
参考文档:https://v3.cn.vuejs.org/guide/data-methods.html#data-property
如下图:
可以看到这里有个 data 函数,并且有个 return,该 return 就是实现将我们定义在里面的变量数据进行返回。
当我们在页面执行操作的时候,vue 都会将 data 中写的数据全局暴露至 div 中的各类标签中实现引用,当然也可以使用 $data
来引用个别数据。
$data
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试vue</title>
<!-- 导入 vue 库-->
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="counter" >
{{ msg }}
</div>
<script>
// 通过 const 关键字定义一个 vue 实例
// data、return 都是 vue 固定语法
const HelloVueApp = {
data(){
return{
msg:"hello vue!"
}
},
};
// 创建一个 vue 实例,并将 HelloVueApp 函挂载至上面 id=hello-vue 的 div 标签中
// 定义 vm 变量
const vm = Vue.createApp(HelloVueApp).mount('#counter')
// console 输出
console.log("$data: "+vm.$data.msg)
console.log("全局: "+vm.msg)
</script>
</body>
</html>
浏览器 console 访问实现访问
3.2 方法
方法(methods):处理数据的函数。在 methods 选项中定义的函数称为方法。
3.3 计算属性
计算属性(computed):根据所依赖的数据动态显示新的计算结果。
3.3.1 默认方式计算
这种方式会对性能有所影响
示例:需要在 {{}}
里添加计算再展示数据,例如统计分数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试vue</title>
<!-- 导入 vue 库-->
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="counter" >
<!-- 三个学科变量相加 -->
总分: {{ math+language+english }}
</div>
<script>
// 通过 const 关键字定义一个 vue 实例
// data、return 都是 vue 固定语法
const HelloVueApp = {
data() {
return {
// 这里分别定义了数学、语文、英语 三个学科变量
math:90,
language: 70,
english:60,
}
},
};
// 创建一个 vue 实例,并将 HelloVueApp 函挂载至上面 id=hello-vue 的 div 标签中
Vue.createApp(HelloVueApp).mount('#counter')
</script>
</body>
</html>
3.3.2 通过 computed 方法实现
computed 计算属性,该属性其实就是做了一个缓存
示例:通过 computed方法实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试vue</title>
<!-- 导入 vue 库-->
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="counter" >
<!-- 直接调用 sum 函数-->
总分: {{ sum }}
</div>
<script>
// 通过 const 关键字定义一个 vue 实例
// data、return 都是 vue 固定语法
const HelloVueApp = {
data() {
return {
// 这里分别定义了数学、语文、英语 三个学科变量
math:90,
language: 70,
english:60,
}
},
// 指定 computed 方法
computed:{
// 定义 sum 函数,并且通过 this 关键字调用我们在 data 中定义的数据本身
sum: function () {
// return 的时候直接相加
return this.math+this.language+this.english
}
},
};
// 创建一个 vue 实例,并将 HelloVueApp 函挂载至上面 id=hello-vue 的 div 标签中
Vue.createApp(HelloVueApp).mount('#counter')
</script>
</body>
</html>
computed 属性的好处就是做了缓存,如果说当这个计算的值还是上一次的值,那么直接就从缓冲读取,不用再重新计算,因为重新计算是需要耗用 cpu 和 内存
小结:计算属性一般就是用来通过其他的数据算出一个新数据,而且它有一个好处就是,它把新的数据缓存下来了,当其他的依赖数据没有发生改变,它调用的是缓存的数据,这就极大的提高了我们程序的性能。
而如果写在methods里,数据根本没有缓存的概念,所以每次都会重新计算。这也是为什么不用methods的原因!
3.4 监听属性
监听属性(watch):是一个观察动作,监听data数据变化后触发对应函数,函数有newValue(变化之后结果)和oldValue(变化之前结果)两个参数。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
监听属性简单来讲就是当数据变化时才执行
示例:监听变化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试vue</title>
<!-- 导入 vue 库-->
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="counter" >
消息: {{ message }} <br>
观察的消息:{{ NewMessage }} <br>
<!-- 点击该按钮触发 methods 中的 btn() 函数 -->
<button @click="btn">改变消息的值</button>
</div>
<script>
// 通过 const 关键字定义一个 vue 实例
// data、return 都是 vue 固定语法
const HelloVueApp = {
data() {
return {
message:"hello vue!",
// 拿到的新值并在页面中展示
NewMessage: '',
OldMessage: ''
}
},
// 该函数修改了 data.message 的值为 hello go
methods: {
btn () {
this.message = 'hello go!'
}
},
// 定义 watch 属性关键字
watch: {
// 函数的名字就是上面 data 数据中的变量名,更具对应的 key 进行监控,当 message 的值发生变化执行该函数
// 该函数默认有两个值,一个为新值另一个为旧值
// 第一个参数为新,第二个参数为旧
message(newValue,oldValue) {
// 将新值赋值给 NewMessage 变量
this.NewMessage = newValue
}
},
};
// 创建一个 vue 实例,并将 HelloVueApp 函挂载至上面 id=hello-vue 的 div 标签中
Vue.createApp(HelloVueApp).mount('#counter')
</script>
</body>
</html>
浏览器访问当前观察的消息为空
点击改变消息的值按钮就变为了 hello go
在以后的项目中从服务端获取的数据会放到 data 中,如果说以后某一个数据被改变了值。那么就可以通过这种方式来监听上面数据,当数据发生变化之后就会执行某个操作
4 Vue常用指令之流程控制
-
v-if
-
v-show
-
v-for
4.1 v-if、v-else、v-else-if
4.1.1 v-if 演示
示例:判断一个元素是否显示
这里我将 seen 默认值等于 true 所以浏览器就会显示 p
标签中的内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="hello-vue">
<!-- 在该标签添加 v-if="seen" 如果 seen=true 的话就会显示 p 标签内容,如果等于 false 就不会显示 -->
<p v-if="seen">现在你看到我了</p>
</div>
<script>
const HelloVueApp = {
data() {
return {
// seen 用于判断 p 标签是否显示,这里可以判断是其他标签但是我这里用 p 用进行演示
seen: true
}
}
}
Vue.createApp(HelloVueApp).mount("#hello-vue");
</script>
</body>
</html>
浏览器访问:
接着我将代码中的 seen
改为了 false
浏览器刷新可以看到没有显示
4.1.2 v-else 演示
演示:这里可以看到 seen
默认为 false
,也就是 p
标签中的内容为 现在你看到我了 无法显示,但是在通过 v-else
就输出内容 看不到我了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="hello-vue">
<!-- 在该标签添加 v-if="seen" 如果 seen=true 的话就会显示 p 标签内容,如果等于 false 就不会显示 -->
<p v-if="seen">现在你看到我了</p>
<!-- 添加 v-else 判断如果为 seen=false 就输出下面内容 -->
<p v-else>看不到我了</p>
</div>
<script>
const HelloVueApp = {
data() {
return {
// seen 用于判断 p 标签是否显示,这里可以判断是其他标签但是我这里用 p 用进行演示
seen: false
}
}
}
Vue.createApp(HelloVueApp).mount("#hello-vue");
</script>
</body>
</html>
浏览器测试:
4.1.3 v-if 结合 template 使用
template
:专门用来显示模板的标签,比如前端框架都会使用到该标签
v-if
指令必须将它添加到一个元素上。如果想切换多个元素呢?
此时可以把一个<template>
元素当做不可见的包裹元素,并在上面使用v-if
。最终的渲染结果将不包含<template>
元素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="hello-vue">
<!-- 在该标签添加 v-if="seen" 如果 seen=true 的话就会显示 template 标签内容,如果等于 false 就不会显示 -->
<template v-if="seen">
<h1>标题</h1>
<p>段落</p>
</template>
</div>
<script>
const HelloVueApp = {
data() {
return {
// seen 用于判断 template 标签是否显示,这里可以判断是其他标签但是我这里用 template 用进行演示
seen: true
}
}
}
Vue.createApp(HelloVueApp).mount("#hello-vue");
</script>
</body>
</html>
可以看到 template
用法中和上面的 p
标签中用法相同,所以这里不在演示 if-else
的用法
4.1.4 多分支判断
所谓的多分支其实就是当 v-if=true
就等于某个内容,如果 v-if=false
就等于其他的内容
在这个示例中我将在 date
函数里面定义 type
字段,也就是说如果 A 就在浏览器显示 type是AA
;如果是 type=B
就在浏览器显示 type是BB
;若两个都不是则在浏览器输出 type 什么都不是
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="hello-vue">
<!-- 这里我定义了三个 if 的多分子,分别是 v-if=" type == 'A' " ; v-else-if=" type == 'B' ;
v-else 用于多分支判断-->
<div v-if=" type == 'A' ">
<p>type是AA</p>
</div>
<div v-else-if=" type == 'B' ">
<p>type是BB</p>
</div>
<div v-else>
<p>type什么都不是</p>
</div>
</div>
<script>
const HelloVueApp = {
data() {
return {
// 这里我先定义 type='A'
type: 'A',
}
}
}
Vue.createApp(HelloVueApp).mount("#hello-vue");
</script>
</body>
</html>
这里我将代码改为 type='B'
浏览器刷新
这里我将代码改为 type='111'
浏览器刷新
总结:
我们可以在浏览器中通过 F12
查看元素看到,浏览器的源码中只显示了 <p>type什么都不是</p>
,而没有将其他两个 P
标签进行显示
这就说明了,if 是移除或者是添加的一个动作
4.2 v-show
v-show:标签类似切换的效果,与 if
有点类似,但是与 if 不同的是会将其显然到 html 中,就是当我们要切换这个元素的话,是不会像上面 if
那样在浏览器源码中将内容删除掉,这才是真正意义上的切换
v-show:另一个用于条件性展示元素的指令,与v-if不同的是,v-show的元素始终会被渲染并保留再DOM中,所以v-show只是简单地切换元素的display CSS属性。
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="hello-vue">
<!-- 通过 v-show 如果为 true 浏览器输出你看到我了,如果为 false 则输出你看不到了 -->
<div >
<p v-show="seen">你看到我了</p>
<p if-else>你看不到了</p>
</div>
<script>
const HelloVueApp = {
data() {
return {
// 这里我先定义 seen=false
seen: false,
}
}
}
Vue.createApp(HelloVueApp).mount("#hello-vue");
</script>
</body>
</html>
浏览器显示,可以看到我在上面的代码中将 seen 定义为 false ,但是在浏览器的元素中依旧能够看到 <p v-show="seen">你看到我了</p>
的内容,只是给 p
标签加了一个 display: none
其实就是将 p
标签做了一个隐藏动作
v-show
与 v-if
的区别:
在后续写项目代码的时候使用 v-show
在不同的元素之间切换的话会更加方便,若使用 v-if
进行元素的切换就会将元素直接移除
比如有的场景需要将元素切换分为多步骤,如点击第二步,那么 v-if
就会将第一步骤的元素进行隐藏,所以在后续的步骤中就无法获取第一步骤的数据,但是使用 v-show
就很好解决这种问题
4.3 v-for
v-for:可以基于一个数组一个对象进行遍历和渲染
可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items
形式的特殊语法,其中 items
是源数据数组,而 item
则是被迭代的数组元素的别名
在下面我将举几个例子,如何实现遍历数组和对象,一般情况下我要将数据渲染到页面中大部分都是从服务端进行动态请求,比如前面学习的 Ajax 就会将服务端数据进行获取,然后在渲染到页面中。
而我们在获取服务端数据的时候都是 json 格式,将 json 转换为 js 对象的话里面无非就是一些数组、对象,所以这个时候就需要对 js 中的这些数组、对象进行遍历,并放置前端代码中并在页面进行显示
4.3.1 v-for 遍历数组
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="hello-vue">
<div >
<!-- 像这种数组一般通过列表来进行展示,所以就需要 ul 和 li 标签 -->
<ul>
<!-- 通过 v-for 指令遍历 myArr 数组,其中 i 就是遍历之后对应的元素 -->
<li v-for="i in myArr">
{{ i }}
</li>
</ul>
</div>
</div>
<script>
const HelloVueApp = {
data() {
return {
// 定义数组
myArr: [
'主机',
'显示器',
'键盘',
]
}
}
}
Vue.createApp(HelloVueApp).mount("#hello-vue");
</script>
</body>
</html>
浏览器访问
但是我们也可通过 for 循环获取到对应的索引如下代码截图:
如果说在遍历的时候赋予的变量是两个值的话,一般需要添加个小括号来定义获取值得变量,而第一个变量为索引,第二个变量则就是对应的元素本身
浏览器刷新
4.3.2 v-for 遍历对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="hello-vue">
<div >
<!-- 像这种数组一般通过列表来进行展示,所以就需要 ul 和 li 标签 -->
<ul>
<!-- 通过 v-for 指令遍历 myObject 对象,其中 k 就是遍历之后对应的 key v 就为 value -->
<li v-for="(k,v) in myObject">
{{ v }} {{k}}
</li>
</ul>
</div>
</div>
<script>
const HelloVueApp = {
data() {
return {
// 定义对象
myObject: {
name:"张三",
age:"21",
sex:"男"
}
}
}
}
Vue.createApp(HelloVueApp).mount("#hello-vue");
</script>
</body>
</html>
浏览器刷新
4.3.3 v-for:维护状态(重要)
维护状态:
该属性一定要加上,否则会造成一些语法错误,就不会让代码正常运行
当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一的 key 属性:
这个是 vue 规定,如果使用 for 循环就需要在属性上添加 key,来绑定属性,这个属性就是用来跟踪 for 的数据变化
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="hello-vue">
<div >
<!-- 像这种数组一般通过列表来进行展示,所以就需要 ul 和 li 标签 -->
<ul>
<!-- 如果是遍历数组将 key=i ,i 就为数组中的下标 -->
<li v-for="(c,i) in myArr" :key="i">
{{ i }} {{c}}
</li>
<br>
<!-- 如果是遍历对象将 key=k ,k 就为对象中的key -->
<li v-for="(k,v) in myObject" :key="k" >
{{ v }} {{k}}
</li>
</ul>
</div>
</div>
<script>
const HelloVueApp = {
data() {
return {
// 定义数组
myArr: [
'主机',
'显示器',
'键盘',
],
// 定义对象
myObject: {
name:"张三",
age:"21",
sex:"男"
}
}
}
}
Vue.createApp(HelloVueApp).mount("#hello-vue");
</script>
</body>
</html>
4.3.4 v-for:选择列表综合案例
获取用户选择并赋值另一个变量再实时浏览器展示:
也就是当用户在页面上通过下拉框选中一个对象,则就就对应对象的数据进行渲染输出
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="hello-vue">
<!-- 定义 select 标签实现下拉框,并且 name=users 用来获取数据 -->
<!-- @change 用于在下拉框这种场景中选择之后就触发一个事件,这里的作用在于获取 user 的 id 以便 p 标签渲染 -->
<!-- selectUser($event) 获取定义的 selectUser 方法中,$event 是一个内置变量可以理解为当前 select 本身,并获取事件内容 -->
<select name="users" @change="selectUser($event)">、
<!-- 该标签用于优化显示,提示下拉框默认输出未选择 value= None -->
<option value="None">未选择</option>
<!-- option 标签定义下拉框的值,这里通过 for 遍历 select 标签中在 data 获取到的数据 -->
<!-- :value="row.id" 获取 users 中的 id , : 是做一个绑定,将获取的 id 绑定到 value 标签上 -->
<option v-for="row in users" :value="row.id" :key="row.id">{{row.name}}</option>
</select>
<p>当前选择的用户ID:{{selectUserId}}</p>
</div>
<script>
const HelloVueApp = {
data() {
return {
// 定义 users 数组,并且在该数组中的值为 3 个对象字典
users: [
{id:1,name:"张三"},
{id:2,name:"李四"},
{id:3,name:"王麻子"}
],
// 定义 selectUserID 变量用于临时存储 users 的值,以便上面 p 标签引用
selectUserId: ''
}
},
// 定义方法
methods: {
selectUser(event){
console.log(event.target.value) // event.target.value 就是获取事件的值,event 事件对象
// 将 data 中的 selectUserId 变量赋值为 event.target.value
this.selectUserId = event.target.value;
// 如果获取 value=None 这赋值 selectUserId=未选择
if(event.target.value == "None" ) {
this.selectUserId = "未选择!"
}
}
}
};
Vue.createApp(HelloVueApp).mount("#hello-vue");
</script>
</body>
</html>
浏览器显示:默认提示未选择
选择:张三,可以在 console 看到 value = 1,用户 id=1 成功获取
选择:未选择,可以在 console 看到 value = None,用户 id=未选择 成功获取