一、前言
通过前面两章,我们已经了解了vue的基本结构组成,从本文开始,我们就正式踏入vue的语法学习。
这里提醒一下,当运行命令npm run dev
后,你在项目中对代码文件做出的一切改动都会直接反应到页面上。
不过前提是你编辑文件后按了Ctr+S
保存文件,又或者开启了vscode中“自动保存”文件的功能,否则是看不到效果的。
二、响应式
vue中最重要且最基础的内容就是“响应式”,这部分的内容你同样也可以在官方文档中找到:
不过官方教程的目标群众是给对前端有一定基础的人看的,新手一上去很可能就会被其各种专业名词搞得头昏脑胀。
说简单点响应式其实就是一个更高级的变量,比如在前文中我写过这样的代码:
如果你写普通的变量:
let msg="hello world,vue"
其实也能用上图中的语法将其显示到html中:
<div>
{{ msg }}
</div>
但不同的地方在于,如果之后你修改了msg
的值,比如在某个点击事件中将msg
修改为了"hello"
,html中的字符串是不会变的,依旧还是前面的"hello world,vue"
。
而响应式变量就比较高级了,它就是用来弥补这一缺点的, 无论你怎么变,它都会实时显示到html页面中。
1.ref
响应式变量的创建在vue中有两种方式,第一种就是这里用到的ref
函数,你可以直接从vue
中将其引入。
而使用方法就是用它将数据包括起来即可:
const a1=ref(10); //数字
const a2=ref(true); //bool
const a3=ref("string"); //string
const a4=ref(['1','2']); //array
const a5=ref({ //object
msg:'111',
age:999
});
const a6=ref(); //undefine
const a7=ref(null); //null
同时要注意我这里的写法,因为ref
函数返回的是一个特殊的对象,并不是其原始的数据,所以我们一般都是使用const
声明的。
正如这里所说,它是一个对象,我们的数据其实是放在该对象上的属性value
上的,所以如果你想要在js代码中修改、访问该数据,就必须通过value
属性进行访问,以上面声明好的响应式变量为例:
a1.value=20;
a2.value=false;
a3.value="test";
a4.value[0]='3';
a5.value.msg="222";
a6.value="string";
a7.value=999;
上面分别是各种数据类型的访问、修改方式,可以看到,和正常的数据相比,其实也是中间多了一个value
属性而已。
而之所以在html中我们不需要写value
,是因为vue自动帮我们解引用了。
ref
函数名实际上是reference
单词的缩写,也就是“引用”的意思。
当然,我们也可以自己手动对其解引用,使用到的函数为unref
:
console.log(a1.value);
console.log(unref(a1));
该函数就是专门用来解引用、获取其原始数据对象的,比如上面两句代码的效果就是完全一样的。
不过要注意,解引用之后得到的值是只读的,也就是不能对其进行修改,如果你希望修改,那还是要使用value
属性进行。
所以可能很多情况下都只会在响应式的对象上对其使用解引用,方面书写。
下面对其代码演示一下:
可以看到,两个打印语句打印出来的内容都是一样,同时修改响应式变量的值也会直接反应到页面标签上。
当然,这里举的例子并不明显,因为这种情况下即使只是普通变量修改依旧会反映到html标签上,原因在于这里同在初始化的代码块中,执行完成后msg
变量就直接是hello
了,显示的自然也是hello
。
而如果是在点击事件中修改两者的数据,就能非常清晰的看出普通变量与响应式变量两者之间的差距了。
2.reactive
创建响应式变量的方式在vue中有两种,上面ref是第一种,而第二种就是这里的reactive
函数。
不同于前面ref
,reactive
创建的响应式变量主要有两个区别:
- 不需要
value
属性、不需要解引用,可以直接像正常变量一样修改、访问。 - 只能作用于数组、对象这种复杂的数据类型。
除了这两点外,其它的使用方式和前面的ref
其实都是一样的:
可以看到,对于对象而言,此时无论是对其访问或者修改都和普通的对象变量一样,但不同之处在于此时它是响应式的,只要其上的数据变量,就会立即反映到html标签中去。
这里使用的对象,对于数组也是同理,但要注意的是,不能将其作用在普通、单一的数据类型上,比如字符串、数字、布尔等。
3.总结
简单总结一下,所谓响应式,其实你就可以将其看做是vue提供的一种变量,只要变量中的值一变,就会立马反应到页面上。
平时使用的时候基本也没什么太多需要纠结的,只要你需要将某个变量显示到html页面上,那么直接就使用ref
函数创建即可,它是通用的。
只不过使用它的使用必须要记住,在html中把它当作普通变量使用即可,只有在js代码中才需要将其当作一个对象看待,我们的实际数据是放在该对象上的value
属性上的。
而对于对象、数组这种数据类型使用它会比较麻烦,这是你可以使用reactive
对其进行简化,可以让你少写一个value
属性。
总得来说,这两者并非是谁取代谁,对于基本数据类型而言,你只能使用ref
,而对于复杂的类型,比如对象、数组等等,就可以选择使用reactive
简化代码。
如果你就是不希望使用ref
要多写一个value
属性才能修改、访问值,还有另外一种常见的做法是将多个需要用ref
绑定的基本数据类型组合成为一个对象,然后对该对象使用reactive
就可以了。
三、模板语法
上面我们提到的响应式变量之所以能够实时将数据刷新到页面上,用的是两个大括号{{}}
将其包裹起来。
而这就是本节要介绍的“模板语法”,其中{{}}
又被称为“文本插值”,这部分内容你同样也可以在官方文档中找到:
“文本插值”很简单,说白了就是官方定义的两个大括号写法{{}}
,它可以用来将script
块中的变量值显示到html页面上,如果这个变量是响应式的变量,那它还会实时跟踪变化。
事实上模板语法并不是仅仅只能用于显示变量值,它甚至还能执行一段js表达式,就像下面这样:
上图代码中的{{}}
中写了一个js中的三元运算符,只不过我直接将变量换为了确定的true
,也就是最终的渲染结果为YES
。
但要注意的是,它只能执行一句表达式,即使是许多级函数链接都行,就像下面这样:
如果你想要执行复杂的操作,它也可以调用函数:
以上就是模板语法中“文本”差值语法的基本用法,简单点来说就是{{}}
可以实现在html中执行一句js语句、并显示结果。
除此之外,模板语法还涉及html标签渲染、以及便签的属性绑定。
首先是标签渲染,比较简单,其实就等价于原生的js代码:
let ele=document.querySelector('#test');
ele.innerHTML="<span>测试</span>"
通过标签对象上的innerHTML
属性,就可以将html字符串直接渲染为其子标签,这个特性在很多时候都非常有用。
而vue就通过了v-html
这个指令替换了上面的代码,使其更加容易被使用:
可以看到,上图中实现的效果和前面的代码是一样的,但此时我们却可以将其设置为响应式的变量,此时如果我们想要修改该div
标签内部的内容时,只需要修改变量test_label
中保存的标签字符串。
最后就是属性绑定。
总的来说,一个标签无非就是两个部分:标签内部的内容、标签本身的各种属性。
{{}}
与v-html
这两个语法都可以让我们动态设置标签内的内容,最后我们还需要学习一下如何动态设置某个标签上的属性,也被称为“属性绑定”。
举一个最简单的例子,图片标签img
,如果我想要让它更换图片链接,使用纯js代码的话就得写一长串代码去动态更改它的src属性对吧!
而在vue中使用属性绑定一切都变得简单起来了,还是像前面一样,定义一个响应式变量:
<script setup>
import { ref } from 'vue';
const link=ref("www.baidu.com/12345.png");
</script>
当然了,这里的链接是随便写的,然后重点来了,在html
中就要写为下面这样:
<template>
<img :src="link">
</template>
是不是非常的简单,你只需要在想要动态设置属性名的前面添加一个冒号:
即可,比如这里的img
标签上的src
属性,这里就是再前面添加:
,然后让其等于我们的响应式变量,就能完成动态属性绑定。
此后,如果你想要更改这个img
标签要显示的图片,就可以直接更改这个响应式变量的值即可!
这个语法与前面的{{}}
语法差不多,里面同样可以写一句表达式、甚至调用函数,只是要注意的是前面有一个冒号。
表达式示例:
<img :src="true?'YES':'NO'">
函数示例:
四、类与样式绑定
这部分的内容其实和上面刚提到的属性绑定是一样的,只是绑定标签的属性而已。
只不过特殊在于两个属性是“类”和“样式”,这是所有标签都有的两个属性。
毕竟vue是前端框架,好看第一位,类和样式这两个属性就是决定控制、调整标签美观的两个非常重要的属性。
首先聊聊绑定类,与前面的绑定标签属性其实是一样的:
一个比较常见的用法是切换主题,就像上面代码那样:
- 首先在css中写两个类的样式
- 通过动态修改标签的类,从而让其在两个样式之间进行切换
而改变的方式也很简单,直接改变上图代码中的theme这个变量值的字符串即可。
除此之外,另一个用途就是标记某个类是否启用:
注意这里与前面的不同之处,这里让其等于的是一个对象,需要用一个大括号将其包裹起来。
前面的键是你想要绑定的类名,后面的值为一个布尔类型,只有后面的值为true
,前面的键才会被绑定到标签之上。
既然是类,当然就可以绑定多个了,所以上图代码中我绑定了两个键值对,前面的键分别为dark、light,如果后面的值为true
,那么该键就会作为类名添加到该标签上。
此时其实现的效果其实和前面是一样的。
绑定类主要是适用于那种样式变化有限的,比如主题色就只有两个,那你就写两个类,然后更改类名即可。
但有些属性却不一样,比如我写过的一个看小说的软件,需要让用户动态调整字体的大小、行高。
这时候用类绑定肯定就不行了,最简单直接的方式是直接用js
查询到所有行,然后动态更改它们的相应属性。
这样当然可以,但既然我们都用vue了,也没必要再自己去亲力亲为这种麻烦事情,而这就可以使用样式绑定的方法来解决。
它用起来和上面的类绑定非常像,同样是一个对象:
<template>
<p :style="{'font-size':font_size+'px'}"></p>
</template>
<script setup>
import { ref} from 'vue';
const font_size=ref(16);
</script>
此时你就可以直接更改变量font_size
的值来动态更改p标签的字体大小了,是不是相当方便!
正如前面说的,它是一个对象,所以你可以绑定多个样式。
太多写在标签中不好看?你也可以将其放在一个响应式对象中:
<template>
<p :style="p_config"></p>
</template>
<script setup>
import { reactive, ref} from 'vue';
const p_config=reactive({
'font-size':font_size+'px',
'font-weight':font_weight
})