73. vue介绍_文本指令_条件渲染_事件指令_属性指令
1. vue介绍
vue是一个渐进式JavaScript框架
官网:https://cn.vuejs.org/
单文件组件:
一种类似 HTML 格式的文件来书写 Vue 组件,它被称为单文件组件 xx.vue
Single-File Components:SFC
Vue 的单文件组件会将一个组件的逻辑 (JavaScript),模板 (HTML) 和样式 (CSS) 封装在同一个文件里
MTV架构:django专用架构,模型-模板-视图 本质也是MVC
Model:数据层 和 MVC 的 Model 完全一样,ORM 映射数据库表,处理数据
T:template 对应 MVC 里的 View;就是 HTML 模板,负责页面展示,只做渲染,不写业务逻辑
V:视图层 django的V+路由=C
MVC架构:经典软件分层架构,模型-视图-控制器
Model:数据层,定义数据结构、操作数据库、封装数据业务规则;不关心页面和请求
View:视图层 模板 用户界面,负责渲染展示数据(HTML、页面 UI)
Controller:控制器 调度中心,接收用户请求,调用模型获取数据,选择视图返回页面
MVVM:vue的架构模式
Model:数据层 原始数据、业务数据,和 MVC/MTV 的 Model 一样 可以简单理解为js变量
View:视图层 页面 UI(HTML),只负责展示,不写业务逻辑 用户看到的页面
ViewModel:视图模型 核心桥梁,负责 View 和 Model 之间的双向数据绑定。
核心特点:双向数据绑定
Model的js数据变 → 自动更新 View 页面
View 页面输入修改 → 自动同步回 Model的js数据
不需要手动操作 DOM 去更新页面,这是和 MVC 最大区别。
在Vue中,响应式是指当数据发生变化时,相关的视图会自动进行更新的特性。
2. vue2和vue3使用
2.1 准备
新建vue项目

在空目录下新建vue2test.html与vue3test.html

vue2官网https://v2.cn.vuejs.org/
vue2源码
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
vue3源码
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
将vue2、vue3的源码放到本地

2.2 vue2声明式渲染
Vue.js采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统
vue2test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue/vue2.js"></script>
</head>
<body>
<div id="d1">
<p>名字是:{{name}}</p>
<p>学校是:{{school}}</p>
</div>
</body>
<script>
var a = new Vue({
el:'#d1',
data:{name:'avril', school:'mit'}
})
</script>
</html>
整体含义
创建一个 Vue2 实例,把页面上 id="d1"的 DOM 元素交给 Vue 管理,并且定义数据,让页面可以通过 {{ }}插值读取这些数据。
逐行讲解
1. var a = new Vue({ ... })
new Vue () 代表新建一个 Vue 实例。
var a 是把这个实例对象保存到变量 a,后续可以用 a 访问实例。
2. el:'#d1
el 全称 element,代表挂载点
#d1是 css 选择器,选中页面中 id 等于 d1 的 div
作用:Vue 接管这个 div 内部的模板,解析里面的 {{name}}、{{school}}
3. data:{name:'avril', school:'mit'}
data 是 Vue 的数据仓库,存放响应式数据。
name: 'avril' 定义变量 name,值为 avril,页面 `{{name}}` 就会渲染成 avril
school: 'mit' 定义变量 school,值为 mit,页面 `{{school}}` 就会渲染成 mit
运行效果

