当前位置: 首页 > news >正文

深入 Vue.js 组件开发:从基础到实践

深入 Vue.js 组件开发:从基础到实践

Vue.js 作为一款卓越的前端框架,其组件化开发模式为构建高效、可维护的用户界面提供了强大支持。在这篇博客中,我们将深入探讨 Vue.js 组件开发的各个方面,从基础概念到高级技巧,助你在 Vue.js 开发之路上稳步前行。

Vue.js 组件基础概念

什么是组件化开发

组件化开发是 Vue.js 的核心特性之一,它允许我们将复杂的用户界面拆分成一个个独立、可复用的小组件。每个组件都有自己的结构(HTML 模板)、样式(CSS)和逻辑(JavaScript),就像搭建积木一样,通过组合这些组件来构建整个应用。这样做的好处显而易见,不仅提高了代码的可维护性,当某个组件出现问题时,我们可以快速定位和修复,而不会影响到其他部分;还增强了代码的复用性,一个组件可以在多个地方重复使用,减少了代码冗余。

组件的构成

一个典型的 Vue.js 组件由三部分组成:

template:定义组件的 HTML 结构,描述了组件在页面上的呈现方式。例如:

<template><div><h2>{{ title }}</h2><p>{{ content }}</p></div></template>

这里的{{ title }}{{ content }}是插值表达式,用于动态显示数据。

2. script:负责处理组件的数据逻辑。在这个部分,我们可以定义数据、方法、生命周期钩子等。例如:

<script>export default {data() {return {title: '我的组件标题',content: '这是组件的内容'};},methods: {// 定义一个方法handleClick() {console.log('按钮被点击了');}}}</script>

style:设置组件的样式。为了避免样式冲突,推荐使用scoped属性,使样式仅作用于当前组件。例如:

<style scoped>div {border: 1px solid #ccc;padding: 10px;}</style>

组件的分类与注册

组件分类

Vue.js 组件分为全局组件和局部组件:

全局组件:在整个应用中都可以使用。全局组件注册后,任何 Vue 实例都能调用它。

局部组件:只能在特定的父组件中使用,其作用域仅限于父组件内部。

组件注册方式

全局注册:在main.js文件中进行全局组件的注册。首先导入组件,例如:

import MyComponent from './components/MyComponent.vue';

然后使用Vue.component方法进行注册,一次只能注册一个组件:

Vue.component('MyComponent', MyComponent);

这样,MyComponent组件就可以在整个应用的任何模板中使用了,如<MyComponent></MyComponent>

2. 局部注册:在需要使用组件的父组件中进行注册。首先在父组件的script部分导入子组件:

import MyChildComponent from './components/MyChildComponent.vue';

然后在父组件的components选项中进行注册:

export default {components: {MyChildComponent},// 其他选项...}

最后在父组件的template中使用子组件:

<template><div><MyChildComponent></MyChildComponent></div></template>

组件的使用步骤

创建组件构造器对象:虽然在现代 Vue 开发中,我们通常使用单文件组件(.vue文件)的方式,而不是显式创建组件构造器对象,但了解其原理有助于深入理解组件。在早期,我们可能会这样创建:

const MyComponent = Vue.extend({template: \`<div><h2>自定义组件</h2></div>\`});

注册组件:如前面所述,选择全局注册或局部注册方式将组件注册到应用中。

使用组件:在注册完成后,就可以在模板中像使用普通 HTML 标签一样使用组件了。例如,如果是全局注册的MyComponent,在任何 Vue 实例的模板中都可以这样使用:

<template><div><MyComponent></MyComponent></div></template>

如果是局部注册在某个父组件中,就在该父组件的模板中使用。

组件间通信

在实际应用中,组件之间往往需要进行数据传递和交互,这就涉及到组件间通信:

父子组件通信

父传子:父组件通过props向子组件传递数据。在子组件中定义props来接收父组件传递的值。例如,父组件模板:

<template><div><ChildComponent :message="parentMessage"></ChildComponent></div></template><script>import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},data() {return {parentMessage: '这是父组件传递给子组件的消息'};}}</script>

子组件中接收props

<script>export default {props: {message: String}}</script><template><div><p>{{ message }}</p></div></template>

子传父:子组件通过触发事件向父组件传递数据。子组件中使用this.$emit方法触发一个自定义事件,并传递数据。例如,子组件模板:

<template><button @click="sendDataToParent">点击传数据给父组件</button></template><script>export default {methods: {sendDataToParent() {const data = '这是子组件要传递给父组件的数据';this.$emit('childEvent', data);}}}</script>

父组件中监听子组件触发的事件:

<template><div><ChildComponent @childEvent="handleChildEvent"></ChildComponent></div></template><script>import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},methods: {handleChildEvent(data) {console.log('接收到子组件传递的数据:', data);}}}</script>

非父子组件通信:对于非父子关系的组件通信,可以使用事件总线或 Vuex 状态管理模式。

事件总线:创建一个空的 Vue 实例作为事件总线,在需要通信的组件中,通过事件总线来触发和监听事件。例如,在main.js中创建事件总线:

Vue.prototype.$eventBus = new Vue();

在组件 A 中触发事件:

this.$eventBus.$emit('sharedEvent', '这是组件A传递的数据');

在组件 B 中监听事件:

this.$eventBus.$on('sharedEvent', (data) => {console.log('组件B接收到数据:', data);});

Vuex:适用于大型应用,通过集中式存储管理应用的所有组件状态。Vuex 中的状态(state)可以被所有组件访问,组件通过提交(commit)mutation 来修改状态,通过分发(dispatch)action 来间接触发 mutation。具体使用方法涉及到 Vuex 的模块、state、mutation、action 等概念,这里不再赘述。

实战案例:创建一个简单的待办事项列表组件

为了更好地理解 Vue.js 组件开发,我们来创建一个简单的待办事项列表组件。

创建项目:使用 Vue CLI 创建一个新的 Vue 项目:

vue create todo - list - projectcd todo - list - projectnpm run serve

创建组件:在src/components目录下创建TodoList.vue组件。

template部分:

<template><div><h2>待办事项列表</h2><input v - model="newTodo" placeholder="添加新任务"><button @click="addTodo">添加</button><ul><li v - for="(todo, index) in todos" : key="index">{{ todo }}<button @click="deleteTodo(index)">删除</button></li></ul></div></template>

script部分:

<script>export default {data() {return {newTodo: '',todos: \[]};},methods: {addTodo() {if (this.newTodo.trim()!== '') {this.todos.push(this.newTodo);this.newTodo = '';}},deleteTodo(index) {this.todos.splice(index, 1);}}}</script>

style部分:

<style scoped>input {padding: 5px;margin - right: 5px;}button {padding: 5px 10px;}ul {list - style - type: none;padding: 0;}li {margin: 5px 0;}</style>

在 App.vue 中使用组件:在App.vue中导入并使用TodoList.vue组件。

<template><div id="app"><TodoList></TodoList></div></template><script>import TodoList from './components/TodoList.vue';export default {components: {TodoList}}</script><style>#app {font - family: Avenir, Helvetica, Arial, sans - serif;-webkit - font - smoothing: antialiased;-moz - osx - font - smoothing: grayscale;text - align: center;color: #2c3e50;margin - top: 60px;}</style>

这样,一个简单的待办事项列表组件就完成了,用户可以添加和删除待办事项。

总结

Vue.js 组件开发为前端开发带来了极大的便利,通过合理地拆分和组织组件,我们能够构建出高效、可维护的应用程序。从基础概念到组件注册、使用以及组件间通信,再到实际案例的实践,希望这篇博客能帮助你对 Vue.js 组件开发有更深入的理解和掌握。在实际项目中,不断实践和探索,你将发现 Vue.js 组件化开发的更多魅力和潜力。

相关文章:

深入 Vue.js 组件开发:从基础到实践

深入 Vue.js 组件开发&#xff1a;从基础到实践 Vue.js 作为一款卓越的前端框架&#xff0c;其组件化开发模式为构建高效、可维护的用户界面提供了强大支持。在这篇博客中&#xff0c;我们将深入探讨 Vue.js 组件开发的各个方面&#xff0c;从基础概念到高级技巧&#xff0c;助…...

maven导入spring框架

在eclipse导入maven项目&#xff0c; 在pom.xml文件中加入以下内容 junit junit 3.8.1 test org.springframework spring-core ${org.springframework.version} org.springframework spring-beans ${org.springframework.version} org.springframework spring-context ${org.s…...

数据守护者:备份文件的重要性与自动化实践策略

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业运营和个人生活中不可或缺的核心资源。无论是企业的财务报表、客户资料&#xff0c;还是个人的家庭照片、工作文档&#xff0c;这些数据都承载着巨大的价值。然而&#xff0c;数据丢失的风险无处不在&#xff0c;硬件故障…...

MyBatis @Param 注解详解:指定的参数找不到?

MyBatis Param 注解详解 1. Param 注解的作用 Param 注解用于显式指定方法参数的名称&#xff0c;让 MyBatis 在 SQL 映射文件&#xff08;XML&#xff09;或注解中通过该名称访问参数。 核心场景&#xff1a; 方法有多个参数时&#xff0c;避免参数名丢失或混淆。参数为简单…...

【项目日记(八)】内存回收与联调

前言 我们前面实现了三层缓存申请的过程&#xff0c;并完成了三层缓存申请过程的联调&#xff01;本期我们来介绍三层的缓存的回收机制以及三层整体联调释放的过程。 目录 前言 一、thread cache 回收内存 二、central cache 回收内存 • 如何确定一个对象对应的span • …...

性能测试监控工具jmeter+grafana

1、什么是性能测试监控体系&#xff1f; 为什么要有监控体系&#xff1f; 原因&#xff1a; 1、项目-日益复杂&#xff08;内部除了代码外&#xff0c;还有中间件&#xff0c;数据库&#xff09; 2、一个系统&#xff0c;背后可能有多个软/硬件组合支撑&#xff0c;影响性能的因…...

016.3月夏令营:数理类

016.3月夏令营&#xff1a;数理类&#xff1a; 中国人民大学统计学院&#xff1a; http://www.eeban.com/forum.php?modviewthread&tid386109 北京大学化学学院第一轮&#xff1a; http://www.eeban.com/forum.php?m ... 6026&extrapage%3D1 香港大学化学系夏令营&a…...

CS144 Lab Checkpoint 0: networking warm up

Set up GNU/Linux on your computer 我用的是Ubuntu&#xff0c;按照指导书上写的输入如下命令安装所需的软件包&#xff1a; sudo apt update && sudo apt install git cmake gdb build-essential clang \ clang-tidy clang-format gcc-doc pkg-config glibc-doc tc…...

靶场之路-VulnHub-DC-6 nmap提权、kali爆破、shell反连

靶场之路-VulnHub-DC-6 一、信息收集 1、扫描靶机ip 2、指纹扫描 这里扫的我有点懵&#xff0c;这里只有两个端口&#xff0c;感觉是要扫扫目录了 nmap -sS -sV 192.168.122.128 PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.4p1 Debian 10deb9u6 (protoc…...

给没有登录认证的web应用添加登录认证(openresty lua实现)

这阵子不是deepseek火么&#xff1f;我也折腾了下本地部署&#xff0c;ollama、vllm、llama.cpp都弄了下&#xff0c;webui也用了几个&#xff0c;发现nextjs-ollama-llm-ui小巧方便&#xff0c;挺适合个人使用的。如果放在网上供多人使用的话&#xff0c;得接入登录认证才好&a…...

3月5日作业

代码作业&#xff1a; #!/bin/bash# 清空目录函数 safe_clear_dir() {local dir"$1"local name"$2"if [ -d "$dir" ]; thenwhile true; doread -p "检测到 $name 目录已存在&#xff0c;请选择操作&#xff1a; 1) 清空目录内容 2) 保留目…...

【MySQL】增删改查

目录 一、新增&#xff08;Create&#xff09; 单行数据 全列插入 多行数据 指定列插入 插入时间 二、查询&#xff08;Retrieve&#xff09; 全列查询 指定列查询 查询字段为表达式 别名 去重&#xff1a;DISTINCT 排序&#xff1a;ORDER BY 条件查询&#xff1…...

【三维生成】StarGen:基于视频扩散模型的可扩展的时空自回归场景生成

标题&#xff1a;《StarGen: A Spatiotemporal Autoregression Framework with Video Diffusion Model for Scalable and Controllable Scene Generation》 项目&#xff1a;https://zju3dv.github.io/StarGen 来源&#xff1a;商汤科技、浙大CAD、Tetras.AI 文章目录 摘要一、…...

线反转法实现矩形键盘按键识别

由于行、列线为多键共用&#xff0c;各按键彼此将相互发 生影响&#xff0c;必须将行、列线信号配合起来并作适当的处 理&#xff0c;才能确定闭合键的位置。 线反转法 第1步&#xff1a;列线输出为全低电平&#xff0c;则行线中电平由高变低 的所在行为按键所在行。 第2步&…...

在 Element Plus 的 <el-select> 组件中,如果需要将 <el-option> 的默认值设置为 null。 用于枚举传值

文章目录 引言轻松实现 `<el-option>` 的默认值为 `null`I 实现方式监听清空事件 【推荐】使用 v-model 绑定 null添加一个值为 null 的选项处理 null 值的显示引言 背景:接口签名规则要求空串参与,空对象不参与签名计算 // 空字符串“” 参与签名组串,null不参与签…...

大白话面试中应对自我介绍

在面试中&#xff0c;自我介绍是开场的关键环节&#xff0c;它就像你递给面试官的一张“个人名片”&#xff0c;要让面试官快速了解你并对你产生兴趣。下面详细讲讲应对自我介绍的要点及回答范例。 一、自我介绍的时间把控 一般面试中的自我介绍控制在1 - 3分钟比较合适。时间…...

Pytorch构建LeNet进行MNIST识别 #自用

LeNet是一种经典的卷积神经网络&#xff08;CNN&#xff09;结构&#xff0c;由Yann LeCun等人在1998年提出&#xff0c;主要用于手写数字识别&#xff08;如MNIST数据集&#xff09;。作为最早的实用化卷积神经网络&#xff0c;LeNet为现代深度学习模型奠定了基础&#xff0c;…...

元宇宙崛起:区块链与金融科技共绘数字新世界

文章目录 一、引言二、元宇宙与区块链的深度融合三、区块链在元宇宙金融中的应用四、金融科技在元宇宙中的创新应用五、面临的挑战与机遇《区块链与金融科技》亮点内容简介获取方式 一、引言 随着科技的飞速发展&#xff0c;元宇宙概念逐渐走进人们的视野&#xff0c;成为数字…...

React Native 实现滑一点点内容区块指示器也滑一点点

效果图如上&#xff0c;内容滑一点点&#xff0c;指示器也按比例话一点点&#xff0c;列表宽度跟数据有关。 实现思路如下&#xff1a; 1.监听列表滑动事件&#xff0c;获取列表横向滑动距离&#xff0c;假设为A&#xff1b; 2.获取列表的宽度&#xff0c;及列表可滑动的宽度…...

怎么写C#命令行参数程序,及控制台带参数案例(程序完整源码)下载

C#命令行参数解析控制台带参数编写案例&#xff08;程序完整源码&#xff09;下载链接 https://download.csdn.net/download/luckyext/90434790 在CMD命令窗口&#xff0c;输入ping 、ipconfig等这样的命令&#xff0c;大家应该都知道&#xff0c;但很多同学可能不知道怎么写…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

Kafka主题运维全指南:从基础配置到故障处理

#作者&#xff1a;张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1&#xff1a;主题删除失败。常见错误2&#xff1a;__consumer_offsets占用太多的磁盘。 主题日常管理 …...

Ubuntu系统复制(U盘-电脑硬盘)

所需环境 电脑自带硬盘&#xff1a;1块 (1T) U盘1&#xff1a;Ubuntu系统引导盘&#xff08;用于“U盘2”复制到“电脑自带硬盘”&#xff09; U盘2&#xff1a;Ubuntu系统盘&#xff08;1T&#xff0c;用于被复制&#xff09; &#xff01;&#xff01;&#xff01;建议“电脑…...

JDK 17 序列化是怎么回事

如何序列化&#xff1f;其实很简单&#xff0c;就是根据每个类型&#xff0c;用工厂类调用。逐个完成。 没什么漂亮的代码&#xff0c;只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...