vue3学习-组件基础、深入组件

组件

基本概述

单独的 .vue文件 单文件组件(SFC)(single file component)

使用子组件
  1. 导入,无需注册,直接使用
  2. 编译时,区分大小写
  3. 可使用 />关闭标签
传递 props
  1. 需要再组件上声明注册 defineProps
<script setup> cosnt props = defineProps(['title'])props.title

defineProps 是一个仅 <script setup> 中可用的编译宏命令,并不需要显式地导入。
组件可以有任意多的 props,默认情况下,所有 prop 都接受任意类型的值

监听事件

子组件通过$emit方法,抛出一个事件

父组件通过v-on 监听子组件抛出的事件

difineEmits 宏

defineEmits 宏 声明需要抛出的事件
并且不需要导入

  • 声明了一个组件可能触发的所有事件
  • 可以对事件的参数进行验证。
  • 可以让vue 避免将他们作为原生事件监听隐式地应用于子组件地更目录
其他
  1. 大小写区分:HTML 标签和属性名称是不分大小写的,所以浏览器会把任何大写的字符解释为小写。
  2. 闭合标签: Vue 的模板解析器支持任意标签使用 /> 作为标签关闭的标志
  3. 元素位置限制: ul、ol、table、select

深入组件

注册

全局注册
# app.component() 方法

参数1 组件名,参数2: 对象或组件

可以被链式调用

缺点
  1. 全局注册,但并没有被使用的组件无法在生产打包时被自动移除 (也叫“tree-shaking”)。
  2. 全局注册在大型项目中使项目的依赖关系变得不那么明确。和使用过多的全局变量一样,这可能会影响应用长期的可维护性。
局部注册

相比之下,局部注册的组件需要在使用它的父组件中显式导入,并且只能在该父组件中使用。它的优点是使组件之间的依赖关系更加明确,并且对 tree-shaking 更加友好。

组件名格式

使用 PascalCase (帕斯卡命名法) 的理由:

  1. PascalCase 时合法的 JavaScript 标识符
  2. <PascalCase/>更显著的表名了这是vue组件

Vue 支持将模板中使用 kebab-case 的标签解析为使用 PascalCase 注册的组件。

props

声明 deineProps()

显式声明它所接受的 props,这样 Vue 才能知道外部传入的哪些是 props,哪些是透传 attribute

const props = deineProps(['foo'])
const props = defineProps({title: string,})

defineProps 无需引入,直接使用

definePorps使用形式:数组、对象

数组形式默认接受任何类型的值

默认prop都是可选的,未传的话默认值 undefined

Boolean类型未传值,默认转换为false

Prop 名字格式
  • camelCase 驼峰名字格式
  • 父组件向子组件传递值时,可使用 camelCase 和 camel-case犯法
单向数据流
  1. 所有的 props 都遵循单向绑定原则

  2. 避免子组件意外修改父组件的状态,导致数据流将很容易变得混乱而难以理解。

更改对象 / 数组类型的 props
  1. JavaScript 的对象和数组是按引用传递
  2. 虽然子组件无法更改 props 绑定,但仍然可以更改对象或数组内部的值。
  3. 对 Vue 来说,禁止这样的改动,虽然可能生效,但有很大的性能损耗,比较得不偿失。
prop 校验
defineProps({a: Number,//a:[String, Number]a: {type: String, reuqired: true, default: 100},a:{validator(value) {return ['success','warning', 'danger'].includs(value)}}
})

defineProps() 宏中的参数不可以访问 `` 中定义的其他变量,因为在编译时整个表达式都会被移到外部的函数中。

Boolean类型转换
  1. 有一种边缘情况——只有当 Boolean 出现在 String 之前时,Boolean 转换规则才适用:
<MyComponent disabled />// disabled 将被转换为 true
defineProps({disabled: [Number, Boolean]
})// disabled 将被解析为空字符串 (disabled="")
defineProps({disabled: [String, Boolean]
})

事件

tip: 事件声明时可选的,还是推荐你完整地声明所有要触发的事件

触发与监听事件
  1. 事件的名字也提供了自动的格式转换,camelCase形式命名事件

  2. 所有传入 $emit() 的额外参数都会被直接传向监听器。举例来说,$emit('foo', 1, 2, 3) 触发后,监听器函数将会收到这三个参数值。

$emit('incremnetClick',1,2,3,4)
声明触发的事件defineEmits()

通过 defineEmits() 宏来声明它要触发的事件

defineEmits(['inFocus', 'sumbit'])
function buttonClick() {emit('submit')
}
Emits验证
  1. 支持对象语法:对触发事件的参数进行验证
const emit = defineEmites({submit(payload){// 通过返回值为 `true` 还是为 `false` 来判断// 验证是否通过}
})

组件v-model

<Hello :modelValue = 'searchText' @update:modelValue='newvalue => searchText = newvalue'/>
内部方法一
<script setup>
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script><template><input:value="modelValue"@input="$emit('update:modelValue', $event.target.value)"/>
</template>

update:modelValue 分号之间没有空格

内部方法二

使用一个可写的,同时具有 getter 和 setter 的 computed 属性。

import { computed } from 'vue'
let props = defineProps(['modelValue'])
let emit = defineEmits(['update:modelValue'])let value = computed({get() {return props.modelValue},set(value) {emit('update:modelValue', value)}
})
<input v-model="value">
v-model参数

默认情况:v-model再组件上使用的时modelValue、update:modelValue

自定义

例如:v-mode:title=“text” ==== title、update:title

v-mode:title="text"
多个v-model 绑定
处理 v-model 修饰符

自定义修饰符

不带参的 v-model
<MyComponent v-model.aaa="myText" />
const props = defineProps({modelVlaue: Stirng,modelModifiers:{default: () => ({})}
})handleClick() {if(props.modelModifiers.aaa){}//判断是否有某个修饰符emit('update:modelValue', '值')
}
带参数 v-model
<MyComponent v-model:title.capitalize="myText">const props = defineProps(['title', 'titleModifiers'])
defineEmits(['update:title'])console.log(props.titleModifiers) // { capitalize: true }

透传 Attributes

指传递给组件,却没有被组件声明为props 或emits的 attributes

  1. 属性 和监听器 默认透传到子组件的根元素上。
  2. 如果子组件的根元素有点击事件,父组件也透传了点击事件,则,这个父级和子级的事件都会被触发

禁用 Attributes 继承

在子组件中配置i选项

<script setup> defineOptions({inheritAttrs: false})

场景:attribute需要应用在根节点以外的其他元素上。

这些透传进来的 attribute 可以在模板的表达式中直接用 $attrs访问

<span>Fallthrough attribute: {{ $attrs }}</span>

这个 $attrs 对象包含了除组件所声明的 propsemits 之外的所有其他 attribute,例如 classstylev-on 监听器等等

需要注意

  1. 透传 attributes 在 JavaScript 中保留了它们原始的大小写,所以像 foo-bar 这样的一个 attribute 需要通过 $attrs['foo-bar'] 来访问。
  2. @click 这样的一个 v-on 事件监听器将在此对象下被暴露为一个函数 $attrs.onClick
多根节点的 Attributes 继承

有着多个根节点的组件没有自动 attribute 透传行为

如果 $attrs 没有被显式绑定,将会抛出一个运行时警告。

在 JavaScript 中访问透传 Attributes
import { useAttrs } from 'vue'
const attrs = useAttrs()

注意:

虽然这里的 attrs 对象总是反映为最新的透传 attribute,但它并不是响应式的 (考虑到性能因素)。你不能通过侦听器去监听它的变化。

插槽Slots

具名插槽

子组件:

父组件:使用 v-slot=“header” 指令 或者简写为 #header

<template #header> #等价于 <template v-slot:header><h1>Here might be a page title</h1>
</template>
作用域插槽

场景:插槽中的内容需要用大父组件域内或子组件域内的数据。

<slot :text="greetingMessage" :count="1"></slot>
<aaa v-slot="slotProps">{{slotProps.text}}</aa>

子组件传入插槽的 props 作为了 v-slot 指令的值

v-slot=“{ text, count }”

具名作用域插槽
<slot name="header" :text="greetingMessage" :count="1"></slot>
<aaa v-slot:header="slotProps">{{slotProps.text}}</aa>

依赖注入

prop 逐级透传问题

实现跨父子孙组件传值

provide(提供)
  1. 接受两个参数:
    1. 第一个:注入名,可以是一个字符串或是一个 Symbol
    2. 第二个:提供的值,任意类型包括响应状态, ref
  2. 一个组件可多次调用 provide() 使用不同的注入名
应用层 Provide
app.provide('message', 'hello')

在应用级别提供的数据在该应用内的所有组件中都可以注入。

inject(注入)
import {reject} from 'vue'
// const props = defineProps()

如果提供的值是一个 ref,注入进来的会是该 ref 对象,而不会自动解包为其内部的值。这使得注入方组件能够通过 ref 对象保持了和供给方的响应性链接。

注入默认值
const value = inject('message', '这是默认值')

在一些场景中,默认值可能需要通过调用一个函数或初始化一个类来取得。为了避免在用不到默认值的情况下进行不必要的计算或产生副作用,我们可以使用工厂函数来创建默认值:

js

const value = inject('key', () => new ExpensiveClass(), true)

第三个参数表示默认值应该被当作一个工厂函数。

和响应式数据配合使用

建议尽可能将任何对响应式状态的变更都保持在供给方组件(父)中

import { provide, ref } from 'vue'
function updateLocation() { location.value = 'South Pole' }
provide('location', { location, updateLocation})const { location, updateLocation } = inject('location')
<button @click="updateLocation">{{ location }}</button>
使用 Symbol 作注入名

避免潜在的冲突

// keys.js
export const myInjectionKey = Symbol()// 在供给方组件中
import { provide } from 'vue'
import { myInjectionKey } from './keys.js'provide(myInjectionKey, { /*要提供的数据
*/ });// 注入方组件
import { inject } from 'vue'
import { myInjectionKey } from './keys.js'const injected = inject(myInjectionKey)

异步组件

基本用法

vue提供了 defineAsyncComponent 方法来实现此功能

import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent(() => {return new Promise((resolve, reject) => {resolve(/*获取到的组件*/)})
})
# 或者
import { defineAsyncComponent } from 'vue'const AsyncComp = defineAsyncComponent(() =>import('./components/MyComponent.vue')
)

AsyncComp 是一个外层包装过的组件,仅在页面需要它渲染时才会调用加载内部实际组件的函数。它会将接收到的 props 和插槽传给内部组件,所以你可以使用这个异步的包装组件无缝地替换原始组件,同时实现延迟加载。

  1. 与普通组件一样,异步组件可以使用 app.component()
app.component('MyComponent', defineAsyncComponent(() =>import('./components/MyComponent.vue')
))
  1. 可以直接在父组件中直接定义它们
<script setup>
import { defineAsyncComponent } from 'vue'const AdminPage = defineAsyncComponent(() =>import('./components/AdminPageComponent.vue')
)
</script><template><AdminPage />
</template>

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

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

相关文章

深度学习:BatchNorm、LayerNorm、InstanceNorm、GroupNorm和SwitchableNorm的理解

深度学习&#xff1a;BatchNorm、LayerNorm、InstanceNorm、GroupNorm和SwitchableNorm的理解 深度学习中的NormBatchNormLayerNormInstanceNormGroupNormSwitchableNorm 附录 深度学习中的Norm 在深度学习中会经常遇到BatchNorm、LayerNorm、InstanceNorm和GroupNorm&#xf…

振弦采集仪完整链条的岩土工程隧道安全监测

振弦采集仪完整链条的岩土工程隧道安全监测 隧道工程是一种特殊的地下工程&#xff0c;其建设过程及运行期间&#xff0c;都受到各种内外力的作用&#xff0c;如水压、地震、地质变形、交通荷载等&#xff0c;这些因素都会对隧道的安全性产生影响。因此&#xff0c;对隧道的安…

SpringBoot项目使用MyBatisX+Apifox IDEA 插件快速开发

今天跟大家介绍两个快速开发项目的插件。能大大提高开发效率。希望能帮助到大家。 1、MyBatisX 插件 MyBatis-Plus为我们提供了强大的mapper和service模板&#xff0c;能够大大的提高开发效率。但是在真正开发过程中&#xff0c;MyBatis-Plus并不能为我们解决所有问题&#xf…

“深入理解Spring Boot:快速构建微服务架构的利器“

标题&#xff1a;深入理解Spring Boot&#xff1a;快速构建微服务架构的利器 摘要&#xff1a;Spring Boot是一种基于Spring框架的开源项目&#xff0c;它通过自动化配置和约定优于配置的原则&#xff0c;使得开发者能够快速构建微服务架构。本文将深入介绍Spring Boot的特点和…

[React]useMemoizedFn和useCallback对比

useMemoizedFn文档地址&#xff1a;https://ahooks.js.org/zh-CN/hooks/use-memoized-fn hooks组件内什么时候会更新自定义函数 在 React 中&#xff0c;自定义的 Hooks 内部的函数在以下常见的几种情况下会被重新赋值&#xff0c;导致更新引用&#xff1a; 组件重新渲染&…

AR开发平台 | 探索AR技术在建筑设计中的创新应用与挑战

随着AR技术的不断发展和普及&#xff0c;越来越多的建筑师开始探索AR技术在建筑设计中的应用。AR(增强现实)技术可以通过将虚拟信息叠加到现实场景中&#xff0c;为设计师提供更加直观、真实的建筑可视化效果&#xff0c;同时也可以为用户带来更加沉浸式的体验。 AR开发平台广…

Docker Compose 安装与使用(常用指令)

一、简介 Docker Compose 是一个编排多容器分布式部署的工具&#xff0c;提供命令集管理容器化应用的完整开发周期&#xff0c;包括服务构建、启动和停止。使用步骤&#xff1a;1. 利用 Dockerfile 定义运行环境镜像 2. 使用 docker-compose.yml 家义组成应用的各服务 3. 运行 …

flink数据流 单(kafka)流根据id去重

方法1 不推荐 package com.yy.uniqimport org.apache.flink.configuration.{Configuration, RestOptions} import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment import org.apache.flink.table.api.bridge.scala.StreamTableEnvironmentimport java.time…

Makefile学习2

文章目录 Makefile学习2Makefile条件判断ifeq 关键字ifneq 关键字ifdef 关键字ifndef 关键字 Makefile函数用户自定义函数文本处理函数 Makefile 通配符 Makefile学习2 Makefile条件判断 使用条件判断&#xff0c;可以让make在编译程序时&#xff0c;根据不同的情况&#xff…

IO进程线程day5(2023.8.2)

一、Xmind整理&#xff1a; 父进程会拷贝文件描述符表给子进程&#xff1a; 二、课上练习&#xff1a; 练习1&#xff1a;①从终端获取一个文件的路径以及名字。②若该文件是目录文件&#xff0c;则将该文件下的所有文件的属性显示到终端&#xff0c;类似ls -l该文件夹③若该文…

【Linux命令200例】touch用来创建新的文件或者修改已有文件

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;本文已收录于专栏&#xff1a;Linux命令大全。 &#x1f3c6;本专栏我们会通过具体的系统的命令讲解加上鲜…

代码随想录算法训练营day52

文章目录 Day52 最长递增子序列题目思路代码 最长连续递增序列题目思路代码 最长重复子数组题目思路代码 Day52 最长递增子序列 300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09; 题目 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 …

前端视频播放技术概览

转眼间&#xff0c;2023 年已进入下半场&#xff0c;在这样一个时间节点下&#xff0c;长视频平台如爱奇艺、优酷、腾讯视频等&#xff0c;以及短视频平台如抖音、快手等&#xff0c;对大家来说早已是司空见惯的事物。然而&#xff0c;在我们追剧、刷弹幕的时候&#xff0c;很少…

阿里云国际版在使用过程中应该注意什么呢?

为确保系统稳定性&#xff0c;用户不得进行以下操作。否则&#xff0c;阿里云可能无法解决由以下违规操作引起的问题&#xff1a; 1) Windows系统中的PV Drivers 程序不可删除 PV Drivers程序为服务器虚拟化驱动程序&#xff0c;请不要针对该程序进行任何操作&#xff0c;如果删…

电压放大器工作在什么状态

电压放大器是一种广泛应用于电子电路中的基本电路元件&#xff0c;其主要功能是将输入信号的电压放大到所需的输出电压幅值&#xff0c;并且保持信号的形状不变。在实际电路设计中&#xff0c;电压放大器的工作状态会受到多种因素的影响&#xff0c;比如输入信号的频率、放大倍…

iOS--runtime

什么是Runtime runtime是由C和C、汇编实现的一套API&#xff0c;为OC语言加入了面向对象、运行时的功能运行时&#xff08;runtime&#xff09;将数据类型的确定由编译时推迟到了运行时平时编写的OC代码&#xff0c;在程序运行过程中&#xff0c;最终会转换成runtime的C语言代…

爱尔眼科四川省区“同心博爱 光明工程”“西部健康公益行”炉霍站启动

8月1日&#xff0c;“同心博爱 光明工程”“西部健康公益行”炉霍站出征仪式在四川爱尔眼科医院隆重举行。 此次公益活动由民革成都市委会、中共锦江区委统战部指导&#xff0c;如意树爱心促进会主办&#xff0c;民革锦江区总支部、爱尔眼科四川省区支持&#xff0c;四川爱尔眼…

手把手教你从零开始搭建个人博客

随着技术的进步和用户需求的变化&#xff0c;个人博客的形式和内容一直在不停地演变。为了给读者提供更丰富、有趣的阅读体验&#xff0c;搭建个人博客的网站一直在寻找更好的优化方法。所以现在出现了一批功能更完善的个人博客搭建软件&#xff0c;今天looklook就以HelpLook为…

C++设计模式之适配器设计模式

文章目录 C适配器设计模式什么是适配器设计模式该模式有什么优缺点优点缺点 如何使用 C适配器设计模式 什么是适配器设计模式 适配器设计模式是一种行为型设计模式&#xff0c;它允许你将两个不兼容的接口组合在一起&#xff0c;使它们能够协同工作。 该模式有什么优缺点 优…

Boost开发指南-3.10singleton_pool

singleton_pool singleton_pool与 pool的接口完全一致&#xff0c;可以分配简单数据类型&#xff08;POD&#xff09;的内存指针&#xff0c;但它是一个单件。 singleton_pool位于名字空间boost&#xff0c;为了使用singleton_pool组件&#xff0c;需要包含头文件<boost/p…