补充要点
1. data 里面的数据是响应式:修改 a.name="xxx",页面上的文字会自动更新,不需要手动操作 DOM。 示例:打开浏览器控制台输入 a.name="test",页面名字立刻变化。
2. 只有写在 data 内的属性,才能在模板 {{}} 中直接使用。
3. el 只能挂载到页面上已存在的 DOM 节点,不能挂载到 html/body 根标签。
4. el和data是传给 Vue 构造函数的配置项 key,是 Vue2 规定好的关键字,不能更改。
2.3 vue3使用全局构建版本
[1] 组合式API(建议)
vue3test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue/vue3.js"></script>
</head>
<body>
<div id="d1">
<p>名字是:{{name}}</p>
<p>学校是:{{school}}</p>
</div>
</body>
<script>
const { createApp, ref } = Vue
createApp({
setup() {
const name = ref('kylian')
const school = ref('harvard')
return {
name, school
}
}
}).mount('#d1')
</script>
</html>
整体含义
创建一个 Vue3 应用,把页面上 id="d1" 的 DOM 元素交给 Vue 管理,并且定义响应式数据,让页面可以通过 {{}} 插值读取这些数据。
逐行讲解
1. const {createApp, ref} = Vue
从 Vue 全局对象解构取出两个函数。createApp 用来创建 Vue 应用,ref 用来创建基础类型的响应式数据。
2. createApp ({...})
createApp () 代表新建一个 Vue 应用,大括号内是应用的配置。
3. setup () { ...}
setup 是组合式 API 的入口函数,组件创建时执行,用来定义数据。
const name = ref ('kylian')
ref 创建响应式变量 name,初始值 kylian。ref 包装普通值,让数据拥有响应式,修改数据页面自动更新。
const school = ref ('harvard')
ref 创建响应式变量 school,初始值 harvard。
return { name, school }
把定义好的数据返回,暴露给模板,模板内就可以使用 {{name}}、{{school}}
4. .mount ('#d1')
mount 代表挂载点
运行效果

补充要点
1. ref里面面的数据,在 js 代码内部读写必须加 .value,例如 name.value="test",模板中使用不需要写 .value。修改后页面文字会自动更新,不需要手动操作 DOM。
2.createApp、ref、setup、mount 是 Vue3 固定 API 名称,不能修改。name、school 属于自定义变量名,可以随意起名。
3.Vue3 不再使用 new Vue () 创建实例,改用 createApp。
4.只有 return 出去的变量,模板才可以访问,不 return 的变量模板无法使用。
[2] 选项式API
vue3test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue/vue3.js"></script>
</head>
<body>
<div id="d1">
<p>名字是:{{name}}</p>
<p>学校是:{{school}}</p>
</div>
</body>
<script>
const {createApp} = Vue
createApp({
data() {
return {
name: 'haaland',
school: 'mit'
}
}
}).mount('#d1')
</script>
</html>
整体含义
创建一个 Vue3 应用,把页面上 id="d1" 的 DOM 元素交给 Vue 管理,并且定义响应式数据,让页面可以通过 {{}} 插值读取这些数据。
逐行讲解
1. const {createApp} = Vue
从 Vue 全局对象解构取出 createApp 函数,createApp 用来创建 Vue 应用。
2. createApp ({...})
createApp () 代表新建一个 Vue 应用,大括号内是应用的配置。
3. data () { ...}
data 是配置项,必须写成函数形式,函数返回一个对象,对象内存放响应式数据。
return { name: 'haaland', school: 'mit' }
返回的对象中定义数据 name 和 school,初始值分别为 haaland、mit,模板可以直接读取。
4. .mount ('#d1')
mount 代表挂载点
运行效果

补充要点
1. Vue3 选项式 API 中,data 必须是一个函数,返回数据对象,不能直接写对象字面量,防止多个组件实例之间数据互相污染。修改 data 内的数据,页面文字会自动更新,不需要手动操作 DOM。
2. createApp、data、mount 是 Vue3 固定 API 名称,不能修改。
3. 插值语法
插值语法核心:双大括号 {{ }},Vue2、Vue3 插值基础写法完全一致。
插值语法可以渲染变量、简单运算、三目运算符、函数,无法渲染标签。
以vue2的插值语法为例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue/vue2.js"></script>
</head>
<body>
<div id="d1">
<p>渲染字符串:{{name}}</p>
<p>渲染数字:{{age}}</p>
<p>渲染数组:{{list1}}---》{{list1[1]}}</p>
<p>渲染对象:{{obj1}}---》{{obj1.name}}--->{{obj1['age']}}</p>
<p>渲染标签字符串:{{link1}}</p>
<p>简单js语法:{{9 + 9}}</p>
<p>简单js语法:{{age + 9}}</p>
<p>简单js语法:{{name + '_NB'}}</p>
<p>三目运算符:{{age >= 18 ? "成年" : "未成年"}}</p>
</div>
</body>
<script>
// 插值语法,可以渲染字符串,列表,对象,简单js语法和三目运算符 无法渲染标签
var a = new Vue({
el: '#d1',
data: { // 一定要定义在data的内部--》所有变量,都可以使用插值语法 {{}}
name: 'avril',
age: 19,
list1: ['张三', '李四', '王五'], // js叫数组,不叫列表
obj1: {name: 'kylian', age: 19}, //不叫字典,js叫对象
link1: '<a href="http://www.baidu.com">点我有好看的</a>'
}
}
)
</script>
</html>

