vue3学习-组件基础、深入组件
组件
基本概述
单独的
.vue
文件 单文件组件(SFC)(single file component)
使用子组件
- 导入,无需注册,直接使用
- 编译时,区分大小写
- 可使用
/>
关闭标签
传递 props
- 需要再组件上声明注册
defineProps
宏
<script setup> cosnt props = defineProps(['title'])props.title
defineProps
是一个仅<script setup>
中可用的编译宏命令,并不需要显式地导入。
组件可以有任意多的 props,默认情况下,所有 prop 都接受任意类型的值
监听事件
子组件通过$emit
方法,抛出一个事件
父组件通过v-on
监听子组件抛出的事件
difineEmits 宏
defineEmits 宏 声明需要抛出的事件
并且不需要导入
- 声明了一个组件可能触发的所有事件
- 可以对事件的参数进行验证。
- 可以让vue 避免将他们作为原生事件监听隐式地应用于子组件地更目录
其他
- 大小写区分:HTML 标签和属性名称是不分大小写的,所以浏览器会把任何大写的字符解释为小写。
- 闭合标签: Vue 的模板解析器支持任意标签使用
/>
作为标签关闭的标志 - 元素位置限制: ul、ol、table、select
深入组件
注册
全局注册
# app.component() 方法
参数1 组件名,参数2: 对象或组件
可以被链式调用
缺点
- 全局注册,但并没有被使用的组件无法在生产打包时被自动移除 (也叫“tree-shaking”)。
- 全局注册在大型项目中使项目的依赖关系变得不那么明确。和使用过多的全局变量一样,这可能会影响应用长期的可维护性。
局部注册
相比之下,局部注册的组件需要在使用它的父组件中显式导入,并且只能在该父组件中使用。它的优点是使组件之间的依赖关系更加明确,并且对 tree-shaking 更加友好。
组件名格式
使用 PascalCase (帕斯卡命名法) 的理由:
- PascalCase 时合法的 JavaScript 标识符
<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犯法
单向数据流
-
所有的 props 都遵循单向绑定原则
-
避免子组件意外修改父组件的状态,导致数据流将很容易变得混乱而难以理解。
更改对象 / 数组类型的 props
- JavaScript 的对象和数组是按引用传递
- 虽然子组件无法更改 props 绑定,但仍然可以更改对象或数组内部的值。
- 对 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类型转换
- 有一种边缘情况——只有当
Boolean
出现在String
之前时,Boolean
转换规则才适用:
<MyComponent disabled />// disabled 将被转换为 true
defineProps({disabled: [Number, Boolean]
})// disabled 将被解析为空字符串 (disabled="")
defineProps({disabled: [String, Boolean]
})
事件
tip: 事件声明时可选的,还是推荐你完整地声明所有要触发的事件
触发与监听事件
-
事件的名字也提供了自动的格式转换,camelCase形式命名事件
-
所有传入
$emit()
的额外参数都会被直接传向监听器。举例来说,$emit('foo', 1, 2, 3)
触发后,监听器函数将会收到这三个参数值。
$emit('incremnetClick',1,2,3,4)
声明触发的事件defineEmits()
通过
defineEmits()
宏来声明它要触发的事件
defineEmits(['inFocus', 'sumbit'])
function buttonClick() {emit('submit')
}
Emits验证
- 支持对象语法:对触发事件的参数进行验证
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
- 属性 和监听器 默认透传到子组件的根元素上。
- 如果子组件的根元素有点击事件,父组件也透传了点击事件,则,这个父级和子级的事件都会被触发
禁用 Attributes 继承
在子组件中配置i选项
<script setup> defineOptions({inheritAttrs: false})
场景:attribute需要应用在根节点以外的其他元素上。
这些透传进来的 attribute 可以在模板的表达式中直接用 $attrs访问
<span>Fallthrough attribute: {{ $attrs }}</span>
这个 $attrs
对象包含了除组件所声明的 props
和 emits
之外的所有其他 attribute,例如 class
,style
,v-on
监听器等等。
需要注意
- 透传 attributes 在 JavaScript 中保留了它们原始的大小写,所以像
foo-bar
这样的一个 attribute 需要通过$attrs['foo-bar']
来访问。 - 像
@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(提供)
- 接受两个参数:
- 第一个:注入名,可以是一个字符串或是一个
Symbol
。 - 第二个:提供的值,任意类型包括响应状态, ref
- 第一个:注入名,可以是一个字符串或是一个
- 一个组件可多次调用 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 和插槽传给内部组件,所以你可以使用这个异步的包装组件无缝地替换原始组件,同时实现延迟加载。
- 与普通组件一样,异步组件可以使用
app.component()
app.component('MyComponent', defineAsyncComponent(() =>import('./components/MyComponent.vue')
))
- 可以直接在父组件中直接定义它们
<script setup>
import { defineAsyncComponent } from 'vue'const AdminPage = defineAsyncComponent(() =>import('./components/AdminPageComponent.vue')
)
</script><template><AdminPage />
</template>
相关文章:
vue3学习-组件基础、深入组件
组件 基本概述 单独的 .vue文件 单文件组件(SFC)(single file component) 使用子组件 导入,无需注册,直接使用编译时,区分大小写可使用 />关闭标签 传递 props 需要再组件上声明注册 def…...

