单向数据流

简介: 单向数据流

所有的 props 都遵循着单向绑定原则,props 因父组件的更新而变化,自然地将新的状态向下流往子组件,而不会逆向传递。这避免了子组件意外修改父组件的状态的情况,不然应用的数据流将很容易变得混乱而难以理解。

另外,每次父组件更新后,所有的子组件中的 props 都会被更新到最新值,这意味着你不应该在子组件中去更改一个 prop。若你这么做了,Vue 会在控制台上向你抛出警告:

const props = defineProps(['foo'])
// ❌ 警告!prop 是只读的!
props.foo = 'bar'

导致你想要更改一个 prop 的需求通常来源于以下两种场景:

当 prop 的校验失败后,Vue 会抛出一个控制台警告 (在开发模式下)。

如果使用了基于类型的 prop 声明 ,Vue 会尽最大努力在运行时按照 prop 的类型标注进行编译。举例来说,defineProps<{ msg: string }> 会被编译为 { msg: { type: String, required: true }}。

  1. prop 被用于传入初始值;而子组件想在之后将其作为一个局部数据属性。在这种情况下,最好是新定义一个局部数据属性,从 props 上获取初始值即可:
const props = defineProps(['initialCounter'])
// 计数器只是将 props.initialCounter 作为初始值
// 像下面这样做就使 prop 和后续更新无关了
const counter = ref(props.initialCounter)
  1. 需要对传入的 prop 值做进一步的转换。在这种情况中,最好是基于该 prop 值定义一个计算属性:
const props = defineProps(['size'])
// 该 prop 变更时计算属性也会自动更新
const normalizedSize = computed(() => props.size.trim().toLowerCase())
  1. 更改对象 / 数组类型的 props
    当对象或数组作为 props 被传入时,虽然子组件无法更改 props 绑定,但仍然可以更改对象或数组内部的值。这是因为 JavaScript 的对象和数组是按引用传递,而对 Vue 来说,禁止这样的改动,虽然可能生效,但有很大的性能损耗,比较得不偿失。
    这种更改的主要缺陷是它允许了子组件以某种不明显的方式影响父组件的状态,可能会使数据流在将来变得更难以理解。在最佳实践中,你应该尽可能避免这样的更改,除非父子组件在设计上本来就需要紧密耦合。在大多数场景下,子组件应该抛出一个事件来通知父组件做出改变。
  2. Prop 校验
    Vue 组件可以更细致地声明对传入的 props 的校验要求。比如我们上面已经看到过的类型声明,如果传入的值不满足类型要求,Vue 会在浏览器控制台中抛出警告来提醒使用者。这在开发给其他开发者使用的组件时非常有用。
    要声明对 props 的校验,你可以向 defineProps() 宏提供一个带有 props 校验选项的对象,例如:
defineProps({
  // 基础类型检查
  // (给出 `null` 和 `undefined` 值则会跳过任何类型检查)
  propA: Number,
  // 多种可能的类型
  propB: [String, Number],
  // 必传,且为 String 类型
  propC: {
    type: String,
    required: true
  },
  // Number 类型的默认值
  propD: {
    type: Number,
    default: 100
  },
  // 对象类型的默认值
  propE: {
    type: Object,
    // 对象或数组的默认值
    // 必须从一个工厂函数返回。
    // 该函数接收组件所接收到的原始 prop 作为参数。
    default(rawProps) {
      return { message: 'hello' }
    }
  },
  // 自定义类型校验函数
  // 在 3.4+ 中完整的 props 作为第二个参数传入
  propF: {
    validator(value, props) {
      // The value must match one of these strings
      return ['success', 'warning', 'danger'].includes(value)
    }
  },
  // 函数类型的默认值
  propG: {
    type: Function,
    // 不像对象或数组的默认,这不是一个
    // 工厂函数。这会是一个用来作为默认值的函数
    default() {
      return 'Default function'
    }
  }
})
  1. 一些补充细节:
  2. 所有 prop 默认都是可选的,除非声明了 required: true。
  3. 除 Boolean 外的未传递的可选 prop 将会有一个默认值 undefined。
  4. Boolean 类型的未传递 prop 将被转换为 false。这可以通过为它设置 default 来更改——例如:设置为 default: undefined 将与非布尔类型的 prop 的行为保持一致。
  5. 如果声明了 default 值,那么在 prop 的值被解析为 undefined 时,无论 prop 是未被传递还是显式指明的 undefined,都会改为 default 值。

运行时类型检查

校验选项中的 type 可以是下列这些原生构造函数:

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol
  • Error

另外,type 也可以是自定义的类或构造函数,Vue 将会通过 instanceof 来检查类型是否匹配。例如下面这个类:

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName
    this.lastName = lastName
  }
}
defineProps({
  author: Person
})

Vue 会通过 instanceof Person 来校验 author prop 的值是否是 Person 类的一个实例。

Boolean 类型转换

为了更贴近原生 boolean attributes 的行为,声明为 Boolean 类型的 props 有特别的类型转换规则。以带有如下声明的 <MyComponent> 组件为例

defineProps({
  disabled: Boolean
})

 

<!-- 等同于传入 :disabled="true" -->
<MyComponent disabled />
<!-- 等同于传入 :disabled="false" -->
<MyComponent />

当一个 prop 被声明为允许多种类型时,Boolean 的转换规则也将被应用。然而,当同时允许 String 和 Boolean 时,有一种边缘情况——只有当 Boolean 出现在 String 之前时,Boolean 转换规则才适用:

// disabled 将被转换为 true
defineProps({
  disabled: [Boolean, Number]
})
  
// disabled 将被转换为 true
defineProps({
  disabled: [Boolean, String]
})
  
// disabled 将被转换为 true
defineProps({
  disabled: [Number, Boolean]
})
  
// disabled 将被解析为空字符串 (disabled="")
defineProps({
  disabled: [String, Boolean]
})
相关文章
|
2月前
|
缓存 开发框架 JavaScript
一切皆插件之后,Agent 工程的新范式
插件化颗粒度越细,黑盒越少,运行越透明,我们看的越清,Agent 的优化空间也就越大。
|
3月前
|
人工智能 自然语言处理 定位技术
OPC中国:如何用 AI 智能体搭建可交付、可治理的一人公司?
当人们讨论“OPC中国”时,常指面向 AI 智能体时代的 One Person Company(协同型一人公司)实践与生态。它不是“一个人包办一切”,而是让人负责目标、判断和责任,让可审计的 AI 工作流承担重复执行。本文从工程视角拆解 OPC中国的概念边界、最小可行技术栈、工作流设计、数据安全和 30 天验证方法,并给出一个可落地的内容交付案例。
336 0
|
6月前
|
机器学习/深度学习 Windows
将远程代码签名与 Electron Builder 集成,实现自动化签名
本文详解如何将远程代码签名服务集成至Electron构建流程,通过自定义`electron-builder`的`signtoolOptions.sign`方法,实现Windows安装包及EXE文件的自动化双哈希(SHA256/SHA1)签名与时间戳,提升应用可信度。
|
6月前
|
机器学习/深度学习 数据采集 人工智能
IDC发布Agent基础设施报告,阿里云无影AgentBay总分第一
IDC正式发布《中国 Agent 基础设施平台/执行平台技术评估,2026》报告,凭借在沙箱、工具、记忆、可观测、安全、开放性与兼容性六大核心维度的卓越表现,阿里云无影AgentBay斩获总分第一,全面领跑中国Agent基础设施市场。
|
存储 传感器 运维
RFID电子标签如何选型呢?一文揭晓!
RFID电子标签是一种通过无线电波实现非接触识别的技术,具备智能感应能力,广泛应用于仓储、物流、医疗、交通等多个领域。选型时需考虑应用需求、频段、材质、性能、兼容性及成本等因素,以实现最佳识别效果与经济效益。
使用Excel随机分配固定人数到不同组里
本文介绍了如何使用Excel为学生随机分配学科或分组。通过插入=RAND()生成随机数,并结合RANK.AVG和ROUNDUP函数实现按固定人数分组,或用CHOOSE与RANDBETWEEN实现非固定分组。操作简单实用,适用于各类随机分配场景。
使用Excel随机分配固定人数到不同组里
|
数据采集 监控 调度
应对频率限制:设计智能延迟的微信读书Python爬虫
应对频率限制:设计智能延迟的微信读书Python爬虫
|
人工智能 缓存 并行计算
《VGSP-C (Virtual GPU Scheduling Platform on CPU):基于CPU的虚拟GPU调度平台》
VGSP-C(基于CPU的虚拟GPU调度平台)提出通过“软仿真+并行调度+多机协同”三大路径,在普通CPU上模拟GPU并行计算行为。适用于资源受限或低成本场景,支持单机推理、分布式训练与极简CPU集群部署,提供统一编程接口与弹性扩展能力,助力AI普惠与算力再平衡。
703 0
|
Arthas 监控 Java
Arthas classloader (查看 classloader 的继承树,urls,类加载信息)
Arthas classloader (查看 classloader 的继承树,urls,类加载信息)
442 3
|
机器学习/深度学习 自然语言处理 并行计算
社区供稿 | Para-Former:DUAT理论指导下的CV神经网络并行化,提速多层模型推理
神经网络正越来越多地朝着使用大数据训练大型模型的方向发展,这种解决方案在许多任务中展现出了卓越的性能。然而,这种方法也引入了一个迫切需要解决的问题:当前的深度学习模型基于串行计算,这意味着随着网络层数的增加,训练和推理时间也会随之增长。
536 28

热门文章

最新文章