4. 指令系统
4.1 前提:安装vue插件
pycharm-文件-设置-插件
在Marketplace安装vue,有的pycharm可能自动安装无需主动安装

当安装了vue插件时,PyCharm仍然无法调用 v- 指令

PyCharm 的库自动检测是靠匹配已知发行文件名(vue.js、vue.min.js 这类)做模式匹配来识别"这是 Vue",这里是vue/vue2.js改名过的文件匹配失败,它就不认为这个页面用了 Vue
因此以上对vue2和vue3的引入方式是错误的,不能写成vue2.js、vue3.js的形式
写成以下这种形式pycharm就能成功调用v-指令

4.2 文本指令
[1] 概念
vue指令:放在标签上,以 v-开头的,都是vue的指令
任何html标签都可以放vue指令
[2] v-html 指令
作用:
1. 设置元素innerHTML,即变量的内容,渲染在当前标签中
2.将标签类型的字符串直接渲染成标签
演示:设置innerHTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue2/vue.js"></script>
</head>
<body>
<div id="d1">
<p v-html="name"></p>
</div>
</body>
<script>
var a = new Vue({
el:'#d1',
data:{name:'avril', school:'mit'}
})
</script>
</html>

演示:将字符串渲染成标签
使用插值语法无法渲染成标签
<body>
<div id="d1">
<p v-html="strHtml"></p>
</div>
</body>
<script>
var a = new Vue({
el:'#d1',
data:{
strHtml: '<a href="https://www.mit.edu">麻省理工网站</a>',
}
})
</script>

v-html可以渲染成标签
<body>
<div id="d1">
<p v-html="strHtml"></p>
</div>
</body>
<script>
var a = new Vue({
el:'#d1',
data:{
strHtml: '<a href="https://www.mit.edu">麻省理工网站</a>',
}
})
</script>

[3] v-text指令
设置元素的 textContent,渲染纯文本,覆盖元素内部原有内容。
1. 只渲染文本,HTML 标签会原样输出
2. 会覆盖标签内的内容
<body>
<div id="d1">
<p v-text="name">加拿大</p> <!--等价于插值语法<p>{{name}}</p>-->
</div>
</body>
<script>
var a = new Vue({
el:'#d1',
data:{
name: 'avril',
}
})
</script>

4.3 条件渲染
[1] 概念
条件渲染用于根据表达式的布尔值,控制 DOM 元素是否渲染或显示,核心指令:v-if、v-else-if、v-else、v-show。
[2] v-show指令
v-show 是条件显示,元素始终会被渲染到 DOM,只是通过 CSS控制隐藏 / 显示。
特点:初始渲染开销大,切换开销小;适合频繁切换显示隐藏的场景。
表达式为 true:display:block(标签正常显示)
表达式为 false:display:none(DOM 仍然存在,标签不显示)
<body>
<div id="d1">
<p v-show="result">加拿大</p>
</div>
</body>
<script>
var a = new Vue({
el:'#d1',
data:{
result: 'avril', /*布尔值为True*/
}
})
</script>

<body>
<div id="d1">
<p v-show="result">加拿大</p>
</div>
</body>
<script>
var a = new Vue({
el:'#d1',
data:{
result: 0, /*布尔值为False*/
}
})
</script>

[3] v-if / v-else-if / v-else指令
(1) 概念
v-if 是条件渲染
条件为 false 时,元素直接从 DOM 树移除
条件为 true 才创建 DOM。
特点:切换开销大,初始渲染开销小;适合条件很少改变的场景。
(2) 基础使用
<body>
<div id="d1">
<p v-if="result">加拿大</p> <!--等价于插值语法<p>{{name}}</p>-->
</div>
</body>
<script>
var a = new Vue({
el:'#d1',
data:{
result: 'avril',
}
})
</script>

布尔值为false时标签被移除
<body>
<div id="d1">
<p v-if="result">加拿大</p> <!--等价于插值语法<p>{{name}}</p>-->
</div>
</body>
<script>
var a = new Vue({
el:'#d1',
data:{
result: 0,
}
})
</script>

