vue3 教程(上)

news2024/11/23 22:44:13

学 vue3 通过官方文档更详细,不过阅读本博客,可以更容易理解,且帮你速成!

  • 官方文档(记得将API风格偏好切换为 组合式 否则你学的是vue2)
    https://cn.vuejs.org/guide/introduction.html
    在这里插入图片描述

学习前的准备

  1. 创建一个 vue3 项目,详见链接
    https://blog.csdn.net/weixin_41192489/article/details/128231728

  2. 开启 vue3 的实验性特征

    在项目的 vite.config.ts 中添加 reactivityTransform: true,

    在这里插入图片描述

  3. 添加 ts 对 vue3 实验性特征的支持

    在项目的 tsconfig.json 中添加 "types": ["vue/ref-macros"]

    在这里插入图片描述

改用 script setup

与 vue2 不同,vue3 的 js 代码写在 <script setup lang="ts"> 中,如

<script setup lang="ts">
let count = $ref(0);

function increment() {
  count++;
}
</script>

以下代码都在项目的 src\views\AboutView.vue 中测试,启动项目后,浏览器访问
http://127.0.0.1:5173/about 查看效果。

先将 AboutView.vue 初始化为

在这里插入代码片

定义响应式变量 $ref

vue2中写在 data(){} 函数中的变量,vue3中写法如下

// 定义响应式变量 count,初始值为 0
let count = $ref(0);

计算属性 computed

vue2中写在 computed 中的计算属性,vue3中写法如下

import { computed } from "vue";
let firstName = $ref("朝");
let lastName = $ref("阳");
// 当 firstName 或 lastName 变化时,会触发重新计算 fullName 
let fullName = computed(() => {
  return firstName + lastName;
});
  • 计算属性中不能直接使用 reverse() 和 sort() ,因为这两个方法将变更原始数组,正确的用法是在调用这些方法之前创建一个原数组的副本[...numbers]
return [...numbers].reverse()

实用技巧:动态绑定样式

<template>
  <div>
    <div :class="classObject">你好</div>
    <button @click="bolder">加粗</button>
    <button @click="markError">标红</button>
  </div>
</template>

<script setup lang="ts">
import { computed } from "vue";

let isBold = $ref(false);
let error = $ref(false);

let classObject = computed(() => ({
  bold: isBold,
  "text-danger": error,
}));

function bolder() {
  isBold = true;
}

function markError() {
  error = true;
}
</script>

<style scoped>
.text-danger {
  color: red;
}
.bold {
  font-weight: bold;
}
</style>

定义方法 function

vue2中写在 methods 中的方法,vue3中写法如下

// 定义方法 increment,每执行一次,count 会自增 1
function increment() {
  count++;
}

内联事件

逻辑极其简单的方法也可以直接写在元素上

<button @click="count++">增加1</button>

在方法后加 () 也会被视为内联事件

<button @click="increment()">增加1</button>

此时可以给方法添加参数

<button @click="increment('参数1',‘参数2’)">按指定参数增加</button>

内联事件访问原生 DOM 事件

需使用 $event

<button @click="submit('参数1', $event)">提交</button>

或者使用内联箭头函数

<button @click="(event) => submit('参数1', event)">提交</button>

方法事件

逻辑比较复杂时,则需给事件绑定方法

<button @click="show">展示</button>

此时方法的默认参数为原生 DOM 事件 event

// event 为原生 DOM 事件
function show(event: any) {
  // 通过 event 可以获取事件相关的各种信息
  console.log(event);
  if (event) {
    // 比如触发事件的标签名称
    console.log(event.target.tagName);
  }
}

事件修饰符

  • .stop 禁止事件冒泡
<a @click.stop="doThis"></a>

效果同 event.stopPropagation()

  • .prevent 禁止事件默认行为
    效果同 event.preventDefault()

使用范例:提交表单时不再重新加载页面

<form @submit.prevent="onSubmit"></form>
  • .capture 事件采用捕获模式
    指向内部元素的事件,在被内部元素处理前,先被外部处理
<div @click.capture="doThis">...</div>
  • .passive 用于改善移动端设备的滚屏性能
    一般用于触摸事件的监听器

范例:滚动事件的默认行为 (scrolling) 将立即发生而非等待 onScroll 完成,以防其中包含 event.preventDefault()

<div @scroll.passive="onScroll">...</div>

.passive 和 .prevent 不能同时使用,因为 .passive 已经向浏览器表明了你不想阻止事件的默认行为。如果同时使用,则 .prevent 会被忽略,并且浏览器会抛出警告。

还可以只使用修饰符,不绑定方法

<form @submit.prevent></form>

链式调用事件修饰符

<a @click.stop.prevent="show"></a>

但要注意调用顺序:
@click.prevent.self 阻止元素及其子元素的所有点击事件的默认行为
@click.self.prevent 只会阻止对元素本身的点击事件的默认行为。

常规按键修饰符

.按键名 即可实现指定按键触发事件

  • 按键名的格式为 kebab-case 形式,如 PageDown 键需使用 .page-down
<!-- 按回车键时调用  submit  -->
<input @keyup.enter="submit" />
<!-- 按 a 键时调用  submit  -->
<input @keyup.a="submit" />
<!-- 按 PageDown 键时调用 submit  -->
<input @keyup.page-down="submit" />

常用的按键有以下别名

  • .enter
  • .tab
  • .delete (捕获“Delete”和“Backspace”两个按键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

系统按键修饰符

  • .ctrl
  • .alt
  • .shift
  • .meta
    在 Mac 键盘上,meta 是 Command 键 (⌘)。
    在 Windows 键盘上,meta 键是 Windows 键 (⊞)。

系统按键修饰符与 keyup 事件一起使用时,该按键必须在事件发出时处于按下状态。如 keyup.ctrl 只会在你按住 ctrl 但松开另一个键时被触发,单独松开 ctrl 键将不会触发。

组合键的实现

<!-- Alt + Enter -->
<input @keyup.alt.enter="clear" />

<!-- Win + Enter  
 -->
<input @keyup.meta.enter="clear" />

<!-- Ctrl + 点击 -->
<div @click.ctrl="doSomething">Do something</div>

<!-- Ctrl + shift + a -->
<input @keyup.ctrl.shift.a="submit" />

.exact 修饰符

控制触发一个事件所需的确定组合

<!-- 当按下 Ctrl 时,即使同时按下 Alt 或 Shift 也会触发 -->
<button @click.ctrl="onClick">A</button>

<!-- 仅当按下 Ctrl 且未按任何其他键时才会触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 仅当没有按下任何系统按键时触发 -->
<button @click.exact="onClick">A</button>

鼠标按键修饰符

  • .left
  • .right
  • .middle
<!-- 在该div上点击鼠标左键时触发 -->
<div @mousedown.left="submit">

条件渲染 v-if v-show

多个元素需要使用 v-if 控制渲染时,可以添加 <template> 包裹

<template v-if="showDetail">
  <h1>标题</h1>
  <p>段落一</p>
  <p>段落二</p>
</template>

v-show 无法在 <template> 上使用

列表渲染 v-for

  • 既可以用 in ,也可以用 of
<div v-for="item of items"></div>
  • 可使用解构
const items = $ref([{ message: "1" }, { message: "2" }]);
<li v-for="({ message }, index) in items">{{ message }} {{ index }}</li>
  • 渲染对象
<li v-for="(value, key, index) in myObject">
  {{ index }}. {{ key }}: {{ value }}
</li>
  • 渲染整数
    效果为 1、2、3、…… n
<!-- n 的初值是从 1 开始而非 0 -->
<span v-for="n in 10">{{ n }}</span>
  • 多个元素需要使用 v-for 渲染时,可以添加 <template> 包裹
<ul>
  <template v-for="item in items">
    <li>{{ item.msg }}</li>
    <li class="divider" role="presentation"></li>
  </template>
</ul>

此时 key 也要写在 <template>

<template v-for="todo in todos" :key="todo.name">
  <li>{{ todo.name }}</li>
</template>
  • key 需为字符串或 number 类型,不要用对象作为 key

v-if 和 v-for 同时存在于一个元素上时

v-if 会首先被执行,但不推荐这种写法

<ul>
  <li
    v-for="user in users"
    v-if="user.isActive"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

应改用 <template> 包裹

<ul>
  <template v-for="user in users" :key="user.id">
    <li v-if="user.isActive">
      {{ user.name }}
    </li>
  </template>
</ul>

双向绑定 v-model

v-model 绑定的值通常是静态的字符串 (复选框中是布尔值),使用 v-bind 可以将选项值绑定为非字符串的数据类型。

<select v-model="selected">
  <!-- 内联对象字面量 -->
  <option :value="{ number: 123 }">123</option>
</select>

单选按钮 radio

<div>Picked: {{ picked }}</div>

<input type="radio" id="one" value="One" v-model="picked" />
<label for="one">One</label>

<input type="radio" id="two" value="Two" v-model="picked" />
<label for="two">Two</label>

复选框 checkbox

单个复选框

<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>

默认值为 true 和 false

通过以下方法可以自定义值

<input
  type="checkbox"
  v-model="toggle"
  true-value="yes"
  false-value="no" />

true-value 和 false-value 是 Vue 特有的属性,仅支持和 v-model 配套使用

多个复选框——值为数组

const checkedNames = $ref([])
<div>Checked names: {{ checkedNames }}</div>

<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>

<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>

<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>

自定义复选框

下拉单选 select

<div>Selected: {{ selected }}</div>

<select v-model="selected">
  <option disabled value="">Please select one</option>
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>

v-model 的初始值不匹配任何一个选择项时,会渲染成一个“未选择”的状态。在 iOS 上,这将导致用户无法选择第一项,因为 iOS 在这种情况下不会触发 change 事件。因此,建议提供一个空值的禁用选项,如上例所示。

.lazy 修饰符

默认情况下,v-model 会在每次 input 事件后更新数据
.lazy 修饰符可以改为在每次 change 事件后更新数据

<!-- 在 "change" 事件后同步更新而不是 "input" -->
<input v-model.lazy="msg" />

.number 修饰符

让用户输入自动转换为数字

<input v-model.number="age" />

若该值无法被 parseFloat() 处理,则返回原始值。
number 修饰符会在输入框有 type=“number” 时自动启用。

.trim 修饰符

自动去除用户输入内容中两端的空格

<input v-model.trim="msg" />

父子组件

子组件继承样式

vue2 中限定只能有一个根节点,父组件中给子组件添加的样式,都会渲染在子组件的根节点上,如:

<!-- 子组件 -->
<p class="child">你好</p>
<!-- 父组件使用子组件时,添加了新的样式 father -->
<MyComponent class="father" />

最终渲染的效果为:

<p class="child father">你好</p>

vue3 中支持多个根节点,所以需要通过 $attrs 指定具体哪些节点继承父组件添加的样式。

<!-- 子组件:在需要继承样式的元素上,添加  :class="$attrs.class" -->
<p :class="$attrs.class">你好</p>
<span>我是朝阳</span>
<!-- 父组件使用子组件时,添加了新的样式 father -->
<MyComponent class="father" />

最终渲染的效果为:

<p class="father">你好</p>
<span>我是朝阳</span>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/73985.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[synchronized ]关键字详解

目录 1.synchronized 特性 1.1互斥性 1.2内存刷新 1.3可重入 2.Java 标准库中的线程安全类 3.死锁问题 3.1 一个线程,一把锁 3.2 两个线程,两把锁 3.3 多个线程,多把锁 4.死锁的条件 1.synchronized 特性 1.1互斥性 synchronized 关键字会起到互斥效果,当某个线程执…

【C语言】字符串函数(一)

目录 一、strlen函数(计算字符串长度) 1、strlen函数的用途 2、strlen函数的使用 3、strlen函数的模拟实现 二、strcpy函数(字符串拷贝) 1、strcpy函数的用途 2、strcpy函数的使用 3、strcpy函数的模拟实现 三、strcat函数(字符串追加) 1、strcat函数的用途 2、strcat函数的使用…

【JavaSE】接口剩余内容

目录 1、接口使用实例 &#x1f4d5;逐步分析学生数组排序的写法 ✨思路&#xff1a; ✨代码实现 ✨弊端 &#x1f4d5;、改进 改进思路&#xff1a; 代码实现&#xff1a; 2、Cloneable接口和深拷贝 2.1、cloneable接口的作用 2.2、深拷贝和浅拷贝 2.2.1、浅拷贝 …

yum安装openldap2.4.44,并配置增量复制(Delta-syncrepl)环境

本文是在centos7环境下通过yum安装openldap2.4.44&#xff0c;并配置增量复制&#xff08;Delta-syncrepl&#xff09;环境 官网对于增量复制介绍&#xff1a;https://www.openldap.org/doc/admin24/replication.html#Delta-syncrepl%20replication Delta-syncrepl 是 syncrep…

ADI Blackfin DSP处理器-BF533的开发详解3:GPIO(含源代码)

我们从最基础的GPIO开始&#xff0c;先讲外设&#xff0c;这玩意不管是单片机&#xff0c;还是ARM&#xff0c;又或是FPGA&#xff0c;甚至SOC的芯片&#xff0c;都有GPIO&#xff0c;有共性&#xff0c;就好理解&#xff0c;让我们看看在ADI的DSP里头&#xff0c;GPIO是怎么一…

MySQL数据库学习(2)

一.MySQL语法书写规范&#xff1a; (1).SQL语句要以分号;结尾 在 RDBMS(关系型数据库)当中&#xff0c;SQL语句是逐条执行的&#xff0c;一条 SQL语句代表着数据库的一个操作。SQL语句是使用英文分号;结尾。 (2).SQL语句不区分大小写 SQL不区分关键字的大小写。例如&#xff0c…

CentOS7下mysql主从复制搭建

mysql安装 CentOS7安装MySql5.7完整教程_长头发的程序猿的博客-CSDN博客_centos7 mysql5.7安装 1、配置主机 1.1、修改my.cnf配置文件 vim /etc/my.cnf 最后一行添加&#xff1a; #主服务器唯一ID server-id1 #启用二进制日志 log-binmysql-bin #设置不要复制的数据库(可…

C++之虚函数

都说面向对象的三大特性是封装、继承、多态。C作为一门面向对象编程语言&#xff0c;肯定也是具备了面向对象的三大特性&#xff0c;那么在C中是如何实现多态的呢&#xff1f; 在C中是通过虚函数动态绑定的方式实现多态的。 虚函数与纯虚函数 首先我们来回顾一下虚函数&…

DAX:GROUPBY函数

DAX 中的 SUMMARIZE 函数功能强大&#xff0c;但同时也很难使用。 它可用于执行表之间的分组和连接&#xff0c;正如我们之前在分组数据一文中描述的那样。 不幸的是&#xff0c;它在计算聚合值时存在一些众所周知的性能问题。除了性能之外&#xff0c;SUMMARIZE 的计算限制是它…

ArrayList中的 subList 强转 ArrayList 导致异常

阿里《Java开发手册》上提过 [强制] ArrayList的sublist结果不可強转成ArrayList,否则会抛出ClassCastException异常&#xff0c;即java.util.RandomAccesSubList cannot be cast to java. util.ArrayList. 说明: subList 返回的是ArrayList 的内部类SubList, 并不是ArrayList …

一块RTX 3090加速训练YOLOv5s,时间减少11个小时,速度提升20%

作者&#xff5c;BBuf 很高兴为大家带来One-YOLOv5的最新进展&#xff0c;在《一个更快的YOLOv5问世&#xff0c;附送全面中文解析教程》发布后收到了很多算法工程师朋友的关注&#xff0c;十分感谢。 不过&#xff0c;可能你也在思考一个问题&#xff1a;虽然OneFlow的兼容性做…

SQL之substrate()函数用法

测试表字段查询如下&#xff1a; 测试在hive中截取前5位字符的第1种写法&#xff1a; 测试在hive中截取前5位字符的第2种写法&#xff1a; 测试在impala中截取前5位字符的第1种写法&#xff1a; 测试在impala中截取前5位字符的第2种写法&#xff1a; 结果&#xff1a; 1、在h…

带分数(蓝桥杯C/C++B组真题详解)

目录 题目 题目思路 题目代码 注解&#xff1a; 1.题目给定的判定条件为 2.关于next_permutation(start,end); 题目&#xff1a; 题目思路&#xff1a; 因为题目要求是满足在1到9中 不重复、不遗漏的所有满足条件的情况 所以我们可以通过全排列 把整数、分子、分母 …

B-树(B-Tree)与二叉搜索树(BST):讲讲数据库和文件系统背后的原理(读写比较大块数据的存储系统数据结构与算法原理)...

人类总喜欢发明创造一些新名词&#xff08;比如说&#xff0c;简写/缩写/简称什么的&#xff09;&#xff0c;并通过这些名词把人群分成了三六九等。弄到最后&#xff0c;把自己都绕晕了。你看&#xff0c;首先就是&#xff0c;B树&#xff0c;不要与Binary tree或Btree混淆。B…

有奖征文 | 当我们谈操作系统时,我们在谈什么?

OS&#xff0c;Operating System&#xff0c;操作系统&#xff0c;计算机中最基本也是最重要的基础性系统软件。1991 年&#xff0c;大二学生 Linus Torvalds 写出 Linux0.01&#xff0c;经过几十年的发展&#xff0c;以 Linux 为代表的服务器操作系统&#xff0c;成长为一个既…

lambda之Stream流式编程

lambda之Stream流式编程 一、什么是 Stream Stream中文称为 “流”&#xff0c;通过将集合转换为这么一种叫做“流”的元素序列&#xff0c;通过声明性方式&#xff0c;能够对集合中的每个元素进行一系列并行或串行的流水线操作。换句话说&#xff0c;你只需要告诉流你的要求…

led护眼台灯对眼睛好?过来人说说led护眼灯是否真的能护眼

众所周知&#xff0c;现在绝大部分光源都是使用led发光&#xff0c;无论是室内照明灯、室外装饰灯、气氛调节灯、工作学习护眼台灯等等&#xff0c;都是使用led灯珠&#xff0c;那么也就有人会问了&#xff1a;led灯真的对眼睛好吗&#xff1f;Led护眼台灯真的能护眼吗&#xf…

TH7-搜附近

TH7-搜附近说明1、探花1.1、查询推荐列表dubbo服务1.1.1、实体对象1.1.2、定义接口1.1.3、编写实现1.1.4、单元测试1.2、查询推荐列表APP接口实现1.2.1、TanHuaController1.2.2、TanHuaService1.2.3、测试1.3、喜欢的dubbo服务1.3.1、定义接口1.3.2、编写实现1.4、左滑右滑1.4.…

fofa搜索漏洞技巧

fofa搜索漏洞技巧整理,主要有以下十个方面:搜索HTTP响应头中含有"thinkphp"关键词的网站和IP;加上标题带有后台的;加上时间,现在新网站有thinkphp日志泄露的有很多; 搜索html正文中含有"管理后台"关键词的网站和IP body="管理后台"等。 …

Linux内核缓存

【推荐阅读】 轻松学会linux下查看内存频率,内核函数,cpu频率 纯干货&#xff0c;linux内存管理——内存管理架构&#xff08;建议收藏&#xff09; 一篇长文叙述Linux内核虚拟地址空间的基本概括 页缓存和块缓存 内核为块设备提供了两种通用的缓存方案&#xff1a; 页缓存&a…