(注,在软件中下载 live server 这个插件,以便运行,可使用右键点击相应插件名字或者快捷键Alt+L/Alt+O进行运行
之前的html,js,css都是使用 open in browser 这个插件运行的,可使用右键点击相应插件名字或者快捷键 Alt+B进行运行)
一、Vue3的响应式数据
在 Vue 3 中,响应式数据的定义主要通过reactive函数和ref函数等方式来实现的
(注:记得写完代码后,把内容暴露出来,也就是下面红色部分内容)
ref:该函数可以用来创建一个响应式的数据,它可以接受基本数据类型的值(如数字、字符串等)或者对象类型的值。ref创建的值在模板中使用时会自动解包,方便进行数据绑定等操作。本质上,ref创建的是一个包含 value属性的对象,对响应式数据的读写实际是通过操作这个 value属性来进行的
以下为例子代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue 3 Ref Example</title>
//链接是在vue官网上找的,必须使用,要不然会报错,常见的还有
//https://unpkg.com/vue@3/dist/vue.esm-browser.js
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<p>{{ count }}</p>
<button @click="increment">Increment</button>
</div>
<script>
const { createApp, ref } = Vue;
const app = createApp({
setup() {
const count = ref(0);
const increment = () => {
count.value++;
};
return {
count,
increment
};
}
});
app.mount('#app');
</script>
</body>
</html>
运行结果(记得按F12调出控制台看有没有报错):
按 increment 按钮可使数字增加:
reactive:该函数用于将一个普通的 JavaScript 对象转换为响应式对象。它会自动对对象的属性进行 “响应式” 处理,意味着当这些属性的值发生改变时,会自动触发与之绑定的 DOM 更新等相关响应操作
以下为例子代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>让数据变成响应式</title>
</head>
<body>
<div id="app">
<p>{{ msg }}</p>
<p>{{ web.title }}</p>
<p>{{ web.url }}</p>
<p>{{number}}</p>
<button @click="change">点击我更换网址</button>
</div>
<script type="module">
//也可像作者一样先在官网下载,再拖进同一文件
import {createApp, ref, reactive} from "./vue.esm-browser.js" //模块化开发方式
createApp({
setup(){
const web = reactive({
title: "百度一下,你就知道",
url: "www.baidu.com"
});
console.log(typeof web, web);
const change = () => {
web.url += "-->数据被修改";
}
// 返回一个对象类型的数据
return { msg: "成功创建第一个Vue应用程序!" ,
web,
change
}
}
}
).mount("#app");
</script>
</body>
</html>
运行结果:
二、Vue3的v-on
在 Vue 3 中,v-on是一个用于绑定事件监听器的指令,主要用于在 DOM 元素上监听 DOM 事件,比如 click(点击事件)、keydown(键盘按下事件)、mouseover(鼠标移过事件)等等众多常见的浏览器原生事件,当对应的事件在该 DOM 元素上被触发时,就会执行与之绑定的 JS 代码
使用@符号来替代 v-on,例如绑定一个点击事件来调用名为 handleClick 的方法,可以写成@click="
handleClick"
,这种缩写方式在实际开发中使用得非常频繁,代码看起来也更加简洁清晰
以下为示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>绑定事件</title>
</head>
<body>
<div id="app">
<h3>{{ msg }}</h3>
<h3>{{ web.url }}</h3>
<h3>{{ web.user }}</h3>
<h3>{{ sub(100, 20) }}</h3>
<!-- v-on:click 表示在 button 元素上监听 click 事件 -->
<button v-on:click="edit">修改</button> <br>
<!-- @click 简写形式 -->
<button @click="add(20, 30)">加法</button> <br>
<!--
enter space tab 按键修饰符
keyup是在用户松开按键时才触发
keydown是在用户按下按键时立即触发
-->
<!-- 回车 <input type="text" @keyup.enter="add(40, 60)"> <br>
空格 <input type="text" @keyup.space="add(20, 30)"> <br>
Tab <input type="text" @keydown.tab="add(10, 20)"> <br>
w <input type="text" @keyup.w="add(5, 10)"> <br> -->
<!-- 组合快捷键 -->
<!-- Ctrl + Enter <input type="text" @keyup.ctrl.enter="add(40, 60)"> <br>
Ctrl + A <input type="text" @keyup.ctrl.a="add(20, 30)"> -->
</div>
<script type="module">
import { createApp, reactive, ref } from './vue.esm-browser.js'
createApp({
setup() {
let msg = "成功启动!!!";
const web = reactive({
title: "百度",
url: "baidu.com",
user: 0
});
const edit = () => {
web.url = "www.baidu.com"
//错误示例 不能直接改变msg的值,因为msg是一个普通变量, 不是响应式数据
msg = "永夜星河"
//从控制台打印信息可以知道确实改变了,但是模板没有响应更新(非响应式数据)
console.log(`msg修改为: ${msg}`);
}
const add = (a, b) => {
web.user += a + b
}
const sub = (a, b) => {
return a - b
}
return {
//普通变量, 非响应式数据, 在模板中普通变量不会自动更新
msg,
//响应式数据
web,
//方法
edit,
add,
sub,
}
}
}).mount("#app")
</script>
</body>
</html>
运行结果:
三、Vue3的v- if
v- if:指令根据表达式的值的真假来决定是否渲染对应的元素及其包含的内容。如果表达式的值为true,则元素会被渲染到 DOM 中;如果表达式的值为flase,该元素及其内部所有子元素将不会被添加到 DOM 里,相当于在 DOM 结构中不存在这些元素(与之对比的是v-show,v-show只是通过设置display样式来控制元素显示隐藏,元素始终在 DOM 中)
基本语法形式是在 HTML 标签上添加v- if指令,然后紧跟一个 JS 表达式
以下为示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>节点的条件渲染</title>
</head>
<body>
<div id="app">
<h3>显示状态: {{ web.show }}</h3>
<!-- Vue处理v-if变化时,是通过删除节点实现隐藏的(可以通过F12检查源代码,当点击时,源码会删除节点) 。
当遇到需要频繁显示和隐藏的场景时,不是合使用v-if, 因为频繁增删节点,会导致渲染效率下降 -->
<p v-if="web.show">v-if</p>
<button @click="toggle">切换显示状态</button>
<hr>
<h3>{{ web.user }}</h3>
<p v-if="web.user < 100">新网站</p>
<p v-else-if="web.user >= 100 && web.user < 1000">优秀网站</p>
<p v-else-if="web.user >= 1000 && web.user < 10000">资深网站</p>
<p v-else>超级网站</p>
<button @click="add_user">增加用户</button>
</div>
<script type="module">
import { createApp, reactive, ref } from './vue.esm-browser.js'
createApp({
setup() {
const web = reactive({ // 响应式数据
show: true,
user: 500
});
const toggle = () => {
web.show = !web.show; // 这个布尔变量被切换后,模板中用到的地方会自动更新,进而被v-show捕获
}
const add_user = () => {
web.user += 1000;
}
return {
web,
toggle,
add_user
}
}
}).mount("#app");
</script>
</body>
</html>
运行结果:
四、Vue3的v-for
v-for是一个指令,用于基于一个数组或者对象等可迭代的数据来源来循环渲染一个元素或一组元素多次,它是实现列表渲染的关键工具
以下为示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>遍历指令</title>
<style>
.textColor{
color: red;
}
</style>
</head>
<body>
<div id="app">
<!-- 遍历对象的值 -->
<h4>遍历对象的值。</h4>
<ul>
<li v-for="value in data.user">
{{ value }}
</li>
</ul>
<!-- 遍历对象的值和索引。 注意:写指令时,先值后索引 -->
<h4>遍历对象的值和索引。 注意:写指令时,先值后索引</h4>
<ul>
<li v-for="(value, index) in data.number">
{{ index }} : {{ value }}
</li>
</ul>
<!-- 遍历对象的值和键。 注意:写指令时,先值后键 -->
<h4>遍历对象的值和键。 注意:写指令时,先值后键</h4>
<ul>
<li v-for="(value, key) in data.user">
{{ key }} : {{ value }}
</li>
</ul>
<!-- 遍历对象的值,键和索引。 注意:写指令时,先值再键后索引 -->
<h4>遍历对象的值,键和索引。 注意:写指令时,先值再键后索引</h4>
<ul>
<li v-for="(value, key, index) in data.user">
{{ index }} : {{ key }} : {{ value }}
</li>
</ul>
<h4>指令嵌套: 先用v-for指令遍历对象,然后展示符合v-if条件的节点</h4>
<ul>
<!--注: <template> 标签可以用来包装多个元素或者多行代码, 不会在页面中渲染 -->
<template v-for="(value, key, index) in data.user">
<li v-if="index == 1">
{{ index }} : {{ key }} : {{ value }}
</li>
</template>
</ul>
</div>
<script type="module">
import { createApp, reactive } from './vue.esm-browser.js'
createApp({
setup() {
const data = reactive({
//数组
number: ["十", "十一", "十二"],
//对象
user: { name: "李雷", gender: "女" }
});
return {
data
}
}
}).mount("#app")
</script>
</body>
</html>
运行结果:
五、Vue3的v- bind
v- bind:主要用于将一个或多个属性绑定到元素上,动态地设置 HTML 元素的属性值,可以响应式地更新 DOM。简单来说,它能够让我们把 JS中的数据关联到 HTML 元素的属性上,使得属性值能根据数据的变化而自动变化
以下为示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>节点的动态属性(单向绑定)</title>
<style>
.textColor{
color: red;
}
</style>
</head>
<body>
<div id="app">
<h3> iuput标签动态属性绑定 v-bind:value </h3>
<input type="text" v-bind:value="web.str">
<h3> iuput标签动态属性绑定(简写形式) :str </h3>
<input type="text" :value="web.str">
<h3> img标签动态属性绑定(简写形式) :src </h3>
<img :src="web.img">
<h3> b标签动态属性绑定(简写形式) :class</h3>
<h4> 注:通过布尔值控制某个类名是否存在,进而控制对应的CSS样式是否被选中生效</h4>
<b :class="{textColor:web.fontStatus}">永夜星河</b>
<br>
<button @click="change">修改</button>
</div>
<script type="module">
import { createApp, reactive } from './vue.esm-browser.js'
createApp({
setup() {
const web = reactive({
str: "w",
img: "./img_src/logo0.png",
fontStatus: false
})
const change = () => {
web.str += "w";
web.img=`./img_src/logo1.png`;
web.fontStatus = !web.fontStatus;
}
return {
web,
change
}
}
}).mount("#app")
</script>
</body>
</html>
运行结果:
(注:文本框是可以输入内容的)
(注:若有疑问,可发评论,作者看到会回复)