(3) 练习
输入用户成绩,显示:优秀、良好、及格、不及格
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue2/vue.js"></script>
</head>
<body>
<div id="d1">
<p>你的成绩是: {{score}}</p>
<p v-if="score>=90&&score<=100">优秀</p>
<p v-else-if="score>=80&&score<90">良好</p>
<p v-else-if="score>=60&&score<80">及格</p>
<p v-else>不及格</p>
</div>
</body>
<script>
var a = new Vue({
el: '#d1',
data: {
score: 99,
},
})
</script>
</html>

动态修改


[4] 补充:前端的响应式修改
前端可以通过 外层变量名._data.里层变量名 = ... 的形式进行响应式修改


4.4 事件指令
[1] 概念
js中的事件:点击、双击、滑动、滚动 点击click使用频率最高
事件指令为 v-on,作用:监听 DOM 事件,触发对应 JavaScript 逻辑。简写语法:@。
v-on: 事件名 ="函数名"
@事件名 ="函数名" (简写)
[2] 事件处理函数
事件处理函数handleClick、handleSay、handleEvent,写在 Vue 实例 methods 配置项内,当绑定的 DOM 事件触发时,Vue 会自动调用对应的函数,运行内部业务代码。
handleClick无参数事件处理函数。
触发时机:元素被点击。
特点:不带自定义参数,Vue 会自动把原生 event 事件对象作为第一个参数传入函数。
methods:{
handleClick(event){
// event 原生事件对象,保存点击相关信息
console.log('按钮被点击')
}
}
带自定义参数的事件处理函数。
触发时机:元素被点击。
特点:模板手动传入自定义参数,此时不会自动携带 event 对象;如果同时需要 event,必须在模板显式传入 $event。
<button @click="handleSay('hello')">点击</button>
methods:{
handleSay(msg){
console.log('收到消息:', msg)
}
}
handleEvent
用于手动接收原生 DOM 事件对象event。
触发时机:元素被点击。
特点:模板中显式传递event,在函数内拿到原生 event,可以获取点击坐标、目标元素、阻止冒泡等原生 DOM 操作。
<button @click="handleEvent($event)">点击</button>
$event用于传事件对象而不是变量名
methods:{
handleEvent(e){
console.log('原生事件对象', e.target)
}
}
| 函数名称 | 类型 | 参数特点 | 适用场景 |
|---|---|---|---|
| handleClick | 无参事件函数 | 自动得到 event | 不需要传自定义数据,只需要原生事件 |
| handleSay | 自定义参数函数 | 模板传自定义值,默认不带 event | 需要把页面数据、固定字符串传给方法 |
| handleEvent | 携带 $event 的函数 | 手动传入 $event,拿到原生事件对象 | 既要传自定义参数,又要操作原生 DOM 事件 |
补充要点:
1. 函数名只是约定命名,不是 Vue 内置关键字,可以改成任意合法名称。
2. methods 内的 this 默认指向当前 Vue 实例,可以直接读取 data 中的变量。
[3] 函数的两种等价写法
(1) 对象方法简写(ES6)
methods:{
handleClick(){
console.log(this)
}
}
(2) 完整函数赋值写法(ES5)
methods:{
handleClick: function(){
console.log(this)
}
}
[4] 代码演示
(1) 触发点击事件时显示与隐藏交替
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue2/vue.js"></script>
</head>
<body>
<div id="d1">
<img src="./img/1.jpeg" alt="" height="200px" v-show="is_show">
<br>
<button v-on:click="handleClick">点击显示或隐藏</button>
</div>
</body>
<script>
var a = new Vue({
el:'#d1',
data:{
is_show:1,
},
methods:{
handleClick:function (){
this.is_show = !this.is_show /*每点击一次让is_show取反,true与false交替*/
}
}
})
</script>
</html>
点击按钮时图片显示与隐藏交替出现


(2) 传参
常量传参
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue2/vue.js"></script>
</head>
<body>
<div id="d1">
<button @click="handleClick('giao')">点击在控制台打印</button> <!--常量传给变量名name-->
</div>
</body>
<script>
var a = new Vue({
el:'#d1',
methods:{
handleClick(name){
console.log(`${name}点击了`)
}
}
})
</script>
</html>
每点击一次计数增加

