以上视频的学习笔记,方便查阅和复习。
目录
学习完本章后,需要记住的易混点:
- 不能在标签属性中使用 { { }} 插值 ,插值表达式只能在标签中间使用
- 在{ {}}插值表达式中使用data配置项中的属性时,直接写属性名即可
- 在vue的指令中,访问data配置项中的属性也,直接填写属性名即可
- 在methods配置项中的函数内访问data中的属性时,需要在属性名前 加上 this.(或vue实例名.)
一、为什么要学习Vue
1.前端必备技能
2.岗位多,绝大互联网公司都在使用Vue
3.提高开发效率
4.高薪必备技能(Vue2+Vue3)
二、什么是Vue
概念:Vue (读音 /vjuː/,类似于 view) 是一套 构建用户界面 的 渐进式 框架
Vue2官网:Vue.js
1.什么是构建用户界面
基于数据 渲染出用户看到的界面

2.什么是渐进式
渐进式就是循序渐进,不一定非得把Vue中的所有API都学完才能开发Vue,可以学一点开发一点
Vue的两种开发方式:
-
Vue核心包开发
场景:局部模块改造
-
Vue核心包&Vue插件&工程化
场景:整站开发
3.什么是框架
所谓框架:就是一套完整的解决方案
举个栗子
如果把一个完整的项目比喻为一个装修好的房子,那么框架就是一个毛坯房。
我们只需要在“毛坯房”的基础上,增加功能代码即可。
提到框架,不得不提一下库。
-
库,类似工具箱,是一堆方法的集合,比如 axios、lodash、echarts等
-
框架,是一套完整的解决方案,实现了大部分功能,我们只需要按照一定的规则去编码即可。
下图是 库 和 框架的对比。

框架的特点:有一套必须让开发者遵守的规则或者约束
咱们学框架就是学习的这些规则 官网
总结:什么是Vue?
Vue是什么:
什么是构建用户界面:
什么是渐进式:
什么是框架:
三、创建Vue实例
我们已经知道了Vue框架可以 基于数据渲染出用户界面,那应该怎么做呢?

比如就上面这个数据,基于提供好的msg 怎么渲染后右侧可展示的数据呢?
核心步骤(4步):
-
准备用于渲染的容器
-
引入vue核心包(官网) — 分为 开发版本/生产版本
-
创建Vue实例 new Vue()
-
在Vue实例中添加配置项,渲染数据
-
el:指定挂载点,配置选择器,指定要渲染的容器
-
data:通过data给当前的组件(vue文件)提供数据
-
methods:通过这个配置项定义函数
-
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 1. 准备用于渲染的容器 -->
<div id="app">
<!-- 将来编写一些用于渲染的代码逻辑 -->
{
{msg}}
<a href="#">{
{count}}</a>
</div>
<!-- 2. 引入开发版本的核心包 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<!-- 引入了VueJS核心包,在全局环境中,就有Vue构造函数了 -->
<script>
<!-- 3. 创建Vue实例 new Vue() -->
<!-- 4. 在Vue实例中添加配置项,渲染数据 -->
const app = new Vue({
//通过el 来配置选择器,指定Vue管理的是哪个盒子
el:'#app',
//通过data 提供要渲染的数据
data:{
msg:'Hello',
count:666
}
})
</script>
</body>
</html>
效果:

总结:创建Vue实例需要执行哪4步
四、插值表达式 { {}}
插值表达式是一种Vue的模板语法

