本章主要介绍vue3中的基础指令使用方式和一些开发技巧。分为基础指令,逻辑指令,列表指令,事件,MVVM数据绑定与监听。本章中所有代码例子都是在使用Vite 创建的 vue项目中来完成的。
基础语法指令
- [2.1 基础指令](#2.1 基础指令)
- [2.1.1 设置变量](#2.1.1 设置变量)
- [2.1.2 v-text与v-html 指令](#2.1.2 v-text与v-html 指令)
- [2.1.3 函数](#2.1.3 函数)
- [2.1.4 v-bind 绑定变量](#2.1.4 v-bind 绑定变量)
- [2.1.5 css类名称绑定](#2.1.5 css类名称绑定)
- [2.1.6 样式属性绑定](#2.1.6 样式属性绑定)
- [2.2 逻辑指令](#2.2 逻辑指令)
- [2.2.1 判断 v-if](#2.2.1 判断 v-if)
- [2.2.2 v-show 与v-if 区别](#2.2.2 v-show 与v-if 区别)
- [2.3 列表指令](#2.3 列表指令)
- [2.3.1 数组](#2.3.1 数组)
- 2.3.2列表
- [2.3.3 对象](#2.3.3 对象)
- [2.3.4 列表使用](#2.3.4 列表使用)
- [2.4 事件](#2.4 事件)
- [2.4.1 v-on 使用](#2.4.1 v-on 使用)
- [2.4.2 事件对象](#2.4.2 事件对象)
- [2.4.3 事件修饰符](#2.4.3 事件修饰符)
- [2.4.4 按键修饰符](#2.4.4 按键修饰符)
- [2.5 响应性函数ref 与reactivity](#2.5 响应性函数ref 与reactivity)
- [2.6 输入表格v-model指令](#2.6 输入表格v-model指令)
- [2.7 Computed 模板函数](#2.7 Computed 模板函数)
- [2.8 Watcher](#2.8 Watcher)
其他章节
第一章 Vue3项目创建 1 Vue CLI 创建vue项目
第一章 Vue3项目创建 2 使用 Webpack 5 搭建 vue项目
第一章 Vue3项目创建 3 Vite 创建 vue项目
第二章 Vue3 基础语法指令
第三章 Vue Router路由器的使用
第四章 VUE常用 UI 库 1 ( element-plus,Ant ,naiveui,ArcoDesign)
第四章 VUE常用 UI 库 2 ( ailwind 后台框架)
2.1 基础指令
传统Vue写法需要在代码中定义 Composition API模块,在现在的vue3写法可以加入
在<script>
块中添加setup
属性,表示里面的代码被编译成setup()
函数中的功能内容。这意味着它只在第一次导入组件时执行一次,里面的代码<script setup>
将在每次创建组件的实例时执行。
vue
<script setup>
console.log('脚本内容')
</script>
2.1.1 设置变量
在vue模板文件中写入对应的指令语法,这些指令语法在编译成浏览器中可以运行的html代码。从这里开始,我们将演示在vue模板文件编写 Vue.js 指令功能,并在浏览器中运行这些指令代码。在App.vue 文件中加入html的 h1 标签,在script标签中,写入JavaScript代码alert('欢迎来到我的代码世界')代码。
javascript
<script setup>
</script>
<template>
<h1>Vue 3 入门</h1>
</template>
<script setup>
alert('欢迎来到我的代码世界');
console.log('欢迎来到我的代码世界');
</script>
<style scoped>
</style>
更新保存 App.vue 文件中的指令代码后,内容会自动反映到浏览器中,开发者可以在工具控制台中会看到"欢迎来到我的代码世界"。
标记标签指令
javascript
<script setup>
</script>
<style scoped>
</style>
我会发现脚本标签中写的代码是在组件加载时自动执行的记住这一点,因为它很重要,它们是通过内设标签来找到要加载编译的模板代码。
在 script 标签中有一个名为 setup 的字符串,但请注意不要删除它,因为 script 是必要的设置,它告诉开发者那些 script 标签中可以编写 Vue.js 代码(Composition API)。如果删除它会使用 Vue.js 中的JavaScript 代码无法正常运行。同样style样式标签中加入scoped属性标记为Vue指令可以编辑的style样式属性。
- script setup script 脚本编译标签
- style scoped css样式编译标签
绑定在加入setup标识的 script 标签中定义变量(必须有setup标识),例如定义一个message变量,再通过模板template引入和使用这个变量信息。在script 标签中定义好变量值,在模板标签中使用{{ 变量名 }}**两个小括号将变量名包裹起来的方法将变量值绑定到模板中html属性中。
变量{{属性}}绑定
vue
<script setup>
const message = '第一个脚本变量';<-----|
</script> |
<template> |
<h1> vue3 入门</h1> |
<p>{{ message }}</p> <-----------|
</template>
<style scoped>
</style>
这段代码在运行的浏览器中可以显示message变量消息的内容。
定义的变量在模板template标签中的还可以像操作javascript函数一样来操作,它的使用方法与在script中操作javascript函数变量基本是一样的,我们可以像操作普通javascript变量一样来操作这些模板中的变量了。
javascript
<script setup>
const message = '第一个脚本变量';
alert('欢迎来到我的代码世界');
console.log('欢迎来到我的代码世界');
</script>
<template>
<h1> vue3 入门</h1>
<p>{{ message }}</p>
<div>{{ message.length > 10 ? '大于' : '小于' }}10个字符</div>
<div>{{ message.length * 10 }}</div>
</template>
<style scoped>
</style>
- 判断 : message.length > 10 ? '大于' : '小于'
- 字符长度: message.length
总结
- 1 vue模板分成三大部分 script,template,style。
- 2 可以在script中定义变量值,通过{{}}方式绑定到template中。
- 3 script中别忘记需要加setup,style加scoped标记。
javascript
<script setup>
</script>
<template>
</template>
<style scoped>
</style>
2.1.2 v-text与v-html 指令
有的时候需要在HTML元素(div, p, button, span, ...) 中操作一些特殊属元素例如,将变量中的值绑定到HTML元素中或者它的特殊属性中来展示。
** v-text**
使用 v-text 指令将变量中的值,以字符串的方法绑定到 html元素中。可以在浏览器上看到 v-text 指令中设置的变量的内容。
javascript
<script setup>
const message = '<h1>第一个脚本变量</h1>';
</script>
<template>
<p>{{ message }}</p>
<p v-text="message"></p>
</template>
v-html
通过标签中的v-html 属性,可以将脚本中的变量对象转换成的HTML 代码显示在屏幕上。v-html 与 v-text 最大的不同是v-html将变量中的字符串转换成html元素,而v-text 不会转换字符串成为html元素。
javascript
<script setup>
const message = '<h1>第一个脚本变量</h1>';
</script>
<template>
<p>{{ message }}</p>
<p v-text="message"></p>
<div v-html="message"></div>
</template>
在v-text指令中message为字符串 < h1 >第一个脚本变量< /h1>,v-html指令中messags变量是包含在< h1>元素中的标题。
2.1.3 函数
在vue文件中允许在脚本标签中内设函数,而这些内设的函数可以像普通的javascript函数一样被执行与调用。例如我们定义一个将变量字符串转换成大写的函数upperCase,再在脚本标签中执行调用这个函数。
javascript
<script setup>
let message = 'Zhtbs';
function upperCase(){
message = message.toUpperCase();
};
//const upperCase = () => {
//};
//字母转换成大写字母
upperCase();
</script>
<template>
<h1>Vue3 例子</h1>
<div v-text="message"></div>
</template>
在浏览中看到message变量定义的字符串已经被函数upperCase转换成大写字母了。
2.1.4 v-bind 绑定变量
v-bind 指令的作用是绑定数据和元素属性,开发者通过使用 v-bind 指令将定义好的变量信息绑定到 html 标签的属性中。
v-bind 指令设置方法在html元素标签内,属性名称前面加上 v-bind: (变量名前只有一个冒号)在用等于号绑定变量名称。
javascript
<a v-bind:href="变量名称">连接内容</a >
为了方便大家来理解,我们演示一下将javasrcipt脚本中的变量绑定到模板中的a标签 中经常使用的href属性上面。在使用 v-bind 指令设置 href 属性时,可以如下描述指令代码。:(冒号)在 v-bind 之后,后跟属性名称。定义了一个链接变量URL, URL指向www.baidu.com百度。通过v-bind 将URL绑定到href 属性上面来。
javascript
<script setup>
const link = 'https://www.baidu.com';
</script>
<template>
<h1>Vue3 例子</h1>
<a v-bind:href="link">baidu连接</a>
</template>
<style scoped>
</style>
在页面中可以通过点击baidu连接 ,将浏览器页面跳转到www.baidu.com百度首页。
上面演示了如何使用 v-bind 设置 href 属性,在通过JavaScript 动态更改它href 属性中的内容。这样做可以更好的体现页面中mvvm的设计思想,可以通过控制脚本中变量来实时控制模板中html属性的变量内容。
2.1.5 css类名称绑定
v-bind指令不光可以绑定 script 脚本标签中的变量,同时也可以将style标签中的css样式绑定到模板中html元素属性中。
在v-bind:绑定css样式类名称的时候可以使用简化语法来缩写指令,将v-bind去掉只保留:冒号。
html
用:来绑定css变量名称 判断变量名称
| |
v-bind:class="{class名: 变量名称 or (true or false)}"
<a v-bind:href="link" :class="{zhtbs:true}">baidu连接</a>
1 使用 v-bind 设置css类方式
在v-bind指令中需要使用判断值来决定css样式是否被改变。在绑定的变量中设置 true、false值来决定绑定的变量是否被使用。
javascript
<script setup>
const link = 'https://www.baidu.com';
const iszhtbs=true;---------|
</script> |
<template> | iszhtbs为true样式出现
<a v-bind:href="link" |
:class="{zhtbs:iszhtbs}">baidu连接</a>
</template>
<style scoped>
.zhtbs {
color: red;
font-weight: 900;
}
</style>
- iszhtbs 的变量被设置为 false,css样式不会被绑定,下面字体不会变成红色。
2 v-bind 指令中的多类设置
在实际开发中元素的css样式会有多个,这些css样式会根据业务数据的变化而发生改变。可以通过v-bind绑定指令中来实现多个css样式变化的业务逻辑。在绑定的指令中用**,号** 将不同业务的css样式类分组,在通过每组绑定的变量来判断这个css样式是否在页面中执行与展示。
html
<script setup>
const iszhtbs = true;
const isBlack = true;
</script>
<p :class="{zhtbs:iszhtbs,back:isback}"></p>
在页面中定义两个css样式,在分别定义两个css样式控制变量。在脚本中通过控制iszhtbs和isback的true,false值来达到对html元素中的css样式控制。
javascript
<script setup>
const link = 'https://www.baidu.com';
const iszhtbs=true;//css控制标量
const isback=true;//css控制标量
</script>
<template>
<h1>Vue3 例子</h1>
<a v-bind:href="link"
v-bind:class="{zhtbs:iszhtbs,back:isback}">baidu连接</a>
</template>
<style scoped>
.zhtbs {
color: red;
font-weight: 900;
}
.back {
background-color: black;
}
</style>
- v-bind 指令中可以加入逻辑判断语法&&与 ||。
- 逻辑语法可以多种组合应用。
javascript
v-bind:class="{变量名称 && 'class名称'}"
<p :class="iszhtbs && 'zhtbs'"></p>
v-bind:class="{变量名称 || 'class名称'}"
<p :class="iszhtbs ? 'zhtbs':'back'"></p>
// 以在数组中使多种逻辑组合。
<p :class="[iszhtbs, isBlack]"></p>
<p :class="[{ zhtbs: 'iszhtbs' },isback]"></p>
<p :class="[iszhtbs && 'zhtbs',isback]"></p>
<p :class="[iszhtbs ? 'zhtbs' : 'back', isback]"></p>
2.1.6 样式属性绑定
对于 style 属性,有多种描述方式,就像 class 一样。您可以使用内联对象来设置多个属性。它用于定义变量 activeColor 和 fontStress 并设置 v-bind 的样式属性。如果要将文本颜色从红色更改为蓝色,请将 activeColor 的值从红色更改为蓝色。
javascript
<script setup>
const activeColor = 'red';
const fontStress = '900';
</script>
<template>
<h1>Vue 3 入门</h1>
<p :style="{ color: activeColor, fontWeight: fontStress }">
v-bind设置style样式属性
</p>
</template>
上面fontWeight的描述是驼峰式的,但是在使用普通样式属性的时候,要用单引号。
vue
<p :style="{ color: activeColor, 'font-weight': fontStress }">
v-bind设置style样式属性
</p>
您还可以在变量端设置样式。通过在变量端设置样式,模板标签变得更清晰、更易于查看。
javascript
<script setup>
const styleObjcet = {
color: 'red',
fontWeight: 900,
};
</script>
<template>
<h1>Vue 3 入门</h1>
<p :style="styleObjcet"> v-bind设置style样式属性</p>
</template>
也可以像普通的样式属性一样写。
javascript
<script setup>
const styleObjcet = 'color:red;font-weight:900';
</script>
<template>
<h1>Vue 3 入门</h1>
<p :style="styleObjcet">v-bind设置style样式属性</p>
</template>
2.2 逻辑指令
在vue模板中进行条件判断时,会使用到v-if 和 v-show 指令 。这些判断指令通常会根据条件来控制模板中要显示的内容或者在输入表单发生错误时显示错误消息,又或者做一些其他复杂的业务逻辑判断。v-if 和 v-show 在使用上是有所区别的,我们将对这些指令进行逐一介绍使用的方法和不同情况下使用的区别。
2.2.1 判断 v-if
v-if 指令是一个条件判断指令,通常会用在显示/隐藏显示内容或者更改某个元的内容,或根据条件来修改参数值。v-if判断指令和其他语言的判断指令一样,会有其他的判断分支,它们分别是v-else-if 和 v-else 与 v-if 。它们在进行业务判断的时候可以同时使用,也可以不必同时使用,要根据具体业务逻辑来判断怎么使用。在使用的时候注意 v-if 是必需的,但 v-else-if 和 v-else 仅在必要同时使用。
v-if、v-else-if、v-else 指令只能在vue模板标签内使用,不能在javasrcipt脚本中使用这些指令。
如果要在javasrcipt脚本中做逻辑判断,需要使用普通的javasrcipt语法 if, else-if, else。
v-if 写在素中
javascript
<script setup>
// 使用js语法判断分支。 if, else-if, else
</script>
<template>
<div v-if="条件式">内容</div>
<div v-else-if="条件式">内容</div>
<div v-else>内容</div>
</template>
例如,通过属性error值来判断信息是否在屏幕上显示提示内容,通过 v-if 指令来判断error 值是否存在,如果error 值存在就把error内容显示出来,没有error 值不存在error内容就隐藏起来。
javascript
<script setup>
const error = '错误信息';
</script>
<template>
<h1>Vue 3 入门</h1>
<div v-if="error">{{ error }}</div>
</template>
还可以使用布尔值 true 或 false 作为条件,来判断表达式中的值是否显示。
javascript
<script setup>
const error = true;
</script>
<template>
<h1>Vue 3 入门</h1>
<div> v-if="error">错误发生。</div>
</template>
v-else 分支
在某些情况下,如果没有错误信息的时候要提示给用户没有错误内容。在这种情况下,需要使用到 v-else 指令。v-else 描述了当不满足v-if 的条件时要执行的内容,例如错误(error)变量中没有任何内容,屏幕不会显错误(error)值中得内容,但v-else指令中的内容会在屏幕中档显示出来。
javascript
<script setup>
const error = '';
</script>
<template>
<h1>Vue 3 入门</h1>
<div v-if="error">{{ error }}</div>
<div v-else>else发生</div>
</template>
v-else-if判断多个条件。例如 有多个判断条件,每个判断条件要显示的内容不一样,这个时候就可以使用到v-else-if指令来进行条件判断。
javascript
<script setup>
const stock = 0;
</script>
<template>
<h1>Vue 3 入门</h1>
<div v-if="stock > 5">商品库存剩余{{stock}}</div>
<div v-else-if="stock === 0">没有库存</div>
<div v-else>库存不正常,请盘库修复库存</div>
</template>
v-if 指令可以根据判断属性的内容而更改显示内容,进入到条件对应的逻辑分支中。
逻辑判断规则是v-if、v-else只能有一个分支条件,但是v-else-if可以有多个分支条件。
v-if 也可以更具条件进行大面积元素的内容显示
html
<div v-if="true">
<div>...</div>
<div>
<p>...</p>
<p>...</p>
</div>
</div>
2.2.2 v-show 与v-if 区别
v-show 指令 与 v-if 指令在使用方法和功能上都非常的相似,都是根据脚本中的元素值来进行逻辑判断 。v-show 指令没有诸如 v-if 指令中的v-else-if 之类的可以一起使用的条件分支,它只能根据条件来控制元素的显示/隐藏。
html
<div v-show="条件">内容</div>;
如果error变量的值为true,则显示内容;如果为false,则不显示内容。
html
<script setup>
const error = true;
</script>
<template>
<h1>Vue 3 入门</h1>
<div v-show="error">错误发生后出现的事情</div>
</template>
v-if 和 v-show 的区别
就下面的代码而言,v-if 和 v-show 可以做同样的事情。如果error为true,会显示两个"An error has occurred.",如果为false,则什么也不会显示。只看这一点,好像没有必要为v-else-if设置多个条件的v-show指令。但是v-show的存在一定是有什么意义的。
html
<script setup>
const error = true;
</script>
<template>
<h1>Vue 3 入门</h1>
<div v-if="error">错误发生。(v-if)</div>
<div v-show="error">错误发生。(v-show)</div>
</template>
在浏览器的开发者工具中查看元素信息,可以看到两个判断信息的元素都存在的。
将判断条件改成false。
html
<script setup>
const error = false;
</script>
<template>
<h1>Vue 3入门</h1>
<div v-if="error">错误发生。(v-if)</div>
<div v-show="error">错误发生。(v-show)</div>
</template>
将error参数改成 false,这个时候 v-if 和 v-show 显示的原理是有很大不同。在元素使用v-if指令的情况下,元素不存在。而元素使用v-show的情况下,元素本身存在浏览其中,但是这个元素的style属性中,display被设置为none。
通过上面的代码实例,大家会发现v-show是通过display属性来控制目标元素的显示/隐藏的。v-if和v-show区别主要在于它们的隐藏的方法不同,但是我们在开发时候怎么来选择v-if和v-show,选择v-show会有那些好处呢?
v-show 的实现原理是元素属性中的 none 和 block 之间切换,而它这样的切换会比使用v-if 添加或删除元素的处理负载要低当页面中有大量的业务逻辑,要通过判断数据来创建新的页面元素的时候,v-show 指令会比v-if 更快的样页面加载出来。页面的加载速度对于用户和交互很重要,因此尽可能进行最低成本的数据加载。
2.3 列表指令
v-for 指令是用于将数组,列表,元素中的对象进行循环遍历。在构建应用程序时总会有这样的情况,需要将数组或者列表中的数据对象展示到浏览器页面中,这些数据对象都是由json元素组成,我们通过v-for 指令将它们循环展示出来。
2.3.1 数组
例如,要将我们学习到的前台语言保存在一个数组中,在模板中通过指定数组索引的方式将数组信息显示在浏览器中。
html
<script setup>
const languages = ['JavaScript', 'TypeScript', 'Vue.js'];
</script>
<template>
<h1>Vue3 数组操作</h1>
<p>{{ languages[0] }}</p>
<p>{{ languages[1] }}</p>
<p>{{ languages[2] }}</p>
</template>
如果用浏览器查看,保存在数组中的信息将显示如下。
而大部分开发中我们是不会直接使用索引来获得数组中的元素到页面中的,通常会使用v-for 循环遍历的方式来获得数组中的元素内容。
html
<script setup>
const languages = ['JavaScript', 'TypeScript', 'Vue.js', 'React', 'Rust', 'Go'];
</script>
<template>
<h1>Vue3 数组操作</h1>
<p v-for="zht in languages" :key="zht">{{ zht }}</p>
</template>
v-for 指令中"zht in languages"将languages数组中的对象引用赋值给zht 对象,在循环中依次取出的key值中的数据。
key 属性中设置循环体唯一标识符。
使用 v-for 指令时,需要使用 v-bind 为 key 属性设置引用唯一标识符
2.3.2列表
在上面的例子中我们使用v-for指令显示的是数组中的元素内容。但是在Vue中开发中,数组列表中大多数保存的是json对象而不是数值,我们需要将这些列表中的json对象值遍历取出。这里还是会使用到v-for 指令将列表中的json对象遍历取出。
定义用户信息列表,用户信息作为对象存储在数组中。
html
<script setup>
const users = [
{ id: 1, name: 'zht', email: 'zht114001@163.com', admin: true },
{ id: 2, name: 'kaimi', email: 'jane@163.com', admin: false },
{ id: 3, name: 'fun', email: 'fun@163.com', admin: false },
];
</script>
就像使用数组中使用 v-for 指令一样。
html
<template>
<h1>Vue3 用户列表</h1>
<p v-for="user in users" :key="zht.id">{{ user }}</p>
</template>
和数组一样,通过v-for按顺序从数组中取出列表中的值(对象),每个对象的内容都原样显示在浏览器上。
使用 v-for 列出对象
上面循环显示出来的是整个对象内容,但是我们需要显示出来的是对象中的属性值。这样需要重写一下上面的代码,通过对象的属性引用(对象.属性名称)拿到对象中的属性值,在循环体中显示出来。
使用 user.property 方式访问到对象中的属性值。
html
<script setup>
const users = [
{ id: 1, name: 'zht', email: 'zht114001@163.com', admin: true },
{ id: 2, name: 'kaimi', email: 'jane@163.com', admin: false },
{ id: 3, name: 'fun', email: 'fun@163.com', admin: false },
];
</script>
<template>
<h1>Vue3 数组操作</h1>
<p v-for="zht in users" :key="zht.id"> {{ zht.id }}:{{ zht.name }}
({{ zht.email }})</p>
</template>
加入ul和li标签代替div,改写如下。
html
<template>
<h1>Vue3 数组操作</h1>
<ul>
<li v-for="zht in users" :key="zht.id">
{{ zht.id }}:{{ zht.name }}({{ zht.email }})
</li>
</ul>
</template>
也可以改写成表格格式显示。
html
<script setup>
const users = [
{ id: 1, name: 'zht', email: 'zht114001@163.com', admin: true },
{ id: 2, name: 'kaimi', email: 'jane@163.com', admin: false },
{ id: 3, name: 'fun', email: 'fun@163.com', admin: false },
];
</script>
<template>
<h1>Vue3 数组操作</h1>
<table>
<thead>
<tr>
<td>ID</td>
<td>名称</td>
<td>Email</td>
</tr>
</thead>
<tbody>
<tr v-for="zht in users" :key="zht.id">
<td>{{ zht.id }}</td>
<td>{{ zht.name }}</td>
<td>{{ zht.email }}</td>
</tr>
</tbody>
</table>
</template>
索引 index
在v-for指令中,通过index获得到每个遍历行中的索引位置。
v-for指令中用括号将 列表引用与索引包裹起来。< li v-for="(zht, index) in users" :key="zht">
索引从0开始起位,逐行加一,显示如下。
html
<template>
<h1>Vue3 数组操作</h1>
<ul>
<li v-for="(zht, index) in users" :key="zht.id">
{{ index }}索引 {{ zht.id }}:{{ zht.name }}({{ zht.email }})
</li>
</ul>
</template>
template标签中v-for指令
v-for一般都是和html标签一起使用,例如 div 元素中加入 v-for指令。但是在开发中有的时候v-for指令需要单独使用不需要加在任何html标签中。这个时候就需要使用到template标签,在template标签中加入v-for指令,生产模板代码中不会有任何html标签元素存在。
html
<template>
<template v-for="zht in users" :key="zht.id">
<div>
{{ zht.id }}{{ zht.name }}{{ zht.email }}
</div>
</template>
</template>
v-for 指令中的of赋值
我们在 v-for 指令中使用了"in",但也可以使用"of"。显示内容无论是in还是of都不会有改变。根据个人开发习惯来决定使用 in和of为列表赋值引用对象。
html
<div v-for="user of users" :key="user.id">
2.3.3 对象
到目前为止,我们演示了 v-for 指令如何遍历数组与列表。在这里将学习与演示到如何使用 v-for 指令列出对象内容。
html
<script setup>
const user = { id: 1, name: 'zht', email: 'zht114001@163.com', admin: true };
</script>
<template>
<h1>Vue3 对象</h1>
<div v-for="zht in user" :key="zht.id">{{ zht }}</div>
</template>
可以看到对象的属性值按顺序显示出来。
使用属v-for="(value, name) in user"()方法按对象的属性名称来显示属性值。
html
<template>
<h1>Vue 3 对象</h1>
<div v-for="(value, name) in user" :key="value">{{ name }}:{{ value }}</div>
</template>
2.3.4 列表使用
1 列表与对象混合使用
在开发中我们通常会将 v-for for array objects 和 v-for for objects两种方法混合使用来遍历出列表对象中的属性值。先将对象中的属性循环出来,在属性中在把属性名称与属性值取出。
html
<script setup>
const users = [
{ id: 1, name: 'zht', email: 'zht114001@163.com', admin: true },
{ id: 2, name: 'kaimi', email: 'jane@163.com', admin: false },
{ id: 3, name: 'fun', email: 'fun@163.com', admin: false },
];
</script>
<template>
<h1>Vue 3 对象属性</h1>
<div v-for="user in users" :key="user.id">
<div v-for="(value, name) in user" :key="value">{{ name }}:{{ value }}</div>
</div>
</template>
2 列表判断
通过使用 v-for 和 v-if 指令组合,可以对列表对象中的属性与值进行筛选,将符合条件的信息显示出来。例如 admin: true信息我们显示出为管理员,如果admin: false显示为普通用户。 v-for 和 v-if 通过判断列表中的admin 属性来确定哪条信息是管理员。
html
<script setup>
const users = [
{ id: 1, name: 'zht', email: 'zht114001@163.com', admin: true },
{ id: 2, name: 'kaimi', email: 'jane@163.com', admin: false },
{ id: 3, name: 'fun', email: 'fun@163.com', admin: false },
];
</script>
<template>
<h1>Vue 3 对象属性</h1>
<div v-for="zht in users" :key="zht.id">
{{ zht.id }}:{{ zht.name }}({{ zht.email }})
<template v-if="!zht.admin">
普通用户
</template>
<template v-else>
管理员
</template>
</div>
</template>
浏览器显示内容。
2.4 事件
页面中元素中通过事件指令来绑定脚本中函数。事件由用户执行的操作触发,例如单击按钮、移动鼠标或按下键盘。Vue.js 允许使用 v-on 指令接收用户触发的事件。通过使用 v-on 指令接收事件,也可以将其用作于执行另一个进程的触发器。即使设置了 v-on 指令,也需要触发事件发生,否则事件不会被执行。
2.4.1 v-on 使用
让我们来设置一个用户单击按钮时会触发的单击事件。在模板的button属性中设置点击事件,它的写法是在 v-on 指令后添加一个 :(冒号)在定义一个事件类别(click)= 函数名称(v-on:click="函数名称")。在 JavaScript 脚本中创建要执行的函数,我们这里定义一个名为clickButton的函数。将这个函数名称绑定到模板中v-on:click事件中去,当用户点击页面中的button时候事件会执行 JavaScript 脚本中clickButton 函数里面的内容。
html
<script setup>
const clickButton = () => {
alert("我被点击了");
};
</script>
<template>
<h1>Vue 3 事件</h1>
// v-on: 事件类型 = 函数名称
<button v-on:click="clickButton">点击按钮</button>
</template>
1 v-on指令缩写
v-on指令有一个缩写,v-on:click可以写成@click,开发中可以使用省略的@click来绑定事件。
html
<button @click="clickButton">点击按钮</button>
2 绑定其他事件
在开发中我不仅会使用到点击事件@click,也会使用到其他事件,例如绑定一个双击事件@dbclick。
html
<button @dbclick="clickButton">双击事件</button>
v-on指令也可以用于其他事件 mouseover 和 mouseenter等。
3 事件传递参数
可以在函数括号中设置参数值,在参数值传递到脚本函数中。
html
<script setup>
const clickButton = (msg) => {
alert(msg);
};
</script>
<template>
<h1>Vue 3 事件</h1>
<button @click="clickButton('我要点击')">点击按钮</button>
</template>
传动态参数在脚本中定参数变量名称,在模板函数中直接字入变量名称不需要其他修饰符号。
html
<script setup>
const clickButton = (msg) => {
alert(msg);
};
const zht=1;
</script>
<template>
<h1>Vue 3 事件</h1>
<button @click="clickButton(zht)">点击按钮</button>
</template>
4 执行多函数
在模板内的一个事件中,同时可以触发多个函数,使用,号
将函数名称分开。当点击这个按钮的时候,几个函数被先后执行。
html
<script setup>
const clickButton = (msg) => {
alert(msg);
};
const another = (msg) => {
alert(msg);
};
const zht=1;
</script>
<template>
<h1>Vue 3 事件</h1>
<button @click="clickButton('我要点击'), another(zht)">点击按钮</button>
</template>
2.4.2 事件对象
在 Vue 中,每个事件被触发执行后都会在脚本的对应函数中产生一个与事件对象$event。我们可以通过检查接收到的事件对象中的 target 属性来获取有关被单击元素的信息。
html
<script setup>
const clickButton = (event) => {
console.log(event.target);
};
</script>
<template>
<h1>Vue 3 事件</h1>
<button @click="clickButton($event)">点击按钮</button>
</template>
单击按钮,在浏览中的开发人员工具控制台会显示一下信息内容。获得到这个事件元素的整体html字符串。
html
<button">点击按钮</button>
我们可以通过事件对象来访问元素,并且改变这些被访问元素中的属性值。例如我们改变一下这个按钮的样式。通过添加以下设置,按钮的颜色将在单击时变为红色。
html
<script setup>
const clickButton = (event) => {
event.target.style.backgroundColor = 'red';
};
</script>
<template>
<h1>Vue 3 事件</h1>
<button @click="clickButton($event)">点击按钮</button>
</template>
事件参数传值
在开发的时候我们使用event.target来获得事件中的参数内容。
html
<script setup>
const clickButton = (event) => {
alert(event.target.id);
alert(event.target.name);
};
</script>
<template>
<h1>Vue 3 事件</h1>
<button id="1" name="zht" @click="clickButton($event)">点击按钮</button>
</template>
2.4.3 事件修饰符
事件修饰符是用来定义事件一些其他辅助功能,定义方法是在方法名称后边添加修饰符关键字。
html
v-on:click.修饰符
v-on:click.prevent
例如,当执行表单from的提交时,页面总是重新加载。要防止页面重新加载,我们需要使用事件对象并调用 event.preventDefault方法来解决。在Vue框架中的实现方式很简单,就是在事件中加上修饰符prevent,执行preventDefault即可。不使用prevent时查看设置方法,然后设置preventn并查看运行情况。
下面,提交事件设置在表单标签中。如果你设置提交事件并点击表单标签内的按钮,事件将被接收并执行发送功能。当你点击发送按钮时,发送功能被执行,控制台上显示"发送",但是当页面重新加载时"发送"字符消失了
html
<script setup>
const send = () => {
console.log('保存');
};
</script>
<template>
<h1>Vue 3 事件</h1>
<form @submit="send">
<button>保存</button>
</form>
</template>
表单提交之后,在浏览器开发工具后台中没有打印出来'保存'两个字,说明页面已经重新加载了。
我们在这个函数事件对象上加入 preventDefault 方法来防止页面重新加载。这样可以通过运行 preventDefault 方法取消提交的默认行为。
html
<script setup>
const send = (event) => {
//防止重新加载
event.preventDefault();
console.log('保存');
};
</script>
<template>
<h1>Vue 3 事件</h1>
<form @submit="send">
<button>保存</button>
</form>
</template>
表单提交之后,在浏览器开发工具后台中有打印出来'保存'两个字,说明页面没有重新加载。
上面的代码中我们成功的防止了页面的重新加载,但是我们使用了事件中的方法这样的代码写法。在vue中我们
通过使用事件修饰符来完成相同的功能,这样可以更简便的书写代码,而不在调用事件对象了。在@submit 后天加入prevent(@submit.prevent)修饰符来完成阻止页面重新加载。
html
<script setup>
const send = (event) => {
console.log('保存');
};
</script>
<template>
<h1>Vue 3 事件</h1>
//加入阻止默认事件修饰符
<form @submit.prevent="send">
<button>保存</button>
</form>
</template>
在点检保存按钮之后在浏览器开发工具后台中打印出来'保存'。
其他修饰符关键字
.stop
表示停止冒泡
.prevent
表示阻止默认事件
.capture
表示使用事件捕获模式
.self
表示当在event.target 是当前元素自身时触发处理函数
.once
表示事件只会触发一次
.passive
表示处理事件函数中不会调用preventDefault函数
2.4.4 按键修饰符
按键修饰符,当按下特定键盘键时接收事件。例如,通过将键修饰符 enter 设置为 @keyup 事件来接收用户按下 Enter 时触发的事件。在下面的代码中,当在屏幕上按下回车按钮时,会产生一个回车事件,该事件被@keyup.enter 事件接收并执行提交功能。@submit事件从submit函数接收事件,执行send函数,控制台显示"send"。
html
<script setup>
const send = (event) => {
alert('保存');
};
</script>
<template>
<h1>Vue 3 事件</h1>
<form @submit.prevent="send">
<button @keyup.enter="submit">保存</button>
</form>
</template>
其他事件
.enter
:只有在按下 Enter 键时才触发事件处理函数。
.tab
:只有在按下 Tab 键时才触发事件处理函数。
.delete
:只有在按下 Delete 或 Backspace 键时才触发事件处理函数。
.esc
:只有在按下 Esc 键时才触发事件处理函数。
.space
:只有在按下空格键时才触发事件处理函数。
.up
:只有在按下上箭头键时才触发事件处理函数。
.down
:只有在按下下箭头键时才触发事件处理函数。
.left
:只有在按下左箭头键时才触发事件处理函数。
.right
:只有在按下右箭头键时才触发事件处理函数。
2.5 响应性函数ref 与reactivity
vue3中的reactivity响应性是一种允许我们以声明式的方式去适应变化的编程范例。一种vue3中的mvvm模式,将脚本中变量数据与模型中的数据双向绑定,当数据模型发生变化,所有对应数据模型自动变化数据。大家看下面的一段代码功能,我们模仿mvvm写法来完成一个点击按钮会自动累加计数的小功能。
html
<script setup>
const count = 0;
</script>
<template>
<h1>Vue 3 count累加</h1>
<button type="button" @click="count++">count 是: {{ count }}</button>
</template>
当用户点击按钮的时候,计数变量中的数字什么变化都没有发生。到底除了什么问题呢?
计数数字不会增加,是因为定义的计数变量没有反应性(reactivity)。为了能够实现点击按钮来增加的计数的功能,我们需要使用 ref 函数或 reactivity 函数赋予变量 反应性(reactivity)。
设置 ref 函数
通过使用 ref 函数,将变量设置成反应性变量。
vue
<script setup>
import { ref } from 'vue';//从 vue 中引入 ref 函数
const count = ref(0);
</script>
从 vue 中引入 ref 函数,将ref 函数初始值设置为0,在将ref 函数与count 变量进行绑定。这个时候在点击计数按钮,count 变量就会增加点击次数。
注意:ref 函数中定义的反应变量 count实际上是一个对象,它不能被直接使用与访问到。它需要使用对象中的value 属性来访问与赋值。
html
<script setup>
import { ref } from 'vue';
const count = ref(0);//count是对象
console.log(count.value);
</script>
同时我们也可以在函数中使用count.value来完成,计数器累加功能。
html
<script setup>
import { ref } from 'vue';
const count = ref(0);
const addCount = () => {
//函数中使用累加功能
count.value++;
};
</script>
<template>
<h1>Vue 3 count累加</h1>
<button type="button" @click="addCount">count 是: {{ count }}</button>
</template>
很多人不喜欢在代码中使用import { ref } from 'vue';来进入 r e f 函数。我们可以在 ∗ ∗ v i t e . c o n f i g . j s ∗ ∗ 文件中添加 r e a c t i v i t y T r a n s f o r m : t r u e 插件的参数,就可以直接使用 ref函数。我们可以在**vite.config.js** 文件中添加 reactivityTransform: true 插件的参数,就可以直接使用 ref函数。我们可以在∗∗vite.config.js∗∗文件中添加reactivityTransform:true插件的参数,就可以直接使用ref函数。
javascript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue({
reactivityTransform: true
})]
})
reactive函数
在这里我们来使用第二个反应函数reactive,使用的时候需要从 vue 中导入函数。由于reactive函数(反应函数)将对象作为参数,因此要将计数器设置为对象的属性。
注意在 ref 函数中将boolean、string、object 作为参数,但是reactive函数中只能将 object 作为参数。ref 和 reactive 的不同之处在于如何设置初始值以及如何更新值。
html
<script setup>
import { reactive } from 'vue';
//在事件中与显示的时候需要使用state对象来操作。
const state = reactive({-------------
count: 0, |
}); |
</script> |
<template> |
<h1>Vue 3 count累加</h1> |
<button type="button" |
@click="state.count++"> <-|
count 是: {{ state.count }} <-|
</button>
</template>
累加函数的使用方式也是函数中调用state对象中的属性来完成的。
html
<script setup>
import { reactive } from 'vue';
const state = reactive({
count: 0,
});
const addCount = () => {
//mvvm反射对象累加
state.count++;
};
</script>
<template>
<h1>Vue 3 count累加</h1>
<button type="button" @click="addCount">
count 是: {{ state.count }}
</button>
</template>
ref 和 reactive 之间的区别
ref 和 reactive 函数之间最大的区别是 ref 在访问 script 标签内的值时使用值。虽然 reactive 只能处理对象,但 ref 可以设置原始值(字符串、布尔值等)以及对象。
2.6 输入表格v-model指令
我们在开发表单页面的时候,都会使用到input 元素来接受用户数据输入与输出。在Vue中表单开发中,为我们提供了一个v-model指令来与反应函数变量进行绑定,这样可以达到mvvm模式的效果。在组成输入表单input元素和textarea元素中输入的值,以及在select元素中选择的内容,它们都会立即反映在反应变量中。我们就可以将这些数据模型中的数据进行操作。v-model指令需要和发应变量ref 与reactivity函数联合在一起使用。
v-model使用的标签与组件
- input
- select
- textarea
- vue组件中
html
<script setup>
import { ref } from 'vue';
// message设置成反应变量
const message = ref('我是变量message');
const clicksave = () => {
alert(message.value);
};
</script>
<template>
<h1>Vue 3 MVVM</h1>
<p>{{ message }}</p>
// message绑定为mvvm数据
<input v-model="message" />
<div><button @click="clicksave">保存</button></div>
</template>
我们如何不用v-model指令来绑定,使用普通元素方法来进行数据绑定。
html
<script setup>
import { ref } from 'vue';
const message = ref('我是变量message');
const clicksave = () => {
alert(message.value);
};
</script>
<template>
<h1>Vue 3 MVVM</h1>
<p>{{ message }}</p>
<input :value="message" @input="message = $event.target.value" />
<div><button @click="clicksave">保存</button></div>
</template>
我们使用了input事件,每次从$event对象中获取input元素中的输入值传递给message变量。这样的使用效果与 v-model 指令一样。但是这样的写法更长更难,更不便于理解与操作。
reactive函数绑定方式
html
<script setup>
import { reactive } from 'vue';
const form = reactive({
message: '我是变量message',
});
const clicksave = () => {
alert(form.message);
};
</script>
<template>
<h1>Vue 3 MVVM</h1>
<p>{{ form.message }}</p>
<input v-model="form.message" />
<div><button @click="clicksave">保存</button></div>
</template>
修饰符Modifiers
设置v-model修饰符,可以改变v-model的行为方式。
三种修饰符
txt
lazy
trim
number
- lazy:当字符被输入到 input 元素中时,它们会立即反映在 reactive 变量中,如果添加 lazy 修饰符,更改将会在光标从 input 元素中移开时候才发生,而不是每次输入一个字符时 reactive 变量就发生变化。这是因为v-model内部使用了input事件,但是通过添加lazy改成了change事件。
html
<input v-model.lazy="reactive对象变量" />
- trim:如果input元素的开头或结尾有空格,想要自动去掉加上修饰符trim就可以自动去掉。字符之间的空格永远不会被删除。它与 JavaScript 中的 trim 函数功能相同。
html
<input v-model.trim="reactive对象变量" />
- number:获取为数字,设置修饰符number作为数字获取. 如果type设置为number,Vue会自动转为number,所以type为text时可以使用。
html
<input v-model.number="reactive对象变量" type="text" />
查看input获得到的表单数据类型类型。
javascript
const clicksave = () => {
alert(typeof form.message);
};
2.7 Computed 模板函数
Computed是一种模板函数,用于页面元素的动态生成。如果使用反应变量定义成 Computed 函数中的模板变量,当反应变量更新时,会根据更新内容自动执行刷新Computed 函数中定义定义内容。
html
<script setup>
import { reactive, computed } from 'vue';
const user = reactive({
name: 'zhtbs',
class: '一年一班',
age: '27',
});
const zht = computed(() => `名称:${user.name} 班级:${user.class} 年龄:${user.age}`);
</script>
<template>
<h1>Vue 3 computed</h1>
<h2>内容: {{ zht }}</h2>
</template>
使用computed 创建模板语法 名称:${user.name}
,将函数反应对象映射到模板中。在将computed 对象在模板中定义出来。
v-for 中使用Computed
v-for 和 v-if 指令可以在 Computed函数中混合使用,这样可以解决很多复杂业务情况。例如 在数据列表中判断显示管理员信息。
html
<script setup>
import { reactive, computed } from 'vue';
const users = [
{ id: 1, name: 'zht', email: 'zht114001@163.com', admin: true },
{ id: 2, name: 'kaimi', email: 'jane@163.com', admin: false },
{ id: 3, name: 'fun', email: 'fun@163.com', admin: false },
];
const adminUsers = computed(() => users.filter((user) => user.admin === true));
</script>
<template>
<h1>Vue 3 computed</h1>
<div v-for="user in adminUsers" :key="user.id">
<div>{{ user.id }} {{ user.name }} {{ user.email }}</div>
</div>
</template>
我们通过过滤函数中的条件表达式即可获得非管理员用户。
vue
const generalUsers = computed(() => users.filter((user) => user.admin === false));
Computed 与函数区别
Computed 属性中描述的内容也可以使用函数来描述,直接在函数名称加上 ()。但是,Computed属性和函数之间有很大的区别,Computed属性具有缓存功能。通过下面的例子我们看看 Computed 属性和函数保存缓存数据是什么样。
html
<script setup>
import { reactive, computed } from 'vue';
const user = reactive({
name: 'zhtbs',
class: '一年一班',
age: '27',
});
const zht = computed(() => `${Math.random()}名称:${user.name} 班级:${user.class} 年龄:${user.age}`);
const fullName = () => `${Math.random()} 名称:${user.name} 班级:${user.class} 年龄:${user.age}`;
</script>
<template>
<h1>Vue 3 computed</h1>
<div>{{zht}}</div>
<div>{{zht}}</div>
//函数不会保存缓存
<div>{{fullName()}}</div>
<div>{{fullName()}}</div>
<div>{{fullName()}}</div>
</template>
html
<input v-model="user.name" />
加入这个v-model可以看到与mvvm一样的效果。
Computed 二次传值
更新Computed 属性的值时需要使用到 .value属性,通过操作value属性来达到对属性值得操作。
html
<script setup>
import { reactive, computed } from 'vue';
const user = reactive({
name: 'zhtbs',
class: '一年一班',
age: '27',
});
const zht = computed({
get() {
return `名称:${user.name} 班级:${user.class} 年龄:${user.age}`;
},
set(newValue) {
const names = newValue.split(' ');
user.name = names[0];
user.class = names[names.length - 1];
},
});
const changeName = () => {
zht.value = 'zht 二年二';
};
</script>
<template>
<h1>Vue 3 computed</h1>
<div>{{zht}}</div>
<button @click="changeName">名字变化</button>
</template>
computed属性中get方法是访问和返回模板内容,它的处理的内容和前面对Computed操作是一样的。set 方法是接收新值 newValue 并将接收到的 newValue 进行二次加工处理。我们可以使用 Setter 更新 Computd 属性中的对象内容。
2.8 Watcher
通过使用Watcher,监控reactive与computed中的参数变化情况,在检测到变化时执行其他业务处理功能。它的功能就是监听reactive与computed中的参数变化情况。
watcher + ref
html
<script setup>
import { ref, watch } from 'vue';
const count = ref(0);
watch(count, (count) => {
alert('count:'+count);
});
</script>
<template>
<h1>Vue 3 Watcher监听</h1>
<button @click="count++">Count:{{ count }}</button>
</template>
当ref 对象count变量发生变化的时候,watch中就会监听到count变量变化,执行一次alert('count:'+count)。
使用watcher,不仅可以查看更改后的值,还可以查看更改前的值。更改后的值传递给第一个参数,更改前的值传递给第二个参数。
javascript
watch(count, (count, previousCount) => {
alert('count:'+count+" previousCount:"+previousCount);
});
watcher + reactive
html
<script setup>
import { reactive, watch } from 'vue';
const state = reactive({
count: 0,
});
//注意区别是监听函数
watch(() => state.count, (count, previousCount) => {
alert('count:'+count+" previousCount:"+previousCount);
});
</script>
<template>
<h1>Vue 3 Watcher监听</h1>
<button @click="state.count++">Count:{{ state.count }}</button>
</template>
reactive 与 ref 区别在于在watch中监听的是对象的函数,还是对象本身。