变量名传参
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue2/vue.js"></script>
</head>
<body>
<div id="d1">
<button @click="handleClick(school)">点击在控制台打印</button>
</div>
</body>
<script>
var a = new Vue({
el: '#d1',
data: {school: 'mit'}, /*通过标签传给methods*/
methods: {
handleClick(school) {
console.log(`学校${school}`)
}
}
})
</script>
</html>

[5] 事件修饰符
(1) 概念
事件修饰符是 v-on(简写 @)指令的后缀,以点号书写,用于在模板层面直接处理 DOM 事件细节,避免在业务方法中编写 event.preventDefault ()、event.stopPropagation () 等原生操作,让方法专注于数据逻辑。修饰符支持链式书写,运行顺序同书写顺序。
(2) 基础事件修饰符
| 修饰符 | 等价原生操作 | 作用说明 |
|---|---|---|
| .stop | event.stopPropagation() | 阻止事件向上冒泡传递 |
| .prevent | event.preventDefault() | 阻止事件默认行为,比如a链接的跳转 |
| .capture | addEventListener 第三参数 capture: true | 以捕获模式注册监听器,子元素事件先被外层捕获处理 |
| .self | 判断 event.target === 当前绑定元素 | 仅当事件目标就是当前元素本身时触发,子元素触发不运行 |
| .once | addEventListener 的 once: true | 事件只触发一次,触发后自动解绑(适用于抽奖页面) |
| .passive | addEventListener 的 passive: true | 告知浏览器默认行为立即运行,不等待事件回调,用于优化移动端滚动性能 |
【1】冒泡演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue2/vue.js"></script>
</head>
<body>
<div id="d1">
<div style="height: 150px; background-color: aqua" @click="handleDiv">
<button @click="handleButton">点击展示图片</button>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#d1',
data: {},
methods:{
handleButton(){
alert('giao')
},
handleDiv(){
alert('点击了div')
}
}
})
</script>
</html>
给div和button都绑定click事件
当点击div时,触发handleDiv

当点击button时,触发handleButton,点击确定触发handleDiv


【2】stop阻止冒泡
给button标签加上stop即可
<body>
<div id="d1">
<div style="height: 150px; background-color: aqua" @click="handleDiv">
<button @click.stop="handleButton">点击展示图片</button>
</div>
</div>
</body>
点击button再点击确定不会触发handleDiv

【3】self只有标签本身触发
给外层的div标签加上self,里层的标签button无法触发外层标签的运行
效果同上,点击button再点击确定不会触发handleDiv
<body>
<div id="d1">
<div style="height: 150px; background-color: aqua" @click.self="handleDiv">
<button @click="handleButton">点击展示图片</button>
</div>
</div>
</body>

【4】prevent阻止事件默认行为
例如阻止a链接的跳转
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue2/vue.js"></script>
</head>
<body>
<div id="d1">
<a href="https://www.mit.edu/" @click="handleA">麻省理工学院</a>
</div>
</body>
<script>
var vm = new Vue({
el: '#d1',
data: {},
methods:{
handleA(){
alert('点击了a标签')
}
}
})
</script>
</html>
点击a标签触发click事件,弹出alert,点击确定之后跳转到指定链接


给click加上prevent
<body>
<div id="d1">
<a href="https://www.mit.edu/" @click.prevent="handleA">麻省理工学院</a>
</div>
</body>
点击a标签触发click事件,弹出alert,点击确定之后由于prevent阻止a标签的默认行为无法跳转到指定链接

使用prevent可以改变a链接的目标地址
<body>
<div id="d1">
<a href="https://www.mit.edu/" @click.prevent="handleA">麻省理工学院</a>
</div>
</body>
<script>
var vm = new Vue({
el: '#d1',
data: {},
methods:{
handleA(){
alert('点击了a标签')
location.href = "https://www.harvard.edu/"
}
}
})
</script>
点击a标签,弹出alert,点击alert的确定之后跳转到了重定向的链接


【5】once事件只触发一次
<body>
<div id="d1">
<button @click="handlePrize">点击抽奖</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#d1',
data: {},
methods:{
handlePrize(){
console.log("幸运奖") }
}
})
</script>
每点击一次按钮,控制台会打印一次

给click加上once之后,click事件只会触发一次
<body>
<div id="d1">
<button @click.once="handlePrize">点击抽奖</button>
</div>
</body>

(3) 按键修饰符
【1】基础概念
键盘事件属于 DOM 原生事件,Vue 通过 v-on(简写 @)绑定到可聚焦元素(input、textarea、可编辑 div、全局 document 等)。
按键修饰符是附加在键盘事件后的点号后缀,用于限定只有按下指定按键时才执行回调,替代在方法内部手动判断 event.key。
两类键盘事件:
| 事件名 | 触发时机 | 典型用途 |
|---|---|---|
| keydown | 按键按下瞬间触发,长按会重复触发 | 快捷键拦截、输入实时校验 |
| keyup | 按键松开瞬间触发,长按只在松手触发一次 | 回车提交、输入完成后处理 |
补充:keypress 已被现代浏览器抛弃,不推荐使用。
事件对象核心属性:
| 属性 | 含义 |
|---|---|
| event.key | 按键的标准名称,如 Enter、PageDown、a,区分大小写 |
| event.code | 物理按键位置,如 KeyA,不受键盘布局影响 |
| event.ctrlKey / altKey / shiftKey / metaKey | 对应系统键是否处于按下状态 |
【2】常用按键别名
| 别名 | 对应按键 |
|---|---|
| .enter | Enter 回车键 |
| .tab | Tab 键 |
| .delete | Delete 与 Backspace 两个删除键 |
| .esc | Esc 键 |
| .space | 空格键 |
| .up | 方向上 |
| .down | 方向下 |
| .left | 方向左 |
| .right | 方向右 |
也可直接使用 KeyboardEvent.key 的 kebab-case 形式,例如 .page-down。
基础用法示例:
<!-- 输入框松开回车时提交 -->
<input @keyup.enter="submit" />
<!-- 按下 Tab 键时触发 -->
<input @keydown.tab="onTab" />
<!-- 删除键按下时清空内容 -->
<input @keydown.delete="clearInput" />
【3】按键事件代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue2/vue.js"></script>
</head>
<body>
<div id="d1">
<!--v-model做数据双向绑定,使用插值语法动态展示输入内容-->
<input type="text" v-model="content" @keyup="handleUp">---{{content}} <!--键盘上任意按键按下弹起时触发handleUp事件-->
</div>
</body>
<script>
var vm = new Vue({
el: '#d1',
data: {
content:''
},
methods:{
handleUp(){
console.log('按键弹起') }
}
})
</script>
</html>
当输入框内按键进行输入时,按键弹起一次keyup事件就触发一次
输入abcdef按键总共弹起6次,keyup事件触发6次,控制台打印6次

通过event的key判断按的是哪个按键
<body>
<div id="d1">
<!--v-model做数据双向绑定,使用插值语法动态展示输入内容-->
<input type="text" v-model="content" @keyup="handleUp">---{{content}} <!--键盘上任意按键按下弹起时触发handleUp事件-->
</div>
</body>
<script>
var vm = new Vue({
el: '#d1',
data: {
content:''
},
methods:{
handleUp(event){
console.log('按键弹起', event) }
}
})
</script>

【4】按键修饰符代码
<body>
<div id="d1">
<!--v-model做数据双向绑定,使用插值语法动态展示输入内容-->
<!--enter键弹起时才会触发handleUp事件-->
<input type="text" v-model="content" @keyup.enter="handleUp">---{{content}}
</div>
</body>
<script>
var vm = new Vue({
el: '#d1',
data: {
content:''
},
methods:{
handleUp(event){
console.log('按键弹起', event)
}
}
})
</script>
按其它按键都不会触发keyup事件,只有enter键弹起时才会触发
例如某些网页只有在按enter键时才会确定