原型链污染分析
原型链污染问题 原型链原型的继承原型链污染 原型链 原型的继承 先创建一个对象,查看一下属性 const obj { prop1: 111, prop2: 222,} 这里的Object.prototype就是对象的原型。 原型里面有许多的属性,这里面的constructor是我们需要着重关注的。 除此…...
RF PCB的9条改进型建议
1.小功率的RF的PCB设计中,主要使用标准的FR4材料(绝缘特性好、材质均匀、介电常数ε=4,10%)。主要使用4层~6层板,在成本非常敏感的情况下可以使用厚度在1mm以下的双面板,要保证反面是一个完整的地层,同时由于双面板的厚度在1mm以上,使得地层和信号层之间的FR4介质较厚,…...

网络安全(黑客)自学就业
前段时间,遇到网友提问,说为什么我信息安全专业的找不到工作? 造成这个结果主要是有两大方面的原因。 第一个原因,求职者本身的学习背景问题。那这些问题就包括学历、学校学到的知识是否扎实,是否具备较强的攻防实战…...

uni-app选择器( uni-data-picker)选择任意级别
背景说明 uni-app 官方的插件市场有数据驱动选择器,可以用作多级分类的场景。引入插件后,发现做不到只选择年级,不选择班级(似乎,只能到最后子节点了)。 需求中,有可能选择的不是叶子。比如&a…...

网络入侵探测器Pi.Alert
什么是 Pi.Alert ? Pi.Alert 是 WIFI/LAN 入侵探测器。通过扫描连接到您的 WIFI/LAN 的设备,提醒您未知设备的连接。它还警告断开“始终连接”的设备。 Pi.Alert 使用了三种扫描方式 方式1:arp-scan。arp扫描系统实用程序用于使用 arp 帧搜索…...

Flask项目打包为exe(附带项目资源,静态文件)
1.在项目根目录创建my_app.spec文件,内容如下: # -*- mode: python ; coding: utf-8 -*-block_cipher Nonea Analysis([server.py], # flask入口pathex[],binaries[], datas[("E:/**/templates","/templates"),("E:/**/s…...

无代码开发(BIP旗舰版-YonBuilder)
目录 我的应用 新建领域 菜单管理 应用构建 新建应用 对象建模 新增业务对象 新增业务实体 页面建模 新增页面 编辑页面 发布管理 我的应用 角色管理 yonbuilder开发平台,提供标准服务和专业开发服务; 本篇文章只演示标准服务的可视化应用…...