1.作用:通过 表达式 进行插值,渲染数据到页面中
表达式:是可以被求值的代码,JS引擎会将其计算出一个结果,只要是表达式就可以往{ {}}里面放
以下的情况都是表达式:
money + 100
money - 100
money * 10
money / 10
price >= 100 ? '真贵':'还行'
obj.name
arr[0]
fn()
obj.fn()
2.语法
插值表达式语法:{ { 表达式 }}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--
插值表达式:Vue的一种模板语法
作用:利用 表达式 进行插值渲染
语法:{
{ 表达式 }}
注意点:
1. 使用的数据要存在
2. 支持的是表达式,不是语句 if for
3. 不能在标签属性中使用 {
{ }}
-->
<div id="app">
<p>{
{ nickname }}</p>
<p>{
{ nickname.toUpperCase() }}</p>
<p>{
{ nickname + '你好' }}</p>
<p>{
{ age >= 18 ? '成年' : '未成年' }}</p>
<p>{
{ friend.name }}</p>
<p>{
{ friend.desc }}</p>
<!-- ---------以下这些用法是错误的!-------------- -->
<!-- <p>{
{ hobby }}</p> -->
<!-- <p>{
{ if }}</p> -->
<!-- <p title="{
{ nickname }}">我是p标签</p> -->
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
nickname: 'tony',
age: 18,
friend: {
name: 'jepson',
desc: '热爱学习 Vue'
}
}
})
</script>
</body>
</html>
效果:

3.注意!!!
1.在插值表达式中使用的数据 必须在data中进行了提供!!!!!!!!
<p>{
{hobby}}</p> //如果在data中不存在 则会报错
2.支持的是表达式,而非语句,比如:if for ...
<p>{
{if}}</p>
3.不能在标签属性中使用 {
{ }} 插值 ,插值表达式只能在标签中间使用!!!!!!!!!!!!!!!!!!!!!!!
<p title="{
{username}}">我是P标签</p>
五、数据的响应式处理特性
1.什么是响应式?
数据变化后,视图(页面)也会自动更新。
2.如何访问 和 修改 data中的数据(响应式演示)
data中的数据, 最终会被添加到vue的实例上,所以可以访问数据or修改数据:
- data配置项中的数据已经是响应式数据了。
① 访问数据: "实例.属性名"
② 修改数据: "实例.属性名"= "值"

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
{
{ msg }}
{
{ count }}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
// 响应式数据 → 数据变化了,视图自动更新
msg: '你好,黑马',
count: 100
}
})
// data中的数据,是会被添加到实例上
// 1. 访问数据 实例.属性名
// 2. 修改数据 实例.属性名 = 新值
</script>
</body>
</html>
效果:可通过控制台修改数据也可通过vue开发者工具修改数据,页面都会变化


3.总结
-
什么是响应式
-
如何访问和修改data中的数据呢
六、Vue开发者工具安装
-
通过谷歌应用商店安装(国外网站)
-
极简插件下载(推荐) 极简插件官网_Chrome插件下载_Chrome浏览器应用商店
安装步骤:


安装之后可以F12后看到多一个Vue的调试面板:

七、Vue中的常用指令
Vue会根据不同的指令,针对标签实现不同的功能。
Vue指令: 带有v- 前缀的 标签属性。
下面是v-html的例子,v-html的作用是:动态设置元素的innerHTML,可以解析字符串标签。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div v-html="msg"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
msg: `
<h3>学前端~来黑马!</h3>
`
}
})
</script>
</body>
</html>
效果:

为啥要学:提高程序员操作 DOM 的效率。
vue 中的指令按照不同的用途可以分为如下 6 大类:
-
内容渲染指令(v-html、v-text)
-
条件渲染指令(v-show、v-if、v-else、v-else-if)
-
事件绑定指令(v-on)
-
属性绑定指令 (v-bind)
-
双向绑定指令(v-model)
-
列表渲染指令(v-for)
指令是 vue 开发中最基础、最常用、最简单的知识点。
八、内容渲染指令
内容渲染指令用来辅助开发者渲染 DOM 元素的文本内容。常用的内容渲染指令有如下2 个:
-
v-text(类似innerText)
-
-
使用语法:
<p v-text="uname">hello</p>,意思是将 uame 值渲染到 p 标签中 -
类似 innerText,使用该语法,会覆盖 p 标签原有内容
-
-
v-html(类似 innerHTML)
-
作用:动态设置元素的innerHTML
-
-
-
使用语法:
<p v-html="intro">hello</p>,意思是将 intro 值渲染到 p 标签中 -
类似 innerHTML,使用该语法,会覆盖 p 标签原有内容
-
类似 innerHTML,使用该语法,能够将HTML标签的样式呈现出来。
-
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div v-html="msg"></div>
</div>
<script src="./vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
msg: `
<a href="http://www.itcast.cn">学it, 来黑马</a>
`
}
})
</script>
</body>
</html>
效果:

九、条件渲染指令 v-show/if
条件判断指令,按需控制 DOM元素 的显示和隐藏。条件渲染指令有如下两个,分别是
1. v-show
-
作用: 控制元素的显示和隐藏
-
语法: v-show = "表达式" 表达式值为 true时 显示, 为false时 隐藏
-
原理: 切换css的 display:none 来控制元素的显示和隐藏
-
场景:频繁切换显示隐藏的场景

2. v-if
-
作用: 控制元素的显示和隐藏(条件渲染)
-
语法: v-if= "表达式" 表达式值为 true时 显示, 为false时 隐藏
-
原理: 根据条件判断,是否创建 或 移除元素节点
-
场景: 要么显示,要么隐藏,不频繁切换的场景

示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 200px;
height: 100px;
line-height: 100px;
margin: 10px;
border: 3px solid #000;
text-align: center;
border-radius: 5px;
box-shadow: 2px 2px 2px #ccc;
}
</style>
</head>
<body>
<!--
v-show底层原理:切换 css 的 display: none 来控制显示隐藏
v-if 底层原理:根据 判断条件 控制元素的 创建 和 移除(条件渲染)
-->
<div id="app">
<div v-show="flag" class="box">我是v-show控制的盒子</div>
<div v-if="flag" class="box">我是v-if控制的盒子</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
flag: true
}
})
</script>
</body>
</html>

3. v-else 和 v-else-if
-
作用:辅助v-if进行判断渲染,需要紧接着v-if使用
-
语法:v-else v-else-if="表达式"
示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<p v-if="gender === 1">性别:♂ 男</p>
<p v-else>性别:♀ 女</p>
<hr>
<p v-if="score >= 90">成绩评定A:奖励电脑一台</p>
<p v-else-if="score >= 70">成绩评定B:奖励周末郊游</p>
<p v-else-if="score >= 60">成绩评定C:奖励零食礼包</p>
<p v-else>成绩评定D:惩罚一周不能玩手机</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
gender: 2,
score: 95
}
})
</script>
</body>
</html>
效果:

十、事件绑定指令
v-on:事件名 可以简写为-> @事件名
作用:给DOM元素注册事件,在元素上触发注册的事件后就执行指定的js代码。
语法如下:
-
<button v-on:事件名="内联语句">按钮</button>
-
<button v-on:事件名="methods中的函数名">按钮</button>
-
<button v-on:事件名="methods中的函数名(实参1,实参2...)">按钮</button>
-
如果不传递任何参数给方法,则方法无需加小括号
-
1. 内联语句
-
内联语句是一段可执行的js代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<button @click="count--">-</button>
<span>{
{ count }}</span>
<button v-on:click="count++">+</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
count: 100
}
})
</script>
</body>
</html>
2. 事件处理函数:methods配置项中定义的函数
-
事件处理函数写到一个跟data同级的配置项methods中
-
在methods中,函数内部的this其实是了指向Vue实例,所以在函数内部可以用 this.data中的属性名 访问data配置项中的数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<button @click="fn">切换显示隐藏</button>
<h1 v-show="isShow">黑马程序员</h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app4 = new Vue({
el: '#app',
data: {
isShow: true
},
methods: {
fn () {
// 让提供的所有methods中的函数,this都指向当前实例
// console.log('执行了fn', app.isShow)
// console.log(app3 === this)
this.isShow = !this.isShow
}
}
})
</script>
</body>
</html>
3. 给事件处理函数传参
-
methods方法中可以直接使用 e 当做事件对象
-
如果传递了参数,则实参
$event表示事件对象,固定用法。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
border: 3px solid #000000;
border-radius: 10px;
padding: 20px;
margin: 20px;
width: 200px;
}
h3 {
margin: 10px 0 20px 0;
}
p {
margin: 20px;
}
</style>
</head>
<body>
<div id="app">
<div class="box">
<h3>小黑自动售货机</h3>
<button @click="buy(5)">可乐5元</button>
<button @click="buy(10)">咖啡10元</button>
<button @click="buy(8)">牛奶8元</button>
</div>
<p>银行卡余额:{
{ money }}元</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
money: 100
},
methods: {
buy (price) {
this.money -= price
}
}
})
</script>
</body>
</html>
效果:
点一下三个按钮中的其中一个,银行卡余额就会减去响应的数值

