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项目

image

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

image

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的源码放到本地

image

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

运行效果

image

补充要点

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 代表挂载点

运行效果

image

 

补充要点

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 代表挂载点

运行效果

image

补充要点

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>

image

4. 指令系统

4.1 前提:安装vue插件

pycharm-文件-设置-插件

在Marketplace安装vue,有的pycharm可能自动安装无需主动安装

image

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

image

PyCharm 的库自动检测是靠匹配已知发行文件名(vue.js、vue.min.js 这类)做模式匹配来识别"这是 Vue",这里是vue/vue2.js改名过的文件匹配失败,它就不认为这个页面用了 Vue

因此以上对vue2和vue3的引入方式是错误的,不能写成vue2.js、vue3.js的形式

写成以下这种形式pycharm就能成功调用v-指令

image

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>

image

演示:将字符串渲染成标签

使用插值语法无法渲染成标签

<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>

image

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>

image

[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>

image

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>

image

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

image

[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>

image

布尔值为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>

image

(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>

image

动态修改

image

image

[4] 补充:前端的响应式修改

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

image

image

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('按钮被点击')
  }
}
handleSay

带自定义参数的事件处理函数。

触发时机:元素被点击。

特点:模板手动传入自定义参数,此时不会自动携带 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>

点击按钮时图片显示与隐藏交替出现

image

image

(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>

每点击一次计数增加

image

变量名传参

<!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>

image

[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

image

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

image

image

【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

image

【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>

image

【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,点击确定之后跳转到指定链接

image

image

给click加上prevent

<body>
<div id="d1">
    <a href="https://www.mit.edu/" @click.prevent="handleA">麻省理工学院</a>
</div>
</body>

点击a标签触发click事件,弹出alert,点击确定之后由于prevent阻止a标签的默认行为无法跳转到指定链接

image

使用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的确定之后跳转到了重定向的链接

image

image

【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>

每点击一次按钮,控制台会打印一次

image

给click加上once之后,click事件只会触发一次

<body>
<div id="d1">
    <button @click.once="handlePrize">点击抽奖</button>
</div>
</body>

image

(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次

image

通过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>

image

【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键时才会确定

image

【5】Vue2 与 Vue3 差异

项目Vue2Vue3
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>

image

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

image

[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>

image

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>

image

点击按钮之后

image

(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>

image

点击按钮之后

image

(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>

image

点击按钮之后

image

(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>

image

点击按钮之后

image 

(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>

image

点击按钮之后

image

<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>

image

 

posted @ 2026-10-10 05:01  pythondjango  阅读(8)  评论(0)    收藏  举报