Vue的定义为渐进式的JavaScript框架。所谓渐进式,是指其被设计 为可以自底向上逐层应用。我们可以只使用Vue框架中提供的某层的功 能,也可以与其他第三方库整合使用。当然,Vue本身也提供了完整的 工具链,使用其全套功能进行项目的构建也非常简单。Vue的渐进式性质使其使用方式变得非常灵活,在使用时,我们可以使用其完整的框架,也可以只使用部分功能。
一、响应式数据
1.ref方法
ref
是Vue3中用于创建响应式数据的方法之一。它主要用于创建基本数据类型(如Number
、String
、Boolean
等)的响应式数据。ref
接受一个内部值作为参数,并返回一个带有.value
属性的响应式对象。
例如:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div id="app"><p>{{ msg }}</p></div><script type="module">import {createApp, ref} from "./vue.esm-browser.js" //模块化开发方式createApp({setup(){let msg = ref;// 返回一个对象类型的数据return { msg: "成功创建第一个Vue应用程序!" , }}}).mount("#app");</script>
</body>
</html>
效果如下(运行需安装live-server插件):
2.reactive方法
reactive
用于创建复杂的响应式数据对象,如对象或数组。它将一个普通的 JavaScript 对象转换为响应式对象。被reactive
包裹的对象,其所有的属性都将变成响应式的。
例如:
<!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>{{ web.url }}</p><button @click="change">点击我更换网址</button></div><script type="module">import {createApp, 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 { web,change}}}).mount("#app");</script></body>
</html>
效果如下(运行需安装live-server插件):
点击按钮前 点击按钮后
二、事件绑定指令v-on
v-on
是 Vue.js 中用于绑定事件的指令。它可以将 DOM 事件(如click
、keydown
、submit
等)绑定到组件实例的方法上。
enter space tab 按键修饰符
keyup是在用户松开按键时才触发
keydown是在用户按下按键时立即触发
这使得在用户与页面进行交互(如点击按钮、输入文字等)时,能够触发相应的 JavaScript 代码来处理业务逻辑。
<!-- v-on:click 表示在 button 元素上监听 click 事件 -->
<button v-on:click="edit">修改</button> <br><!-- @click 简写形式 -->
<button @click="add(20, 30)">加法</button> <br>
可以通过@keyup.+键盘内的某个键设置点击该按键或者组合键触发函数,代码如下:
回车 <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)">
效果如下:
未按键版 按键版
以下是一个v-on指令事件绑定的例子:
<!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></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>
效果如下:
未点击版 点击版
三、条件渲染指令v-show和v-if
v-show
是 Vue.js 中的一个指令,用于根据表达式的值来控制元素的显示和隐藏。当表达式的值为true
时,元素会显示;当表达式的值为false
时,元素会隐藏。它通过修改元素display
CSS 属性来实现显示和隐藏的效果。
例如:
<!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-show变化时,是用display:none实现隐藏的(可以通过F12检查源代码,当点击时,源码会加入display:none) --><p v-show="web.show">广东云浮中医药职业学院计算机学院v-show</p> </div><script type="module">import { createApp, reactive, ref } from './vue.esm-browser.js'createApp({setup() {const web = reactive({ // 响应式数据show: true,user: 500});return {web,}}}).mount("#app");</script></body>
</html>
效果如下:
①当表达式的值为true
时,元素正常显示:
②当表达式的值为false时,元素被隐藏:
v-if
也是用于条件渲染的指令。它根据表达式的值来决定是否渲染元素。如果表达式的值为true
,元素会被渲染到 DOM 中;如果表达式的值为false
,元素不会被渲染。
同样是上面的例子,以v-if来实现:
<!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></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捕获}return {web,toggle,}}}).mount("#app");</script></body>
</html>
效果如下:
四、遍历指令v-for
v-for
是 Vue.js 中用于遍历数组或对象并渲染列表的指令。它可以根据数据源(如数组、对象、数字范围等)的内容来动态地生成多个相同结构的 DOM 元素。
1.遍历一个对象的数值:
<!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></div><script type="module">import { createApp, reactive } from './vue.esm-browser.js'createApp({setup() {const data = reactive({ //对象user: { name: "李雷", gender: "女" }});return {data}}}).mount("#app")</script></body>
</html>
效果如下:
2.遍历对象的值和索引 (注意:写指令时,先值后索引):
<!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, index) in data.number">{{ index }} : {{ value }}</li></ul> </div><script type="module">import { createApp, reactive } from './vue.esm-browser.js'createApp({setup() {const data = reactive({//数组number: ["十", "十一", "十二"], });return {data}}}).mount("#app")</script></body>
</html>
效果如下:
3.遍历对象的值和键( 注意:写指令时,先值后键):
<!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, key) in data.user">{{ key }} : {{ value }}</li></ul> </div><script type="module">import { createApp, reactive } from './vue.esm-browser.js'createApp({setup() {const data = reactive({//对象user: { name: "李雷", gender: "女" } });return {data}}}).mount("#app")</script></body>
</html>
效果如下:
4.遍历对象的值,键和索引。 注意:写指令时,先值再键后索引:
<!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, key, index) in data.user">{{ index }} : {{ key }} : {{ value }}</li></ul> </div><script type="module">import { createApp, reactive } from './vue.esm-browser.js'createApp({setup() {const data = reactive({//对象user: { name: "李雷", gender: "女" } });return {data}}}).mount("#app")</script></body>
</html>
效果如下:
5.指令嵌套: 先用v-for指令遍历对象,然后展示符合v-if条件的节点:
<!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>指令嵌套: 先用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({//对象user: { name: "李雷", gender: "女" } });return {data}}}).mount("#app")</script></body>
</html>
效果如下:
五、属性动态化指令v-bind
v-bind
是 Vue.js 中的一个指令,用于动态地绑定一个或多个属性到元素上。它允许你根据组件的数据来改变元素的属性值,比如src
、href
、class
、style
等属性。通过v-bind
,可以实现数据驱动的属性变化,使得视图能够随着数据的改变而自动更新相关属性。
语法为v-bind:属性名="表达式"
,不过在实际开发中,更常用的是缩写形式:属性名="表达式"
。
1.iuput标签动态属性绑定
<!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"><br><button @click="change">修改</button></div><script type="module">import { createApp, reactive } from './vue.esm-browser.js'createApp({setup() {const web = reactive({str: "w",})const change = () => {web.str += "w";}return {web,change}}}).mount("#app")</script></body>
</html>
效果如下:
未点击修改键 点击修改键(根据点击次数叠加)
2.img标签动态属性绑定
<!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> img标签动态属性绑定(简写形式) :src </h3><img :src="web.img"><br><button @click="change">修改</button></div><script type="module">import { createApp, reactive } from './vue.esm-browser.js'createApp({setup() {const web = reactive({img: "./img_src/logo0.png",})const change = () => {web.img=`./img_src/logo1.png`;}return {web,change}}}).mount("#app")</script></body>
</html>
效果如下:
3.b标签动态属性绑定
<!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> 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({fontStatus: false})const change = () => {web.fontStatus = !web.fontStatus;}return {web,change}}}).mount("#app")</script></body>
</html>
效果如下: