Vue3 学习笔记(十三)Vue组件详解


1、组件(Component) 介绍


组件(Component)是 Vue.js 最强大的功能之一。

组件可以扩展 HTML 元素,封装可重用的代码,可以帮助你将用户界面拆分成独立和可复用的部分。

每个 Vue 组件都是一个独立的 Vue 实例,具有自己的模板、数据、方法和生命周期钩子,使得组件可以自包含地定义和管理自己的功能和样式。


在这里插入图片描述


2、定义一个组件


(1)、单文件组件

当使用构建步骤时,我们一般会将 Vue 组件定义在一个单独的 .vue 文件中,这被叫做单文件组件 (简称 SFC):

<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <button @click="count++">You clicked me {{ count }} times.</button>
</template>

(2)、Vue 特定选项 JavaScript 对象

不使用构建步骤(如 webpack 或 Vite)的情况下,使用 Vue 3 的组合式 API 定义一个 Vue 组件。这种定义方式通常用于直接在浏览器中通过 <script> 标签引入 Vue.js 库的场景:

import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    return { count }
  },
  template: `
    <button @click="count++">
      You clicked me {{ count }} times.
    </button>`
  // template: '#my-template-element'
} 

以下是代码的详细解释:

导入 ref 函数

import { ref } from 'vue';

这行代码从 Vue 库中导入了 ref 函数。ref 是一个用于创建响应式引用的函数,它接受一个初始值,并返回一个响应式的对象。


定义组件对象

export default {
  setup() {
    const count = ref(0);
    return { count };
  },
  template: `
    <button @click="count++">
      You clicked me {{ count }} times.
    </button>`
};

这是一个 Vue 组件的 JavaScript 对象定义。它使用了 Vue 3 推荐的组合式 API。

setup 函数

setup() {
  const count = ref(0);
  return { count };
}

setup 函数是组合式 API 的入口点。在这里,我们使用 ref 创建了一个名为 count 的响应式引用,并将其初始值设置为 0setup 函数返回一个对象,其中包含了我们想要在模板中使用的响应式数据。在这个例子中,我们返回了 count


模板

template: `
  <button @click="count++">
    You clicked me {{ count }} times.
  </button>`

组件的 template 属性定义了组件的 HTML 模板。在这个模板中,我们有一个 <button> 元素,当它被点击时,会触发 count++ 操作。这表示 count 的值将增加 1。模板中的 {{ count }} 是一个插值表达式,它将显示 count 的当前值。


内联模板的注释

// 也可以针对一个 DOM 内联模板:
// template: '#my-template-element'

这一行被注释掉了,但它说明了另一种定义模板的方法。你可以通过指定一个已经在 DOM 中存在的元素的 ID 来使用内联模板。


3、使用组件


要使用一个子组件,我们需要在父组件中导入它。假设我们把计数器组件放在了一个叫做 ButtonCounter.vue 的文件中,这个组件将会以默认导出的形式被暴露给外部。

ButtonCounter.vue 组件内容如下:

在这里插入图片描述


使用方法如下:

<script setup>
import ButtonCounter from './ButtonCounter.vue'
</script>

<template>
	<h1>Here are many child components!</h1>
	<ButtonCounter />
	<ButtonCounter />
	<ButtonCounter />
</template>



效果如下:
在这里插入图片描述


  • 通过 <script setup>,导入的组件都在模板中直接可用。

  • 组件可以被重用任意多次

  • 每当你使用一个组件,就创建了一个新的实例

  • 在单文件组件中,推荐为子组件使用 PascalCase 的标签名,以此来和原生的 HTML 元素作区分。虽然原生 HTML 标签名是不区分大小写的,但 Vue 单文件组件是可以在编译中区分大小写的。


4、子组件与父组件通讯 props


(1) 、defineProps()

在 Vue.js 中,props 是一种机制,允许父组件向子组件传递数据。props 是子组件声明的可接收的属性,这些属性由父组件提供,子组件可以通过 props 访问这些传递过来的值。

  • defineProps<script setup> 中的一个宏,用于定义组件的 props。它接受一个字符串数组,数组中的每个字符串都是一个 prop 的名称。

子组件中 使用 defineProps 声明 props 属性:

<script setup>
import { ref } from 'vue'

const count = ref(0)

defineProps(['message'])

</script>

<template>

  <div>
    <p>{{ message }}</p>
  </div>

</template>

在这个子组件中,我们使用 defineProps 函数来声明 props。这个函数是 <script setup> 语法的一部分,用于定义组件的 props

父组件中 传参:

<script setup>
import ButtonCounter from './ButtonCounter.vue'

import { ref } from 'vue';

const parentMessage = ref('Hello from parent!');
</script>

<template>

	 <ButtonCounter :message="parentMessage" />
</template>

在这个父组件中,我们导入了子组件,并使用 ref 函数创建了一个响应式的 parentMessage 变量。然后,我们通过 : 前缀将 parentMessage 作为 prop 传递给子组件。


效果如下:

在这里插入图片描述


(2) 、defineEmits()

在 Vue 3 中,defineEmits 是一个用于在组件的 setup 函数中定义 emits 选项的宏。它允许你指定可以从组件触发的事件及其相应的参数。

定义 emits 选项: 在 <script setup> 中,使用 defineEmits 来定义组件可以触发的事件。


<!-- ChildComponent.vue -->
<script setup>
import { defineEmits } from 'vue';

// 定义组件可以触发的事件
const emit = defineEmits(['custom-event']);

function handleClick() {
  emit('custom-event', { key: 'abc',value:'325r35' });
}

</script>

<template>
  <button @click="handleClick">
    Click me to trigger custom event
  </button>
</template>


父组件中处理子组件事件:

<!-- ParentComponent.vue -->
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';


const eventPayload = ref(null);

// 定义处理子组件事件的方法
function handleCustomEvent(payload) {
  eventPayload.value = payload;
}

</script>

<template>
  <div>
    <ChildComponent
      @custom-event="handleCustomEvent"
    />
    <p>Last event payload: {{ eventPayload }}</p>
  </div>
</template>


实现效果如下,当点击按钮时,触发事件:

在这里插入图片描述


注意事项

  • defineEmits 只能在 <script setup> 中使用。
  • 定义的事件名应与模板中使用的 v-on@ 指令的事件名一致。
  • 使用 defineEmits 定义的事件可以在模板中通过 v-on@ 指令监听,并在父组件中处理。

(3)、defineModel()

这个宏可以用来声明一个双向绑定 prop,通过父组件的 v-model 来使用。

在底层,这个宏声明了一个 model prop 和一个相应的值更新事件。

  • 如果第一个参数是一个字符串字面量,它将被用作 prop 名称

  • 否则,prop 名称将默认为 "modelValue"


在这两种情况下,都可以再传递一个额外的对象,它可以包含 prop 的选项和 model ref 的值转换选项。

以下是使用 defineModel 演示子组件和父组件的使用示例:

首先,创建一个子组件 ChildComponent

<script setup>

const msg = defineModel('msg', { type: String, default: ''});
const score = defineModel('score', { type: Number, default: 0 });


/**
 * 更新score(同步更新父元素中的数据)
 */
const onClick = () => {
  score.value +=1;
};


</script>


<template>
  <div style="margin: 10px;padding: 8px;background-color: azure;">
    <span>子组件</span>
    <div>
      <input v-model="msg"  />
    </div>
    <span>dubble score: {{score * 2}}</span>
    <br />
    <button @click="onClick">score + 1</button>
  </div>
</template>

这里使用了 defineModel 宏来定义两个模型,msgscore。这些模型在内部创建了对应的 propemit 事件,用于实现双向绑定。msg 是一个字符串类型的 prop,默认值为空字符串,score 是一个数字类型的 prop,默认值为 0。

  • defineModel 是 Vue 3 中的一个 API,用于在 <script setup> 中定义具有双向绑定能力的 props
  • v-model 指令用于创建表单输入元素和应用状态之间的双向绑定。
  • @click 指令用于监听点击事件,并在事件发生时执行指定的函数。

然后,创建一个父组件:

<script setup>
import ChildComponent from './ChildComponent.vue';
import { ref } from 'vue';

const msg = ref('test');
const score = ref(1);

</script>

<template>
  <div style="border: 1px solid goldenrod">
    <span>父组件</span>
    <h1>{{ msg }}</h1>
    <h2>origin-score: {{score}}</h2>
  </div>
  
  <ChildComponent 
    v-model:msg="msg" 
    v-model:score="score"
  />
</template>

  • v-model:msgv-model:scorev-model 指令的自定义版本,用于创建子组件的 msgscore 属性与父组件的 msgscore 数据的双向绑定。这意味着当子组件更改这些值时,父组件的相应数据也会更新,反之亦然。
  • 这种双向绑定是通过子组件内部使用 defineModeldefinePropsemit 实现的。子组件需要触发相应的更新事件(如 update:msgupdate:score),以便父组件可以响应这些变化。
  • 由于 <script setup> 语法的简洁性,父组件中不需要 export default,也不需要显式定义 setup 函数。

实现效果如下:

当在子组件中输入 或者点击按钮事件,父组件都会同步更新。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

快速入门kotlin编程(精简但全面版)

注&#xff1a;本文章为个人学习记录&#xff0c;如有错误&#xff0c;欢迎留言指正。 目录 1. 变量 1.1 变量声明 1.2 数据类型 2. 函数 3. 判断语句 3.1 if 3.2 when语句 4. 循环语句 4.1 while 4.2 for-in 5. 类和对象 5.1 类的创建和对象的初始化 5.2 继承 5…

性能之光 年度电竞性能旗舰iQOO 13发布

2024年10月30日&#xff0c;被定义为“性能之光”的年度电竞性能旗舰——iQOO 13正式发布&#xff0c;售价3999元起。iQOO 13作为iQOO 品牌在性能上的又一次深入探索&#xff0c;它像是一束光&#xff0c;引领行业不断拉高性能上限&#xff0c;让用户看到更多的可能性。 iQOO …

ubuntu内核更新导致显卡驱动掉的解决办法

方法1&#xff0c;DKMS指定内核版本 用第一个就行 1&#xff0c;借鉴别人博客解决方法 2&#xff0c;借鉴别人博客解决方法 方法2&#xff0c;删除多于内核的方法 系统版本&#xff1a;ubuntu20.24 这个方法是下下策&#xff0c;如果重装驱动还是不行&#xff0c;就删内核在…

端到端拥塞控制的公平性和稳定性

昨天早上环城河跑步时的两个思考&#xff0c;发了朋友圈&#xff0c;简单总结成文。 拥塞控制算法公平性度量要重新评估&#xff01;仅以带宽公平性做论断是过时且自私的&#xff0c;在全局视角&#xff0c;平衡和稳定一定以某种表现为乘积 “矩” 来保证&#xff0c;比如力矩…

Vue 组件生命周期(四)

Vue 组件生命周期 Vue3 的组件生命周期可以概括为四个阶段&#xff1a;创建、挂载、更新、销毁。每个阶段都包含了一组钩子函数&#xff0c;用于在不同阶段执行特定的操作。 生命周期各阶段对应以下 Hooks 函数&#xff1a; 一、创建阶段 setup() Vue3 引入的新生命周期函数&am…

idea main 不是模块 导致找不到或无法加载主类

问题 导入一个新项目&#xff0c;然后执行启动类&#xff0c;直接报错&#xff1a; 找不到或无法加载主类。 把编译的删除了&#xff0c;重新处理&#xff0c;也不行。 看了下main和test不是模块 正常的是&#xff1a; 处理&#xff1a; 把项目的 .gradle 和 .idae 目录删了&am…

推荐一款优秀的pdf编辑器:Ashampoo PDF Pro

Ashampoo PDF Pro是管理和编辑 PDF 文档的完整解决方案。程序拥有您创建、转换、编辑和保护文档所需的一切功能。根据需要可以创建特定大小的文档&#xff0c;跨设备可读&#xff0c;还可以保护文件。现在您还能像编辑Word文档一样编辑PDF! 软件特点 轻松处理文字 如 Microso…

在manjaro 2024里使用yay命令安装ROS2

不建议这么安装&#xff0c;研究了两天以失败告终。要不就手动编译吧。。。&#xff08;在系统环境良好的情况下&#xff0c;最好是刚装完系统就装ROS&#xff09;真的太多不适配了&#xff0c;旧有的很多yay包都会遇到一些奇怪的问题&#xff1a; 0.一开始就会遇到网络卡住的…

平台化运营公司如何在创业市场招商

在当今商业环境中&#xff0c;平台化运营的公司正成为推动经济发展的重要力量。对于这类公司而言&#xff0c;在创业市场招商意义重大。 平台化运营公司具有独特特点&#xff1a;通过搭建开放共享平台连接供需双方&#xff0c;实现资源优化配置与价值创造。比如电子商务平台、社…