誉天程序员-瀑布模型-敏捷开发模型-DevOps模型比较
文章目录 2. 项目开发-开发方式2.1. 瀑布开发模型2.2. 敏捷开发模型2.3. DevOps开发模型2.4. 区别 自增主键策略1、数据库支持主键自增自增和uuid方案优缺点 2. 项目开发-开发方式 由传统的瀑布开发模型、敏捷开发模型,一跃升级到DevOps开发运维一体化开发模型。 …...

flutter:占位视图(骨架屏、shimmer)
前言 有时候打开美团,在刚加载数据时会显示一个占位视图,如下: 那么这个是如何实现的呢?我们可以使用shimmer来开发该功能 实现 官方文档 https://pub-web.flutter-io.cn/packages/shimmer 安装 flutter pub add shimmer示例…...

【雕爷学编程】MicroPython动手做(30)——物联网之Blynk 4
知识点:什么是掌控板? 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通信,可作为物联网节点,实现物联网应用。同时掌控板上集成了OLED…...

python-网络爬虫.BS4
BS4 Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库, 它能够通过你喜欢的转换器实现惯用的文档导航、查找、修改文档的方 式。 Beautiful Soup 4 官方文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/ 帮助手册&…...
C# 开发规范
控件命名规则 控件名简写 控件名简写LabellblTextBoxtxtButtonbtnLinkButtonlnkbtnImageButtonimgbtnDropDownListddlListBoxlstDataGriddgDataListdlCheckBoxchkCheckBoxListchklsRadioButtonrdoRadioButtonListrdoltImageimgPanelpnlCalendecldAdRotatorarTabletblRequiredF…...

【uniapp 样式】使用setStorageSync存储历史搜索记录
<template><view><view class"zhuangbox u-flex"><u--inputplaceholder"请输入关键字搜索"border"surround"shapecircleprefixIcon"search"prefixIconStyle"font-size: 22px;color: #909399"v-model&q…...
git remote add origin详解
git remote add origin详解_笔记大全_设计学院 一、git remote add origin的基础 使用“git remote add origin”指令,可以轻松地将本地项目连接到远程Git仓库 二、git remote add origin的用法 “git remote add origin”指令可以使用以下语法: git…...

附录1-将uni-app运行到微信开发者工具
目录 1 在manifest.json写入AppID 2 配置微信开发者工具的安装路径 3 微信开发者工具的安全设置 4 运行 5 修改一些配置项 1 在manifest.json写入AppID 2 配置微信开发者工具的安装路径 如果你忘了安装在哪里了,可以右键快捷方式看一下属性 在运行设置…...

【LeetCode】根据二叉树创建字符串
根据二叉树创建字符串 题目描述算法分析编程代码 链接: 根据二叉树创建字符串 题目描述 算法分析 当单纯的按照前序遍历输出后,我们只要对()进行一些修改就好 编程代码 /*** Definition for a binary tree node.* struct TreeNode {* …...

【图论】强连通分量
一.定义 强连通分量(Strongly Connected Components,简称SCC)是图论中的一个概念,用于描述有向图中的一组顶点,其中任意两个顶点之间都存在一条有向路径。换句话说,对于图中的任意两个顶点u和v,…...
网络:VRP介绍
1. VRP 华为使用的通用路由平台,华为的交换机、防火墙、安全设备、无线和路由器的命令行几乎一样。 2. VRP分为用户视图、系统视图。 3. 用户视图 user view <Huawei>:其中<>代表的是用户视图,Huawei是设备的名称。命令比较少。…...

iOS - 解压ipa包中的Assert.car文件
项目在 Archive 打包后,生成ipa包 将 xxx.ipa文件修改为zip后缀即 xxx.zip ,然后再双击解压,会生成一个 Payload 文件夹,里面一个文件 如下图: 然后显示改文件的包内容: 解压 Assets.car 文件的方式&…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...

医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor
1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...