1. 为什么要学习Vue
- 前端必备技能 :
Vue.js作为现代前端开发领域中的主流框架之一,已成为前端开发者必备的技术栈。随着前端技术的不断发展和企业需求的变化,掌握Vue.js能够确保开发者跟上行业发展步伐,适应各类Web项目的开发需求。 - 广泛应用与岗位需求 :
目前,在国内外绝大多数互联网公司,尤其是中大型企业和创业团队中,Vue.js因其易用性、灵活性和强大的生态系统而被广泛采用。这意味着市场对于熟练掌握Vue.js技术的前端工程师有着大量且持续增长的需求。 - 提高开发效率 :
Vue.js 提供了声明式的数据绑定、组件化开发模式、虚拟DOM以及丰富的生态支持如Vuex状态管理库和Vue Router路由库等,这些特性使得开发者可以更高效地构建用户界面和管理应用状态,从而大大提升了整体的开发效率和项目的可维护性。 - 职业发展与高薪竞争力 :
对于寻求职业发展的前端开发者来说,无论是精通Vue 2还是紧跟潮流学习Vue 3,都是提升个人技术水平、增强职场竞争力的关键因素。许多高级前端岗位在招聘时会明确要求或优先考虑具备Vue.js开发经验的候选人,因为这不仅意味着候选者能快速融入团队现有的技术栈,还能带来更高的生产力和更优的项目成果,从而往往与较高的薪资水平挂钩。
2. 什么是Vue
概念: Vue (读音 /vjuː/,类似于 view) 是一套 构建用户界面 的 渐进式框架
Vue2官网:Vue.js,现在Vue2已经停止更新
Vue3官网:Vue.js - 渐进式 JavaScript 框架 | Vue.js
2.1. 什么是构建用户界面
构建用户界面:基于数据 渲染出用户可以看到的界面
2.2. 什么是渐进式
所谓渐进式就是循序渐进,不一定非得把Vue中的所有API都学完才能开发Vue,可以学一点开发一点
Vue的两种开发方式
- Vue核心包开发场景:局部模块改造
- Vue核心包&Vue插件&工程化场景:整站开发
2.3. 什么是框架
所谓框架:就是一套完整的解决方案
举个栗子
如果把一个完整的项目比喻为一个装修好的房子,那么框架就是一个毛坯房。
我们只需要在"毛坯房"的基础上,增加功能代码即可。
提到框架,不得不提一下库。
- 库,类似工具箱,是一堆方法的集合,比如 axios、lodash、echarts等
- 框架,是一套完整的解决方案,实现了大部分功能,我们只需要按照一定的规则去编码即可。
下图是 库 和 框架的对比。
框架的特点: 有一套必须让开发者遵守的规则 或者约束
咱们学框架就是学习的这些规则,官网 --> Vue.js - 渐进式 JavaScript 框架 | Vue.js
总结
Vue是什么:
什么是构建用户界面:
什么是渐进式:
什么是框架:
3. Vue入门实例
上面这个数据,基于提供好的msg(msg="Hello 黑马")怎么渲染后右侧可展示的数据呢?
核心步骤(4步):
- 准备容器
- 引包(官网) --- 开发版本/生产版本
- 创建Vue实例 new Vue()
- 指定配置项,渲染数据
-
- el:指定挂载点
- data提供数据
总结:创建Vue实例需要执行哪4步?
4. 插值表达式{{ }}
插值表达式是一种Vue的模板语法
我们可以用插值表达式渲染出Vue提供的数据
作用: 利用表达式进行插值,渲染到页面中
表达式:是可以被求值的代码,JS引擎会讲其计算出一个结果
以下的情况都是表达式:
money + 100
money - 100
money * 10
money / 10
price >= 100 ? '真贵':'还行'
obj.name
arr[0]
fn()
obj.fn()
用法
<h3>{{title}}<h3>
<p>{{nickName.toUpperCase()}}</p>
<p>{{age >= 18 ? '成年':'未成年'}}</p>
<p>{{obj.name}}</p>
<p>{{fn()}}</p>
错误用法
1.在插值表达式中使用的数据 必须在data中进行了提供
<p>{{hobby}}</p> //如果在data中不存在 则会报错
2.支持的是表达式,而非语句,比如:if for ...
<p>{{if}}</p>
3.不能在标签属性中使用 {{ }} 插值 (插值表达式只能标签中间使用)
<p title="{{username}}">我是P标签</p>
代码案例
总结
1.插值表达式的作用是什么
2.语法是什么
3.插值表达式的注意事项
5. 响应式特性
- 简单理解就是数据变,视图对应变
简单来说就是这样:
想象你正在做一个填字游戏,当你填写一个格子(代表数据)时,整个游戏板(代表视图)会自动检查是否需要更新以反映新填写的内容。
具体到Vue.js中:
假设你有一个网页上的信息展示区域(视图)和一块存储数据的地方(数据模型)。
当你在数据模型里更改了一个值,比如把名字从"Alice"改成了"Bob",Vue就像个聪明的助手,它能立即知道这个变化,并且自动帮你把网页上显示名字的地方也改成"Bob",无需你亲自去修改网页的HTML代码。
换句话说,Vue通过特殊的方式监听你的数据变化,每当数据一变,它就负责把对应的网页部分也做出相应的更新,这就是所谓的"数据驱动视图"或"响应式特性"。这样你就不用每次数据变动都手动操作页面元素,大大简化了编程工作。
- 如何 访问 和 修改 data中的数据
data中的数据, 最终会被添加到实例上
① 访问数据: "实例.属性名"
② 修改数据: "实例.属性名"= "值"
在Vue中,对于实例化的Vue对象,其内部定义的data数据可以按照以下方式访问和修改:
假设我们有一个Vue实例:
var app = new Vue({
data: {
message: 'Hello, Vue!'
}
})
① 访问数据 :
要访问data中的message
属性,你可以直接通过实例的点(.)操作符来访问:
console.log(app.message); // 输出: Hello, Vue!
这意味着你现在获取到了data对象中message属性的值。
② 修改数据 :
同样地,要修改message
属性的值,你可以直接对实例的message属性赋新值:
app.message = 'Hello, World!';
现在,data对象中的message
属性值已经变成了'Hello, World!'。
Vue的响应式系统会监测到这个变化,并根据需要自动更新依赖于message
属性的所有视图部分。
需要注意的是,在Vue3的Composition API(如<script setup>语法)中,数据通常使用ref或reactive定义,此时访问和修改数据的方式略有不同,例如:
import { ref } from 'vue';
setup() {
const message = ref('Hello, Vue!');
console.log(message.value); // 访问数据
message.value = 'Hello, World!'; // 修改数据
}
总结
- 什么是响应式?
- 如何访问和修改data中的数据呢?
6. Vue开发者工具安装
极简插件下载(推荐) 极简插件官网_Chrome插件下载_Chrome浏览器应用商店
具体方法看视频教程------Vue开发者工具安装
7. Vue中的常见指令
Vue.js 中的指令是框架提供的一种特殊机制,它们是带有 v-
前缀的HTML属性,用来告知Vue在特定情况下如何操作DOM元素或影响其行为。学习和掌握Vue指令有助于提高前端开发人员操纵DOM元素和管理数据与视图交互的效率,避免手动操作DOM,降低代码复杂性,增强代码可读性和可维护性。
以下是Vue中常见的指令分类及其功能简介:
- 内容渲染指令
-
- v-html:用于将表达式的结果作为HTML内容插入到元素中,Vue会直接替换元素的innerHTML。
- v-text:将表达式的值转化为纯文本并插入到元素内,类似于innerText。
- 条件渲染指令
-
- v-if / v-else / v-else-if:根据表达式的真假决定是否渲染元素及内容,true时显示,false时不显示,并可能涉及DOM的添加或移除。
- v-show:类似v-if,但它并不移除DOM节点,而是通过CSS的display属性控制元素的显示/隐藏。
- 事件绑定指令
-
- v-on :用于绑定事件处理器到DOM元素上,缩写形式为
@
,如v-on:click="handleClick"
,简写为@click="handleClick"
。
- v-on :用于绑定事件处理器到DOM元素上,缩写形式为
- 属性绑定指令
-
- v-bind :用于动态绑定HTML元素的属性值,可以根据数据的变化更新属性,缩写形式为
:
,如v-bind:href="url"
,简写为:href="url"
。
- v-bind :用于动态绑定HTML元素的属性值,可以根据数据的变化更新属性,缩写形式为
- 双向绑定指令
-
- v-model:用于表单元素的双向数据绑定,它可以自动把表单控件的值与Vue实例的一个特定属性关联起来,无论何时一方改变,另一方也会随之更新。
- 列表渲染指令
-
- v-for :用于循环渲染列表数据,它可以遍历数组或对象,根据数据结构生成多个重复的DOM元素,同时还可以配合
key
属性优化列表渲染性能。
- v-for :用于循环渲染列表数据,它可以遍历数组或对象,根据数据结构生成多个重复的DOM元素,同时还可以配合
通过上述指令,Vue开发者可以在不直接操作DOM的情况下,以声明式的方式编写出更加简洁、易懂且响应式的代码。
7.1. 内容渲染指令
在Vue.js框架中,内容渲染指令是Vue提供的一种模板语法,用于动态更新DOM元素内的文本内容或HTML内容。
以下是关于Vue 3中的两种常用内容渲染指令的解释:
- v-text
-
v-text
指令用于将Vue实例的数据绑定到DOM元素的文本内容上。当你在元素上使用v-text
时,它会替换元素内部所有的内容,将其转换为指定变量的纯文本值。例如:
在这个例子中,uname
是Vue组件实例的一个属性或计算属性,当uname
的值发生变化时,Vue会自动更新<p>
元素的文本内容,其效果等同于JavaScript操作innerText
。
- v-html
-
v-html
指令则是用于将Vue实例的数据作为一个HTML字符串插入到DOM元素内。这允许你将包含HTML标签的内容渲染到元素中,而不是仅仅显示纯文本。然而,使用v-html
时需要注意安全风险,因为它会直接解析并执行其中的HTML代码,可能导致XSS攻击。它的使用语法如下:
当intro
的值改变时,Vue会替换<p>
元素的全部内容,并将其解释为HTML,就像直接设置innerHTML
一样。这意味着如果intro
变量的值是"<strong>Hello World!</strong>"
,那么最终渲染出来的结果将是带有加粗样式文本的Hello World!
。
总之,在Vue 3中,尽管这两种指令仍然可用,但在实践中更推荐使用模板插值(即{``{ }}
)来替代v-text
进行文本内容的渲染,因为模板插值更加简洁且具有相似的效果,不会覆盖元素内部其他内容。而v-html
则主要用于那些确实需要动态插入可信任HTML片段的场景,但务必确保输入内容的安全性。
代码示例:
<template>
<div id="app">
<!-- 使用 v-text 指令 -->
<p v-text="username"></p>
<!-- 使用 v-html 指令 -->
<div v-html="formattedIntro"></div>
<!-- 设置按钮用于更改数据 -->
<button @click="changeData">点我试试</button>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
// 创建响应式数据
const username = ref('雨空集');
let rawIntro = '这是一个简单的代码介绍';
const formattedIntro = ref(rawIntro);
// 更改数据的方法
function changeData() {
username.value = '喂';
formattedIntro.value = '你还真的点ta啊';
}
return {
username,
formattedIntro,
changeData
};
}
};
</script>
7.2. 条件渲染指令
Vue.js中的v-show
和v-if
都是用于条件渲染的指令,但它们的工作机制和适用场景有所不同:
- v-show
- 作用:同样用于控制元素的显示与隐藏。
- 原理 :不论初始条件如何,元素总是会被渲染到DOM中,只是通过修改元素的CSS样式(通常是
display: none/block
)来控制其是否可见。当v-show
表达式的值为true
时,元素会显示出来(CSS样式为display: block
),当表达式的值为false
时,元素会隐藏(CSS样式为display: none
)。 - 性能影响 :由于元素始终存在于DOM树中,所以在频繁切换条件下,
v-show
相比v-if
而言对DOM的操作较少,因为不需要每次切换都进行DOM节点的添加或移除,仅需改变样式即可,故在频繁切换显示隐藏状态的情况下,v-show
可能有更好的性能表现。
- v-if
- 作用:同样是条件渲染,但控制粒度更为精细。
- 原理 :
v-if
更具惰性,它会根据表达式的值决定是否真正创建或销毁相关的DOM元素。当v-if
的表达式值为true
时,元素会被渲染到DOM中;当表达式值变为false
时,元素及其包含的所有子节点将从DOM中移除。反之亦然。 - 性能影响 :由于涉及到DOM节点的创建和销毁,
v-if
在初次渲染和条件变化时会对DOM进行更多的操作。因此,在非频繁切换或希望减少不必要的DOM节点占用资源的情况下,v-if
可能是更好的选择。
总结起来,两者的主要区别在于:
- 持久性 :
v-show
的元素始终存在于DOM中;v-if
的元素会在条件不满足时从DOM中移除。 - 性能开销 :
v-show
适合频繁切换且无需关心DOM节点数量的情况;v-if
适用于不常变化或者在条件不满足时希望彻底移除节点以节省资源的情况。 - 样式控制 :
v-show
仅仅是通过CSS样式控制元素显示与否;v-if
则是根据条件决定整个元素的存在与否。
- v-else 和 v-else-if
v-else 和 v-else-if 是 Vue.js 中进一步细化条件渲染逻辑的辅助指令,它们都是配合 v-if
指令使用的:
v-else
- 作用 :
v-else
用于定义一个"默认"或"其他"条件块,当它紧跟在一个v-if
或v-else-if
后面时,若前面的条件表达式计算结果为false
,则v-else
包含的元素将会被渲染。 - 语法 :
<element v-else></element>
。注意,v-else
不需要表达式,它默认与最近的未关闭的v-if
或v-else-if
关联。
v-else-if
- 作用 :
v-else-if
提供了额外的条件判断,它类似于v-if
,但只能放在一个v-if
或另一个v-else-if
之后,用于在前面条件不满足时继续检查另一个条件。 - 语法 :
<element v-else-if="expression"></element>
。这里的expression
是一个 JavaScript 表达式,只有当与它关联的前一个v-if
或v-else-if
的表达式计算结果为false
时,才会去计算v-else-if
的表达式。
综合使用示例:
<div v-if="type === 'A'">
这是类型A的内容
</div>
<div v-else-if="type === 'B'">
这是类型B的内容
</div>
<div v-else>
这是除了类型A和B之外的其他内容
</div>
在这个例子中,Vue会按照顺序检查每个条件:
- 首先检查
type
是否等于'A'
,如果是,则渲染第一个div
; - 若
type
不等于'A'
,则检查是否等于'B'
,如果是,则渲染第二个div
; - 如果上述两个条件都不满足,那么渲染
v-else
后的div
。
7.3. 事件绑定指令
在Vue.js中,当我们想要让页面上的某个元素(如按钮、链接等)响应用户的操作(如点击、鼠标悬停等),就需要给这个元素绑定事件。
Vue提供了 v-on****指令(可以简写为 @****)来实现这一目的。
-
内联语句 :
你可以在v-on
或@
后面直接写JavaScript表达式。例如,当你点击一个按钮时,你想让计数器减一:<button @click="count--">-</button>
这意味着当你点击这个按钮时,Vue会执行count--
这个命令,即减少count
变量的值。
在Vue 3 Composition API中,你需要先声明这个变量并在setup函数中对其进行操作:
<script setup>
import { ref } from 'vue'
const count = ref(100)
function decreaseCount() {
count.value--;
}
</script>
<button @click="decreaseCount">-</button>
-
事件处理函数 :
有时候,你的逻辑可能比较复杂,不适合直接写在内联表达式中,这时可以将逻辑封装成一个单独的方法,并在事件绑定处调用这个方法:<button @click="toggleVisibility">切换显示隐藏</button>
然后在Vue组件的methods或Composition API的setup函数中定义toggleVisibility
这个方法,它会负责处理显示/隐藏的状态切换:
// Vue 2.x Options API
methods: {
toggleVisibility() {
this.isShow = !this.isShow;
}
}
// Vue 3 Composition API
<script setup>
import { ref } from 'vue'
const isShow = ref(true);
function toggleVisibility() {
isShow.value = !isShow.value;
}
</script>
-
给事件处理函数传参 :
如果你需要在触发事件时传递一些参数给处理函数,可以直接在绑定事件的括号里写入:<button @click="buyDrink(5)">购买5元商品</button>
在对应的事件处理函数buyDrink
中,你会接收到传递过来的参数(这里是商品的价格):
// Vue 2.x 或 Vue 3 Composition API
methods: {
buyDrink(price) {
// 在这里,price是从按钮点击事件中传来的参数
// 可能会执行扣款或其他涉及商品价格的逻辑
}
}
// 或者在Vue 3 Composition API的setup函数中
<script setup>
function buyDrink(price) {
// 在这里,price是从按钮点击事件中传来的参数
// 可能会执行扣款或其他涉及商品价格的逻辑
}
</script>
简而言之,在Vue中,通过v-on
或@
指令,你可以告诉Vue当特定事件发生时(如点击按钮)应该执行什么动作(如改变数据、调用方法)。同时,还可以向这些方法传递参数以便更好地处理各种情况。
7.4. 属性绑定指令
在网页编程中,HTML元素的属性(如图片的src、链接的href等)通常是静态的,一旦写好就不会变。但在Vue.js中,我们可以让这些属性变得动态,也就是它们的值可以根据Vue组件内部的数据变化而自动更新。
在Vue 3中,属性绑定(Attribute Binding)的原理和Vue 2基本一致,主要通过指令来动态地绑定HTML元素的属性值至Vue组件实例的数据属性。Vue 3引入了Composition API,但这不影响属性绑定的基本用法。
Vue 3属性绑定的语法依旧支持两种形式:
-
完整语法:
v-bind:属性名="表达式"
-
简写语法:
:属性名="表达式"
举例说明:
想象一下,你在做一个网页,里面有一张图片,你想让用户每次打开网页时看到不同的图片。在Vue中,你可以这么操作:
<!-- HTML部分 -->
<div id="app">
<img :src="imagePath" alt="动态图片">
</div>
// Vue 3.x 代码部分(使用Composition API)
import { ref, createApp } from 'vue';
const imagePath = ref('path/to/default-image.jpg'); // 初始化时的图片路径
const App = {
setup() {
// 这里你可以定义一个函数,用于更改图片路径
function changeImage(newPath) {
imagePath.value = newPath; // 更新图片路径
}
return {
imagePath, // 把图片路径暴露出去,让HTML部分可以使用
changeImage // 如果需要的话,也可以暴露出去,用于触发图片更换
};
}
};
createApp(App).mount('#app');
在上面的代码中,:src="imagePath"
是一种特殊的Vue语法,它表示图片的src
属性会随着imagePath
这个变量的变化而变化。也就是说,如果你在JavaScript部分改变了imagePath
的值,那么图片就会加载新的路径指向的图片。
这就是Vue中的属性绑定,它使得HTML元素的属性值不再是固定的,而是根据组件内部的数据动态变化。
7.5. 列表渲染指令
Vue 提供了 v-for 列表渲染指令,用来辅助开发者基于一个数组来循环渲染一个列表结构。
在Vue 3中,v-for的基本语法是:
<element v-for="(item, index) in array" :key="keyExpression">
<!-- 渲染内容,这里可以使用item和index -->
</element>
-
item:这是数组中的每一个元素,在每次循环迭代中,item变量将被赋值为数组中的下一个元素。
-
index(可选):这是当前迭代项在数组中的索引(位置)。如果你只需要遍历数组中的元素本身而不关心索引,可以省略index。
-
array:这是待遍历的数组。Vue将会遍历这个数组的每一项,并为每一项生成对应的DOM元素。
-
:key(重要):为了优化性能和避免不必要的DOM操作,Vue要求在使用v-for时提供一个唯一的键(key)。这个键用于标识每个列表项,通常可以从数组的元素中获取,例如:key="item.id"。
-
- 作用: 给列表项添加的唯一标识 。便于Vue进行列表项的正确排序复用。
- 为什么加key: Vue 的默认行为会尝试原地修改元素(就地复用)
在Vue 3中,我们通常会处理数据并在模板中展示它们。这里是一个更基础的例子,假设我们有一个数组,里面存储了一些简单的数字:
// 在你的Vue组件<script setup>或setup()函数中定义数据
import { ref } from 'vue';
const numbers = ref([1, 2, 3, 4, 5]);
接下来,在模板(HTML)中,我们可以使用Vue的v-for
指令来循环遍历并渲染这些数字:
<!-- Vue组件的模板部分 -->
<template>
<div>
<!-- 使用v-for循环遍历numbers数组 -->
<p v-for="number in numbers" :key="number">
这是数字 {{ number }}
</p>
</div>
</template>
在这个例子中,v-for="number in numbers"
告诉Vue要对numbers
数组中的每一个元素执行一次循环,并且在每次循环中,当前元素的值会被赋给名为number
的新变量。因此,Vue会在页面上创建多个<p>
标签,每个标签内显示数组中的一个数字。
:key
属性是Vue为了优化列表渲染而推荐使用的特殊属性,它用于给每个列表项一个唯一的标识,这里我们直接使用了数组中的数字作为键值。在实际应用中,特别是当数据项具有唯一标识符时,应该使用该标识符作为key
的值。
7.6. 双向绑定指令
在Vue 3中,当你想让你的网页上的表单元素(比如文本框input、单选框radio、下拉框select等)的值和Vue组件中的某个变量保持同步时,就可以使用v-model
指令。
举个例子,假设我们有一个文本框和一个Vue组件变量message
:
<input type="text" v-model="message" />
- 当用户在这个文本框中输入文字时,Vue会自动把用户输入的文字更新到
message
这个变量中; - 当你在JavaScript代码中修改
message
变量的值时,文本框中显示的文字也会立刻变成新值。
换句话说,v-model="message"
使得文本框的值和变量message
之间建立了"双向"的联系,无论哪一方发生变化,另一方都会立刻同步更新。
对于复选框、单选框、下拉框等其他表单元素,v-model
的用法也类似,它都能帮你轻松实现数据与界面的实时同步。
举个例子:
<template>
<div id="app">
<!-- 文本输入框与message数据双向绑定 -->
<input type="text" v-model="message" placeholder="请输入信息..." />
<!-- 显示message的当前值 -->
<p>{{ message }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
// 创建一个响应式变量message
const message = ref('');
// 当message变量的值变化时,文本框的值会随之更新
// 当文本框的值变化时,message变量的值也会随之更新
</script>
在上述代码中:
- 我们首先在
<script setup>
标签内使用Vue 3的ref
函数创建了一个响应式变量message
,初始值为空字符串。 - 在模板(HTML)部分,我们将文本输入框的
v-model
指令绑定到message
变量。 - 当用户在文本框中输入内容时,Vue会自动更新
message
的值;同时,当我们在JavaScript中直接修改message
的值时,文本框显示的内容也会相应地改变,这就是双向绑定的功能。 - 页面还展示了一个
<p>
标签,其内容是{``{ message }}
,这意味着每当message
变量的值发生变化时,<p>
标签里的内容也会实时更新,显示出message
当前的值。
8. 综合案例-小黑记事本
功能需求:
- 列表渲染
- 删除功能
- 添加功能
- 底部统计 和 清空
Vue代码示例:
<template>
<!-- 主体区域 -->
<section id="todoapp">
<!-- 输入框 -->
<header class="header">
<h1>小黑记事本</h1>
<!-- 当按下回车键时触发addItem方法 -->
<!-- 输入完成后,清空输入框 -->
<input
autofocus="autofocus" <!-- 自动获取焦点 -->
autocomplete="off" <!-- 关闭自动补全功能 -->
placeholder="请输入任务" <!-- 提示用户输入内容 -->
class="new-todo"
@keyup.enter="addItem" <!-- 按下回车键时调用addItem方法 -->
v-model="inputItem" <!-- 将输入框的值与inputItem双向绑定 -->
/>
</header>
<!-- 列表区域 -->
<section class="main">
<ul class="todo-list" v-for="(item, index) in arr" :key="index"> <!-- 遍历数组arr -->
<li class="todo">
<div class="view">
<span class="index">{{ index + 1 }}</span> <!-- 显示当前项的索引 -->
<label>{{ item }}</label> <!-- 显示当前项的任务内容 -->
<button class="destroy" @click="deleteItem(index)"> <!-- 删除按钮,点击时调用deleteItem方法 -->
</button>
</div>
</li>
</ul>
</section>
<!-- 统计和清空 -->
<footer class="footer">
<span class="todo-count"> <!-- 显示剩余任务数量 -->
<strong>{{ arr.length }}</strong> items left
</span>
<button class="clear-completed" @click="cleararr"> <!-- 清空所有任务按钮,点击时调用cleararr方法 -->
清空
</button>
</footer>
</section>
<!-- 底部信息区域 -->
<footer class="info">
<p>
<a href="http://www.itheima.com/"><!-- 链接到指定网址 -->
<img src="./assets/img/11-05.png" alt="" /><!-- 显示图片 -->
</a>
</p>
</footer>
</template>
<script setup>
import {ref} from 'vue' // 引入Vue的ref函数
// 创建一个响应式数据arr,存储待办事项列表
const arr = ref(['吃饭', '睡觉', '打豆豆'])
// 删除指定索引处的待办事项
function deleteItem(index) {
arr.value.splice(index, 1)
}
// 清空所有待办事项
function cleararr() {
arr.value = []
}
// 创建一个响应式数据inputItem,用于暂存待办事项输入框的内容
const inputItem = ref('')
// 添加新的待办事项到列表,并清空输入框
function addItem() {
arr.value.push(inputItem.value)
inputItem.value = '' // 清空输入框内容
}
</script>
<style lang="scss" scoped>
</style>