Vue 3指令与事件处理 vue指令的实现原理
bigegpt 2024-10-11 10:54 9 浏览
title: Vue 3指令与事件处理
date: 2024/5/25 18:53:37
updated: 2024/5/25 18:53:37
categories:
- 前端开发
tags:
- Vue3基础
- 指令详解
- 事件处理
- 高级事件
- 实战案例
- 最佳实践
- 性能优化
第1章 Vue 3基础
1.1 Vue 3简介
Vue 3 是一个由尤雨溪(尤大)领导的开源JavaScript框架,它专注于构建用户界面。相较于Vue 2,Vue 3在核心理念上保持一致,但对一些底层实现进行了重大优化,包括:
- SFC(Single File Component) : Vue 3继续支持SFC模式,将组件的模板、样式和逻辑集成在一个文件中。
- Composition API: 引入新的编程模型,强调组件内部状态的可组合性,而非依赖于props和data。
- TypeScript支持: 提供了更好的类型系统,方便开发者编写类型安全的代码。
- Performance: 通过移除一些不必要的依赖,提高了性能,特别是对于大型应用。
1.2 安装与配置
1.2.1 环境准备
- Node.js: Vue 3需要Node.js环境,建议使用最新版本。
- 使用npm或yarn: 作为包管理器,安装Vue CLI(命令行工具)。
1.2.2 Vue CLI安装
- 打开终端(或命令提示符):
npm install -g @vue/cli
- 或者使用yarn:
yarn global add @vue/cli
1.2.3 创建项目
- 创建一个新的Vue 3项目:
vue create my-project
- 进入项目目录:
cd my-project
1.2.4 配置基本文件
- 修改src/main.js,引入Vue实例并启动应用:
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
app.mount('#app');
1.3 模板语法
1.3.1 JSX-like模板 Vue 3的模板语法采用类似React的JSX语法,但更简洁。如创建一个Hello World组件:
<template>
<div>Hello, {{ name }}!</div>
</template>
<script>
export default {
data() {
return {
name: 'World',
};
},
};
</script>
- {{ }}用于插值表达式,{{{ }}}用于文本插值。
- <div>是标签,<template>用于包裹组件内容。
1.3.2 简化模板 Vue 3还支持更简洁的模板语法,如:
<template>
<div>Hello, {{ name }}!</div>
</template>
<script>
export default {
data() {
return { name: 'World' };
},
};
</script>
- 省略了<script>标签内的export default和data。
第2章 Vue 3指令
2.1 内置指令
Vue 3提供了多种内置指令,用于控制DOM的行为和渲染。以下是一些常用的内置指令: AD:漫画首页
2.1.1 v-bind
v-bind 指令用于动态地绑定一个或多个属性,或者一个组件 prop 到表达式。在Vue 3中,v-bind 可以简写为 :。
示例:
<template>
<img :src="imageSrc" alt="Image">
</template>
<script>
export default {
data() {
return {
imageSrc: 'https://example.com/image.jpg',
};
},
};
</script>
2.1.2 v-model
v-model 指令用于在表单控件或者组件上创建双向数据绑定。
示例:
<template>
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
</template>
<script>
export default {
data() {
return {
message: '',
};
},
};
</script>
2.1.3 v-on
v-on 指令用于监听DOM事件,并在触发时执行一些JavaScript代码。v-on 可以简写为 @。
示例:
<template>
<button @click="incrementCounter">Click me</button>
</template>
<script>
export default {
data() {
return {
counter: 0,
};
},
methods: {
incrementCounter() {
this.counter++;
},
},
};
</script>
2.1.4 v-show与v-if
v-show 和 v-if 指令用于条件性地渲染一块内容。v-show 是通过CSS控制元素的显示与隐藏,而 v-if 则是通过创建或销毁DOM元素来控制。
示例:
<template>
<p v-show="isVisible">This is shown by v-show</p>
<p v-if="isVisible">This is shown by v-if</p>
</template>
<script>
export default {
data() {
return {
isVisible: true,
};
},
};
</script>
2.1.5 v-for
v-for 指令用于基于源数据多次渲染元素或模板块。
示例:
<template>
<ul>
<li v-for="item in items" :key="item.id">
{{ item.text }}
</li>
</ul>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' },
],
};
},
};
</script>
2.1.6 v-text与v-html
v-text 指令用于更新元素的 textContent。v-html 指令用于更新元素的 innerHTML。
示例:
<template>
<p v-text="textContent"></p>
<p v-html="htmlContent"></p>
</template>
<script>
export default {
data() {
return {
textContent: 'This is text content',
htmlContent: '<span>This is HTML content</span>',
};
},
};
</script>
通过这些内置指令,Vue 3允许开发者以声明式的方式控制DOM,使得代码更加简洁和易于维护。
2.2 自定义指令
除了内置指令,Vue 3还允许开发者创建自定义指令。自定义指令可以用于执行更多复杂的DOM操作。
2.2.1 创建自定义指令
可以使用 directives 选项在组件中注册自定义指令。
示例:
export default {
directives: {
focus: {
// 指令的定义
mounted(el) {
el.focus();
},
},
},
};
2.2.2 钩子函数
自定义指令可以包含以下几个钩子函数:
- bind:只调用一次,指令第一次绑定到元素时调用。
- inserted:被绑定元素插入到父节点时调用(仅保证父节点存在,但不一定已被插入到文档中)。
- updated:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新。
- componentUpdated:所在组件的 VNode 及其子 VNode 全部更新后调用。
- unbind:只调用一次,指令与元素解绑时调用。
示例:
export default {
directives: {
focus: {
bind(el) {
console.log('focus bind');
},
inserted(el) {
console.log('focus inserted');
},
updated(el) {
console.log('focus updated');
},
componentUpdated(el) {
console.log('focus componentUpdated');
},
unbind(el) {
console.log('focus unbind');
},
},
},
};
2.2.3 指令参数与修饰符
自定义指令可以接受一个参数,该参数是一个字符串,表示指令的修饰符。修饰符是一个 prefiex,以 . 开头,用于指明指令应该以特殊方式绑定。
示例:
export default {
directives: {
focus: {
bind(el, binding) {
if (binding.arg === 'input') {
el.focus();
}
},
},
},
};
可以在使用自定义指令时,使用 v-bind 传递参数。
示例:
<template>
<input v-focus.input="">
</template>
通过自定义指令,开发者可以扩展 Vue 的功能,并在组件中实现更多复杂的DOM操作。
第3章 Vue 3事件处理
3.1 Vue 3事件处理
Vue 3的事件处理机制与Vue 2类似,但使用了更简洁的语法。Vue 3中不再直接支持v-on,而是使用@符号来绑定事件。
3.1.1 基本事件绑定
基础的事件绑定使用 @ 符号,后跟事件名称,再加事件处理函数。例如:
<button @click="handleClick">点击我</button>
对应的JavaScript部分:
export default {
methods: {
handleClick() {
console.log('Button clicked');
},
},
};
3.1.2 事件修饰符
Vue 3的事件修饰符与Vue 2兼容,包括:
- .prevent:阻止事件的默认行为(如阻止表单的默认提交)
- .stop:阻止事件的进一步传播(默认行为不会被阻止)
- .capture:在捕获阶段触发,从根元素开始向上
- .self:仅在事件源和触发元素相同时触发
- .passive:在触摸移动事件中,用于处理滚动,使事件在默认行为执行前触发,常用于阻止滚动
例如:
<button @click.prevent="handleClick">阻止默认</button>
3.1.3 按键修饰符
- .once:只触发一次,然后移除事件监听
- .key:用于键盘事件,指定一个键值(如 Enter、Esc)来监听
例如:
<input @keyup.enter="handleEnter" />
在这个例子中,当用户按下回车键时,handleEnter 方法会被调用。
3.2 事件处理函数
在Vue 3中,事件处理函数是响应用户交互的关键部分,它们可以以不同的形式存在,包括内联事件处理器、方法事件处理器以及结合计算属性和侦听器。
3.2.1 内联事件处理器
内联事件处理器是指直接在模板中定义的JavaScript表达式,它们通常用于简单的逻辑。例如:
<button @click="count++">增加计数</button>
在这个例子中,点击按钮会直接增加count的值。
3.2.2 方法事件处理器
方法事件处理器是指在Vue组件的methods选项中定义的函数,这些函数可以处理更复杂的逻辑。例如:
export default {
data() {
return {
count: 0,
};
},
methods: {
incrementCount() {
this.count++;
},
},
};
在模板中使用:
<button @click="incrementCount">增加计数</button>
3.2.3 计算属性与侦听器
计算属性和侦听器也可以用于事件处理,尤其是在需要根据数据变化来更新视图或执行某些操作时。
- 计算属性:计算属性是基于它们的依赖进行缓存的,只有当依赖变化时才会重新计算。例如:
export default {
data() {
return {
firstName: 'John',
lastName: 'Doe',
};
},
computed: {
fullName() {
return `${this.firstName} ${this.lastName}`;
},
},
};
在模板中使用计算属性:
<button @click="fullName = 'Jane Smith'">更改全名</button>
- 侦听器:侦听器用于观察和响应Vue实例上的数据变动。例如:
export default {
data() {
return {
message: 'Hello',
};
},
watch: {
message(newVal, oldVal) {
console.log(`Message changed from ${oldVal} to ${newVal}`);
},
},
};
在模板中触发侦听器:
<button @click="message = 'Hello, Vue 3'">更改消息</button>
通过这些不同类型的事件处理函数,Vue 3提供了灵活且强大的工具来处理用户交互和数据变化。
第4章高级事件处理
在Vue中,高级事件处理技术包括使用事件总线、自定义事件和事件委托,这些技术可以帮助开发者更有效地管理组件间的通信和事件处理。
4.1 事件总线
事件总线是一个中央集线器,用于在非父子关系的组件之间传递事件。在Vue 2中,通常使用一个空的Vue实例作为事件总线。但在Vue 3中,推荐使用mitt或tiny-emitter等第三方库,因为Vue 3移除了$on、$off和$once等实例方法。
使用事件总线的基本步骤如下:
- 创建事件总线:
import mitt from 'mitt';
export const emitter = mitt();
- 在发送组件中触发事件:
this.emitter.emit('eventName', data);
- 在接收组件中监听事件:
this.emitter.on('eventName', this.handleEvent);
4.2 自定义事件
自定义事件是Vue中组件间通信的另一种方式,特别是在父子组件之间。子组件可以使用$emit方法触发一个自定义事件,父组件则通过在子组件标签上使用v-on或@来监听这个事件。
示例:
子组件:
methods: {
handleClick() {
this.$emit('custom-event', '传递的数据');
}
}
父组件:
<child-component @custom-event="handleCustomEvent"></child-component>
4.3 事件委托
事件委托是一种优化事件处理的技术,它利用事件冒泡机制,将事件处理器添加到父元素上,而不是每个子元素上。这样可以减少内存消耗和提高性能,尤其是在有很多子元素需要监听相同事件的情况下。 AD:专业搜索引擎
在Vue中实现事件委托的示例:
<ul @click="handleClick">
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</ul>
methods: {
handleClick(event) {
const target = event.target;
if (target.tagName === 'LI') {
// 处理点击事件
}
}
}
在这个例子中,handleClick方法会监听<ul>元素上的点击事件,并通过检查事件目标来确定是否是<li>元素被点击。这样,无论有多少个<li>元素,都只需要一个事件处理器。
第5章实战案例
以下是一些Vue.js简单实战案例,涵盖了表单处理、列表渲染与过滤、动态组件与异步组件的应用。
5.1 表单处理
表单处理是前端应用中常见的需求,Vue提供了简洁的方法来处理表单输入。
<template>
<div>
<form @submit.prevent="submitForm">
<input v-model="form.name" placeholder="Name">
<input v-model="form.email" type="email" placeholder="Email">
<button type="submit">Submit</button>
</form>
</div>
</template>
<script>
export default {
data() {
return {
form: {
name: '',
email: ''
}
};
},
methods: {
submitForm() {
// 处理表单提交逻辑
console.log('Name:', this.form.name);
console.log('Email:', this.form.email);
}
}
};
</script>
5.2 列表渲染与过滤
列表渲染是Vue中的基础功能,结合过滤器可以实现复杂的数据展示。
<template>
<div>
<input v-model="search" placeholder="Search">
<ul>
<li v-for="item in filteredList" :key="item.id">
{{ item.name }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
search: '',
items: [
{ id: 1, name: 'Apple' },
{ id: 2, name: 'Banana' },
{ id: 3, name: 'Cherry' },
// 更多数据...
]
};
},
computed: {
filteredList() {
return this.items.filter(item => item.name.includes(this.search));
}
}
};
</script>
5.3 动态组件与异步组件
动态组件和异步组件可以提高应用的灵活性和性能。
<template>
<div>
<button @click="component = 'ChildA'">切换到ChildA</button>
<button @click="component = 'ChildB'">切换到ChildB</button>
<component :is="component"></component>
</div>
</template>
<script>
export default {
data() {
return {
component: 'ChildA'
};
},
components: {
ChildA: { template: '<div>This is ChildA</div>' },
ChildB: { template: '<div>This is ChildB</div>' }
}
};
</script>
异步组件的实现通常涉及到动态导入:
components: {
ChildA: () => import('./ChildA.vue'),
ChildB: () => import('./ChildB.vue')
}
这样,ChildA和ChildB组件会按需加载,从而提高应用的性能。
第6章最佳实践
在Vue.js开发中,遵循一些最佳实践可以提高应用的性能、代码的可维护性和可测试性。以下是关于性能优化、代码组织与重用、测试与调试的最佳实践。AD:首页 | 一个覆盖广泛主题工具的高效在线平台
6.1 性能优化
- 使用v-if替代v-show:在需要频繁切换显示状态时,使用v-if比v-show更高效。
- 合理使用计算属性:对于复杂的数据处理,使用计算属性可以减少重复计算,提高性能。
- 避免不必要的组件渲染:使用v-once指令可以渲染一次后不再更新,适用于静态内容。
- 异步组件和代码分割:使用异步组件和Webpack的代码分割功能,可以按需加载组件,减少初始加载时间。
- 使用keep-alive缓存组件:对于需要频繁切换但数据不变的组件,使用<keep-alive>可以避免重复渲染。
6.2 代码组织与重用
- 组件化开发:将UI拆分为可重用的组件,每个组件负责特定的功能。
- 遵循单一职责原则:每个组件或模块应只负责一个功能,提高代码的可维护性和可测试性。
- 使用Mixins或Composition API:对于组件间的共享逻辑,可以使用Mixins或Vue 3的Composition API。
- 模块化管理状态:使用Vuex或其他状态管理工具来管理应用的状态,确保状态的可预测性和可维护性。
- 代码风格一致:遵循统一的代码风格和命名规范,提高代码的可读性。
6.3 测试与调试
- 单元测试:为组件和关键逻辑编写单元测试,确保代码的正确性。可以使用Jest或Vue Test Utils等工具。
- 端到端测试:使用Cypress或Puppeteer等工具进行端到端测试,确保应用在真实环境中的表现符合预期。
- 使用Vue Devtools:利用Vue Devtools进行调试,可以直观地查看组件树、状态和事件。
- 日志和错误处理:在关键点添加日志输出,便于追踪问题。使用try-catch处理可能的错误,提高应用的健壮性。
- 持续集成:将测试集成到持续集成流程中,确保每次代码提交都经过自动化测试。
相关推荐
- 当Frida来“敲”门(frida是什么)
-
0x1渗透测试瓶颈目前,碰到越来越多的大客户都会将核心资产业务集中在统一的APP上,或者对自己比较重要的APP,如自己的主业务,办公APP进行加壳,流量加密,投入了很多精力在移动端的防护上。而现在挖...
- 服务端性能测试实战3-性能测试脚本开发
-
前言在前面的两篇文章中,我们分别介绍了性能测试的理论知识以及性能测试计划制定,本篇文章将重点介绍性能测试脚本开发。脚本开发将分为两个阶段:阶段一:了解各个接口的入参、出参,使用Python代码模拟前端...
- Springboot整合Apache Ftpserver拓展功能及业务讲解(三)
-
今日分享每天分享技术实战干货,技术在于积累和收藏,希望可以帮助到您,同时也希望获得您的支持和关注。架构开源地址:https://gitee.com/msxyspringboot整合Ftpserver参...
- Linux和Windows下:Python Crypto模块安装方式区别
-
一、Linux环境下:fromCrypto.SignatureimportPKCS1_v1_5如果导包报错:ImportError:Nomodulenamed'Crypt...
- Python 3 加密简介(python des加密解密)
-
Python3的标准库中是没多少用来解决加密的,不过却有用于处理哈希的库。在这里我们会对其进行一个简单的介绍,但重点会放在两个第三方的软件包:PyCrypto和cryptography上,我...
- 怎样从零开始编译一个魔兽世界开源服务端Windows
-
第二章:编译和安装我是艾西,上期我们讲述到编译一个魔兽世界开源服务端环境准备,那么今天跟大家聊聊怎么编译和安装我们直接进入正题(上一章没有看到的小伙伴可以点我主页查看)编译服务端:在D盘新建一个文件夹...
- 附1-Conda部署安装及基本使用(conda安装教程)
-
Windows环境安装安装介质下载下载地址:https://www.anaconda.com/products/individual安装Anaconda安装时,选择自定义安装,选择自定义安装路径:配置...
- 如何配置全世界最小的 MySQL 服务器
-
配置全世界最小的MySQL服务器——如何在一块IntelEdison为控制板上安装一个MySQL服务器。介绍在我最近的一篇博文中,物联网,消息以及MySQL,我展示了如果Partic...
- 如何使用Github Action来自动化编译PolarDB-PG数据库
-
随着PolarDB在国产数据库领域荣膺桂冠并持续获得广泛认可,越来越多的学生和技术爱好者开始关注并涉足这款由阿里巴巴集团倾力打造且性能卓越的关系型云原生数据库。有很多同学想要上手尝试,却卡在了编译数据...
- 面向NDK开发者的Android 7.0变更(ndk android.mk)
-
订阅Google官方微信公众号:谷歌开发者。与谷歌一起创造未来!受Android平台其他改进的影响,为了方便加载本机代码,AndroidM和N中的动态链接器对编写整洁且跨平台兼容的本机...
- 信创改造--人大金仓(Kingbase)数据库安装、备份恢复的问题纪要
-
问题一:在安装KingbaseES时,安装用户对于安装路径需有“读”、“写”、“执行”的权限。在Linux系统中,需要以非root用户执行安装程序,且该用户要有标准的home目录,您可...
- OpenSSH 安全漏洞,修补操作一手掌握
-
1.漏洞概述近日,国家信息安全漏洞库(CNNVD)收到关于OpenSSH安全漏洞(CNNVD-202407-017、CVE-2024-6387)情况的报送。攻击者可以利用该漏洞在无需认证的情况下,通...
- Linux:lsof命令详解(linux lsof命令详解)
-
介绍欢迎来到这篇博客。在这篇博客中,我们将学习Unix/Linux系统上的lsof命令行工具。命令行工具是您使用CLI(命令行界面)而不是GUI(图形用户界面)运行的程序或工具。lsoflsof代表&...
- 幻隐说固态第一期:固态硬盘接口类别
-
前排声明所有信息来源于网络收集,如有错误请评论区指出更正。废话不多说,目前固态硬盘接口按速度由慢到快分有这几类:SATA、mSATA、SATAExpress、PCI-E、m.2、u.2。下面我们来...
- 新品轰炸 影驰SSD多款产品登Computex
-
分享泡泡网SSD固态硬盘频道6月6日台北电脑展作为全球第二、亚洲最大的3C/IT产业链专业展,吸引了众多IT厂商和全球各地媒体的热烈关注,全球存储新势力—影驰,也积极参与其中,为广大玩家朋友带来了...
- 一周热门
- 最近发表
-
- 当Frida来“敲”门(frida是什么)
- 服务端性能测试实战3-性能测试脚本开发
- Springboot整合Apache Ftpserver拓展功能及业务讲解(三)
- Linux和Windows下:Python Crypto模块安装方式区别
- Python 3 加密简介(python des加密解密)
- 怎样从零开始编译一个魔兽世界开源服务端Windows
- 附1-Conda部署安装及基本使用(conda安装教程)
- 如何配置全世界最小的 MySQL 服务器
- 如何使用Github Action来自动化编译PolarDB-PG数据库
- 面向NDK开发者的Android 7.0变更(ndk android.mk)
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- resize函数 (64)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- mybatis大于等于 (64)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- linuxlink (65)
- pythonwget (67)
- androidinclude (65)
- libcrypto.so (74)
- logstashinput (65)
- hadoop端口 (65)
- vue阻止冒泡 (67)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)