十一、属性绑定指令
-
作用:动态设置 标签中某个标签属性的值,比如设置标签属性:src、url、title
-
语法:v-bind:标签属性名=“表达式”
-
v-bind:标签属性名=“表达式” 可以简写成=> :标签属性名=“表达式”
场景:动态设置img标签的标签属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<!-- v-bind:src => :src -->
<img v-bind:src="imgUrl" v-bind:title="msg" alt="">
<img :src="imgUrl" :title="msg" alt="">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
imgUrl: './imgs/10-02.png',
msg: 'hello 波仔'
}
})
</script>
</body>
</html>
效果:

十二、小案例-波仔的学习之旅
需求:默认展示数组中的第一张图片,点击上一页下一页来回切换数组中的图片
实现思路:
1.用数组存储图片路径 ['url1','url2','url3',...]
2.可以准备个下标index 去数组中取图片地址。
3.通过v-bind给src绑定当前的图片地址
4.点击上一页下一页只需要修改下标的值即可
5.当展示第一张的时候,上一页按钮应该隐藏。展示最后一张的时候,下一页按钮应该隐藏
<!DOCTYPE html> <!-- 定义文档类型为HTML5 -->
<html lang="en"> <!-- 设置页面语言为英文 -->
<head>
<meta charset="UTF-8"> <!-- 设置页面字符集为UTF-8 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- 告诉IE使用最新的引擎渲染页面 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 设置视口宽度为设备宽度,初始缩放比例为1.0 -->
<title>Document</title> <!-- 设置页面标题 -->
</head>
<body>
<div id="app"> <!-- Vue实例挂载点 -->
<button v-show="index > 0" @click="index--">上一页</button> <!-- 当index大于0时显示按钮,点击时index减1 -->
<div>
<img :src="list[index]" alt=""> <!-- 显示list数组中当前index对应的图片 -->
</div>
<button v-show="index < list.length - 1" @click="index++">下一页</button> <!-- 当index小于list长度减1时显示按钮,点击时index加1 -->
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <!-- 引入Vue.js库 -->
<script>
const app = new Vue({ // 创建Vue实例
el: '#app', // 指定Vue实例挂载的元素
data: { // 定义Vue实例的数据
index: 0, // 当前图片索引
list: [ // 图片列表
'./imgs/11-00.gif',
'./imgs/11-01.gif',
'./imgs/11-02.gif',
'./imgs/11-03.gif',
'./imgs/11-04.png',
'./imgs/11-05.png',
]
}
})
</script>
</body>
</html>
十三、v-for指令
作用:基于数据 循环渲染 带有v-for指令的 整个元素,可以遍历数组、对象、数字
v-for 指令需要使用 (item, index) in arr 形式的语法,其中:
-
item 表示数组中的每一项
-
index 是每一项的索引,不需要可以省略
-
索引从0开始
-
-
arr 要遍历的数组
以下是遍历数组的例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- Vue实例的挂载点 -->
<div id="app">
<!-- 页面标题 -->
<h3>小黑水果店</h3>
<!-- 无序列表,用于显示带有索引的水果列表 -->
<ul>
<!-- 列表项,使用v-for指令遍历list数组,同时获取元素和索引 -->
<li v-for="(item, index) in list">
<!-- 显示水果名称和索引 -->
{
{ item }} - {
{ index }}
</li>
</ul>
<!-- 另一个无序列表,用于显示水果列表 -->
<ul>
<!-- 列表项,使用v-for指令遍历list数组,获取元素 -->
<li v-for="item in list">
<!-- 显示水果名称 -->
{
{ item }}
</li>
</ul>
</div>
<!-- 引入Vue.js库 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!-- Vue实例的JavaScript代码 -->
<script>
// 创建Vue实例
const app = new Vue({
// 指定Vue实例挂载的元素
el: '#app',
// 定义Vue实例的数据
data: {
// 定义一个包含水果名称的数组
list: ['西瓜', '苹果', '鸭梨', '榴莲']
}
})
</script>
</body>
</html>
效果:

此语法也可以遍历对象和数字
//遍历对象
<div v-for="(value, key, index) in object">{
{value}}</div>
value:对象中的值
key:对象中的键
index:遍历索引从0开始
//遍历数字
<p v-for="item in 10">{
{item}}</p>
item从1 开始
十四、小案例-小黑的书架
需求:
1.根据左侧数据渲染出右侧列表(v-for)
2.点击删除按钮时,应该把当前行从列表中删除(获取当前行的id,利用filter进行过滤)

实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- Vue实例的挂载点 -->
<div id="app">
<!-- 书架标题 -->
<h3>小黑的书架</h3>
<!-- 无序列表,用于显示书籍列表 -->
<ul>
<!-- 列表项,使用v-for指令遍历booksList数组,同时使用:key绑定唯一标识 -->
<li v-for="(item,index) in booksList" :key="item.id">
<!-- 显示书籍名称 -->
<span>{
{item.name}}</span>
<!-- 显示书籍作者 -->
<span>{
{item.author}}</span>
<!-- 删除按钮,注册点击事件 -->
<button @click="del(item.id)">删除</button>
<!-- 点击事件处理函数,用于删除数组中对应的项 -->
</li>
</ul>
</div>
<!-- 引入本地Vue.js库 -->
<script src="./vue.js"></script>
<!-- Vue实例的JavaScript代码 -->
<script>
// 创建Vue实例
const app = new Vue({
// 指定Vue实例挂载的元素
el: '#app',
// 定义Vue实例的数据
data: {
// 定义一个包含书籍信息的数组
booksList: [
{ id: 1, name: '《红楼梦》', author: '曹雪芹' },
{ id: 2, name: '《西游记》', author: '吴承恩' },
{ id: 3, name: '《水浒传》', author: '施耐庵' },
{ id: 4, name: '《三国演义》', author: '罗贯中' }
]
},
// 定义Vue实例的方法
methods:{
// 删除方法,根据id删除数组中的对应项
del(id){
console.log('删除',id)
// 使用filter方法过滤掉id匹配的项,更新booksList数组
this.booksList = this.booksList.filter(item => item.id !== id)
}
}
})
</script>
</body>
</html>
十五、v-for中的key
继续使用第十四节的案例代码。
语法: key="唯一值"
作用:给列表项设置的唯一标识。便于Vue进行列表项的正确排序复用。
为什么加key:Vue 的默认行为会尝试原地修改元素,也就是删除最后一个li标签,然后将内容上移
注意:
-
key 的值只能是字符串 或 数字类型
-
key 的值必须具有唯一性
-
推荐使用 id 作为 key(唯一),不推荐使用 index 作为 key(会变化,不对应)
十六、双向绑定指令 v-model
双向绑定就是:
-
数据改变后,呈现的页面会更新
-
页面更新后,数据也会随之变化
作用: 在表单元素(input、radio、select)上使用,实现数据和视图(表单)的双向数据绑定,快速 获取 或 设置 表单元素的内容
语法:v-model="data中的变量名"
需求:使用双向绑定实现以下需求
-
点击登录按钮获取表单中的内容
-
点击重置按钮清空表单中的内容

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- 告诉IE使用最新的引擎渲染页面 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- 设置页面视口,适配移动设备 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 页面标题 -->
<title>Document</title>
</head>
<body>
<!-- Vue实例的挂载点 -->
<div id="app">
<!-- 输入框,使用v-model实现双向数据绑定,用于获取账户名 -->
账户:<input type="text" v-model="username"> <br><br>
<!-- 输入框,使用v-model实现双向数据绑定,用于获取密码 -->
密码:<input type="password" v-model="password"> <br><br>
<!-- 登录按钮,绑定点击事件 -->
<button @click="login">登录</button>
<!-- 重置按钮,绑定点击事件 -->
<button @click="reset">重置</button>
</div>
<!-- 引入Vue.js库 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!-- Vue实例的JavaScript代码 -->
<script>
// 创建Vue实例
const app = new Vue({
// 指定Vue实例挂载的元素
el: '#app',
// 定义Vue实例的数据
data: {
// 账户名数据
username: '',
// 密码数据
password: ''
},
// 定义Vue实例的方法
methods: {
// 登录方法,打印账户名和密码
login () {
console.log(this.username, this.password)
},
// 重置方法,清空账户名和密码
reset () {
this.username = ''
this.password = ''
}
}
})
</script>
</body>
</html>
十七、综合案例-小黑记事本