【5】Vue2 与 Vue3 差异
| 项目 | Vue2 | Vue3 |
|---|---|---|
| keyCode 数字修饰符(按键与数字的对应) | 支持,如 @keyup.13 (13即enter键) | 移除,KeyboardEvent.keyCode 已抛弃 |
| 全局自定义别名 | Vue.config.keyCodes 注册 | 移除,直接使用 event.key 的 kebab-case |
| 原生按键名 | 有限支持 | 完整支持任意 event.key 转为 kebab-case |
4.5 属性指令
[1] 概念
v-bind,通过属性指令,将Vue实例中的数据绑定到HTML元素的属性上,并实现属性值的动态更新。
每个标签都有各自的属性
比如name、id、class、src、href 、link...
在以前的写法中,name=xx这样写就把name属性值固定
变量名对应的值发生变化,属性名随变量名发生变化
完整写法: v-bind: 属性名 ="变量名"
简写写法: : 属性名 ="变量名"
属性名是HTML元素的属性名称,变量名是Vue实例中的一个数据。
[2] 基础用法代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue2/vue.js"></script>
</head>
<body>
<div id="d1">
<img v-bind:src="picture" alt="" height="200px"> <!--src是属性名,picture是变量名-->
</div>
</body>
<script>
var a = new Vue({
el: '#d1',
data: {
picture: "./img/1.jpeg",
},
})
</script>
</html>

前端修改变量值,属性值随变量值发生改变

[3] class
(1) 概念
class是标签的属性,受属性指令控制
class的值通过属性指令传递,而不再直接写
(2) class的值为字符串
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue2/vue.js"></script>
<style>
.aqua {background-color: aqua;}
.blue {background-color: deepskyblue;}
.font {font-size: 60px;}
.height {height: 150px;}
.width {width: 150px;}
</style>
</head>
<body>
<div id="d1">
<!--class为属性,既然为属性就受属性指令的控制-->
<!-- <div class="height, width, background-color"></div>-->
<div :class="source1"></div>
</div>
</body>
<script>
var a = new Vue({
el: '#d1',
data: {
source1: 'height width aqua', /*class的值为字符串*/
},
})
</script>
</html>

class的值为字符串时,修改class的值需要修改整个字符串
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue2/vue.js"></script>
<style>
.aqua {background-color: aqua;}
.blue {background-color: deepskyblue;}
.font {font-size: 60px;}
.height {height: 150px;}
.width {width: 150px;}
</style>
</head>
<body>
<div id="d1">
<!--class为属性,既然为属性就受属性指令的控制-->
<!-- <div class="height, width, background-color"></div>-->
<div :class="source1"></div>
<button @click="handleChange">点击修改颜色</button>
</div>
</body>
<script>
var a = new Vue({
el: '#d1',
data: {
source1: 'height width aqua',
},
methods:{
handleChange(){
this.source1 = 'height width blue' /*修改class的值需要修改整个字符串*/
}
}
})
</script>
</html>

点击按钮之后

(3) class的值为数组
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue2/vue.js"></script>
<style>
.aqua {background-color: aqua;}
.blue {background-color: deepskyblue;}
.font {font-size: 60px;}
.height {height: 150px;}
.width {width: 150px;}
</style>
</head>
<body>
<div id="d1">
<!--class为属性,既然为属性就受属性指令的控制-->
<!-- <div class="height, width, background-color"></div>-->
<div :class="source1"></div>
<button @click="handleChange">点击修改颜色</button>
</div>
</body>
<script>
var a = new Vue({
el: '#d1',
data: {
source1: ['height', 'width', 'aqua'] /*class的值为数组*/
},
methods:{
handleChange(){
/*修改class的值无需修改整个数组*/
this.source1.pop() /*删除最后一个元素*/
this.source1.push('blue')
}
}
})
</script>
</html>

点击按钮之后

(4) class的值为对象
:class="{类名: 布尔变量}"
布尔变量为true就加上该属性,为false就移除该属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue2/vue.js"></script>
<style>
.aqua {background-color: aqua;}
.blue {background-color: deepskyblue;}
.font {font-size: 60px;}
.height {height: 150px;}
.width {width: 150px;}
</style>
</head>
<body>
<div id="d1">
<!--class为属性,既然为属性就受属性指令的控制-->
<!-- <div class="height, width, background-color"></div>-->
<div :class="source1"></div>
<button @click="handleChange">点击修改颜色</button>
</div>
</body>
<script>
var a = new Vue({
el: '#d1',
data: {
source1: {height: true, width: true, aqua:true, blue:false, font:false} /*class的值为对象*/
},
methods:{
handleChange(){
/*修改class为对象的值*/
this.source1.aqua = false
this.source1.blue = true
}
}
})
</script>
</html>
页面效果与之前一样
[4] style
(1) style的值为字符串
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue2/vue.js"></script>
</head>
<body>
<div id="d1">
<!--style为属性,既然为属性就受属性指令的控制-->
<!-- <div style="height: 100px; width:100px; background-color: aqua"></div>-->
<div :style="source1"></div>
<button @click="handleChange">点击修改颜色</button>
</div>
</body>
<script>
var a = new Vue({
el: '#d1',
data: {
source1: 'height: 100px; width:100px; background-color: aqua', /*style的值为字符串*/
},
methods: {
handleChange() {
/*style的值为字符串,修改时需要修改整个字符串*/
this.source1 = 'height: 100px; width:100px; background-color: violet'
}
}
})
</script>
</html>