mybatis数据映射(记录踩坑点)

刚开始&#xff0c;userInfo里面的id我默认以为是User表的id&#xff0c;但是后面稍微看了一下返回的数据&#xff0c;userId跟replyId一致&#xff0c;我就知道userInfo里的id指的是Reply的id&#xff08;应该是命名冲突&#xff0c;先查Reply有没有id&#xff0c;没有&#x…

OpenCV基本操作(python开发)——(7)实现图像校正

OpenCV基本操作&#xff08;python开发&#xff09;——&#xff08;1&#xff09; 读取图像、保存图像 OpenCV基本操作&#xff08;python开发&#xff09;——&#xff08;2&#xff09;图像色彩操作 OpenCV基本操作&#xff08;python开发&#xff09;——&#xff08;3&…

【工具使用】VSCode如何将本地项目关联到远程的仓库 (vscode本地新项目与远程仓库建立链接)

在日常练习的项目中&#xff0c;我每次都在vscdoe编写前台代码&#xff0c;但是对于编写的代码&#xff0c;如何将本地项目关联到远程的仓库&#xff1b;这里做一下记录 文章目录 1、Gitee 新建远程仓库2、将本地的项目和远程仓库进行关联**3、将本地修改的代码推送到远程通过命…

语言≠思维,大模型学不了推理:一篇Nature让AI社区炸锅了

转自&#xff1a;机器之心 大语言模型&#xff08;LLM&#xff09;为什么空间智能不足&#xff0c;GPT-4 为什么用语言以外的数据训练&#xff0c;就能变得更聪明&#xff1f;现在这些问题有 「标准答案」了。 近日&#xff0c;一篇麻省理工学院&#xff08;MIT&#xff09;等…

技术星河中的璀璨灯塔 —— 青云交的非凡成长之路

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

高空作业未系安全带监测系统 安全带穿戴识别预警系统

在各类高空作业场景中&#xff0c;安全带是保障作业人员生命安全的关键防线。然而&#xff0c;由于人为疏忽或其他原因&#xff0c;作业人员未正确系挂安全带的情况时有发生&#xff0c;这给高空作业带来了巨大的安全隐患。为有效解决这一问题&#xff0c;高空作业未系安全带监…

移远通信闪耀2024香港秋灯展,以丰富的Matter产品及方案推动智能家居产业发展

10月27-30日&#xff0c;2024香港国际秋季灯饰展在香港会议展览中心盛大开展。 作为全球领先的物联网整体解决方案供应商&#xff0c;移远通信再次亮相&#xff0c;并重点展示了旗下支持Matter协议以及亚马逊ACK ( Alexa Connect Kit ) SDK for Matter方案的Wi-Fi模组、低功耗蓝…

Java如何实现PDF转高质量图片

大家好&#xff0c;我是 V 哥。在Java中&#xff0c;将PDF文件转换为高质量的图片可以使用不同的库&#xff0c;其中最常用的库之一是 Apache PDFBox。通过该库&#xff0c;你可以读取PDF文件&#xff0c;并将每一页转换为图像文件。为了提高图像的质量&#xff0c;你可以指定分…

【力扣刷题实战】另一棵树的子树

大家好&#xff0c;我是小卡皮巴拉 文章目录 目录 力扣题目&#xff1a; 另一棵树的子树 题目描述 示例 1&#xff1a; 示例 2&#xff1a; 解题思路 问题理解 算法选择 具体思路 解题要点 完整代码&#xff08;C语言&#xff09; 兄弟们共勉 &#xff01;&#xf…

ubuntu 24 (wayland)如何实现无显示器远程桌面

ubuntu 24默认采用的是wayland而非x11&#xff0c;查过文档vnc对wayland的支持不是很好&#xff0c;折腾了好久&#xff0c;弄了一个如下的方案供参考&#xff1a; 硬件条件 需要一个显卡欺骗器或者可以接HDMI口作为视频信号源输出的设备。 将ubuntu的主机的HDMI输出接到该硬…

StructRAG简介

StructRAG是一种新型的框架&#xff0c;旨在提升大型语言模型&#xff08;LLMs&#xff09;在知识密集型推理任务中的性能。它通过推理时的混合信息结构化机制&#xff0c;根据任务需求以最合适的格式构建和利用结构化知识。 以下是StructRAG的核心组成部分和工作流程&#xff…