功能需求:
-
列表渲染
-
删除功能
-
添加功能
-
底部统计 和 清空
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./css/index.css" />
<title>记事本</title>
</head>
<body>
<!-- 主体区域 -->
<section id="app">
<!-- 输入框区域 -->
<header class="header">
<!-- 标题 -->
<h1>小黑记事本</h1>
<!-- 输入框,使用v-model双向绑定todoName -->
<input v-model="todoName" placeholder="请输入任务" class="new-todo" />
<!-- 添加任务按钮,点击触发add方法 -->
<button @click="add" class="add">添加任务</button>
</header>
<!-- 列表区域 -->
<section class="main">
<!-- 任务列表 -->
<ul class="todo-list">
<!-- 循环渲染每个任务项 -->
<li class="todo" v-for="(item,index) in list" :key="item.id">
<!-- 任务视图 -->
<div class="view">
<!-- 任务编号 -->
<span class="index">{
{index + 1}}.</span>
<!-- 任务名称 -->
<label>{
{item.name}}</label>
<!-- 删除任务的按钮,点击触发del方法 -->
<button @click="del(item.id)" class="destroy"></button>
</div>
</li>
</ul>
</section>
<!-- 统计和清空区域,使用v-show根据任务列表长度决定是否显示 -->
<footer v-show="list.length > 0" class="footer">
<!-- 任务统计 -->
<span class="todo-count">合 计:<strong> {
{list.length}} </strong></span>
<!-- 清空所有任务的按钮,点击触发clear方法 -->
<button @click="clear" class="clear-completed">
清空任务
</button>
</footer>
</section>
<!-- 底部脚本区域 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<script>
// 创建Vue实例
const app = new Vue({
// 指定Vue实例挂载的元素
el: '#app',
// 定义Vue实例的数据
data: {
// 绑定输入框的值
todoName:"",
// 任务列表
list:[
{id:1,name:"跑步一公里"},
{id:2,name:"跳绳一公里"},
{id:3,name:"游泳一公里"},
]
},
// 定义Vue实例的方法
methods:{
// 删除任务的方法
del(id){
// 使用filter方法删除指定id的任务项
console.log(id)
this.list = this.list.filter(item => item.id !== id)
},
// 添加任务的方法
add(){
// 检查输入是否为空,若为空则弹出提示
if(this.todoName.trim()===''){
alert('请输入任务名称')
return
}
// 向任务列表前添加新任务,并清空输入框
this.list.unshift({
id: +new Date(),
name: this.todoName
})
this.todoName = ''
},
// 清空任务列表的方法
clear(){
// 将任务列表设置为空数组
this.list = []
}
}
})
</script>
</body>
</html>
589

被折叠的 条评论
为什么被折叠?