点击按钮之后

(2) style的值为数组
<script>
var a = new Vue({
el: '#d1',
data: {
source1: [{'height': '100px'}, {'width': '100px'}, {'background-color': 'aqua'}], /*style的值为数组*/
},
methods: {
handleChange() {
/*style的值为数组,修改时只需要修改对应位置元素*/
this.source1[2]['background-color'] = 'deepskyblue' /*仍然需要加上key值*/
}
}
})
</script>
</html>

点击按钮之后
(3) style的值为对象
属性名支持驼峰命名(推荐)或者引号包裹横线。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue2/vue.js"></script>
</head>
<body>
<div id="d1">
<!--style为属性,既然为属性就受属性指令的控制-->
<!-- <div style="height: 100px; width:100px; background-color: aqua"></div>-->
<div :style="source1"></div>
<button @click="handleChange">点击修改边长</button>
</div>
</body>
<script>
var a = new Vue({
el: '#d1',
data: {
source1: {'height': '100px', 'width': '100px', 'background-color': 'aqua'} /*style的值为对象*/
},
methods: {
handleChange() {
/*style的值为对象,修改时只需要修改对应key值的元素*/
this.source1['height'] = '200px'
this.source1.width = '50px'
}
}
})
</script>
</html>

点击按钮之后

<script>
var a = new Vue({
el: '#d1',
data: {
source1: {'height': '100px', 'width': '100px', 'background-color': 'aqua'} /*style的值为对象*/
},
methods: {
handleChange() {
/*style的值为对象,修改时只需要修改对应key值的元素*/
this.source1['height'] = '200px'
this.source1.width = '50px'
this.source1.background-color = 'blue'
}
}
})
</script>
this.source1.background-color = 'blue'报错:
减号 -在 JavaScript 中是减法运算符。
background-color这个属性名包含减号,不能直接用点 .访问对象属性
| 写法 | 是否可用 | 适用场景 |
|---|---|---|
| 对象。属性名 | ✅可用 | 属性名没有横杠、空格、特殊字符,纯字母数字下划线,例如 width、height |
| 对象 [' 属性名 '] | ✅可用 | 属性名包含 -、空格、中文、特殊字符,例如 background-color |
正确写法:
this.source1['background-color'] = 'blue'
Vue 里写 style 对象还有一种推荐写法,使用驼峰 backgroundColor,就可以用点语法:
data 内:source1: {height:'100px', width:'100px', backgroundColor:'aqua'}
修改:this.source1.backgroundColor = 'blue'
4.6 练习
初始图片固定,点击开始按钮,每隔一秒随机切换一张图片,点击停止按钮切换图片停止
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue2/vue.js"></script>
</head>
<body>
<div id="d1">
<img :src="picture" alt="" height="200px"> <!--属性指令-->
<button @click="handleClick">开始/停止</button> <!--添加点击时间-->
</div>
</body>
<script>
var a = new Vue({
el: '#d1',
data: {
picture: './img/1.jpeg',
t: null, /*设置定时器*/
pics: ['/img/1.jpeg', '/img/2.jpeg', '/img/3.png', '/img/4.jpeg'],
},
methods: {
handleClick() {
if (this.t) { /*有值说明定时器已经开启*/
clearInterval(this.t)
this.t = null
}
else {
var _this = this /*用_this代指this*/
/*开启一个定时器,每隔1秒,让picture变*/
this.t = setInterval(function () {
/* Math.random() * _this.picture.length 0~1之间的数字乘数组的长度,就是0~4之间的随机数字 */
/* floor对小数进行向下取整*/
_this.picture = _this.pics[Math.floor(Math.random() * _this.pics.length)]
}, 1000) /*每隔1秒匿名函数运行一次*/
}
}
}
})
</script>
</html>


浙公网安备 33010602011771号