惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
PCI Perspectives
PCI Perspectives
H
Help Net Security
爱范儿
爱范儿
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
雷峰网
雷峰网
S
Secure Thoughts
Jina AI
Jina AI
Attack and Defense Labs
Attack and Defense Labs
大猫的无限游戏
大猫的无限游戏
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
Security @ Cisco Blogs
阮一峰的网络日志
阮一峰的网络日志
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Recent Commits to openclaw:main
Recent Commits to openclaw:main
The Hacker News
The Hacker News
The Last Watchdog
The Last Watchdog
T
Tor Project blog
小众软件
小众软件
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 叶小钗
博客园 - 【当耐特】
G
Google Developers Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
Cyber Attacks, Cyber Crime and Cyber Security
C
Cisco Blogs
T
The Blog of Author Tim Ferriss
I
Intezer
S
Schneier on Security
S
Securelist
W
WeLiveSecurity
C
Cybersecurity and Infrastructure Security Agency CISA
P
Palo Alto Networks Blog
Scott Helme
Scott Helme
Project Zero
Project Zero
Google Online Security Blog
Google Online Security Blog
T
Threatpost
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Engineering at Meta
Engineering at Meta
Blog — PlanetScale
Blog — PlanetScale
V
Visual Studio Blog
Last Week in AI
Last Week in AI
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
人人都是产品经理
人人都是产品经理
Y
Y Combinator Blog
A
Arctic Wolf
GbyAI
GbyAI
H
Hackread – Cybersecurity News, Data Breaches, AI and More
L
LangChain Blog

博客园 - zhouyu

shardingsphere实现按月分表 Vue3手册译稿 - 深入组件 - 插槽 vscode Vue3 多根节点语法检验错误fix Vue3手册译稿 - 深入组件 - 自定义事件 Vue3手册译稿 - 深入组件 - 非prop属性 Vue3手册译稿 - 深入组件 - 组件注册 Vue3手册译稿 - 基础 - 组件基础 Vue3手册译稿 - 基础 - 表单输入绑定 Vue3手册译稿 - 基础 - 事件处理 Vue3手册译稿 - 基础 - 列表渲染 Vue3手册译稿 - 基础 - 条件渲染 Vue3手册译稿 - 基础 - Class和Style绑定 Vue3手册译稿 - 基础 - 计算属性及监听器 Vue3手册译稿 - 基础 - Data属性及方法 Vue3手册译稿 - 基础 - 模板语法 Vue3手册译稿 - 基础 - 应用&组件实例 Vue3手册译稿 - 基础 - 介绍 Vue3手册译稿 - 基础 - 安装 元旦三天假期,实现一个电商退单管理系统【四】-手机客户端实现
Vue3手册译稿 - 深入组件 - pros
zhouyu · 2021-03-12 · via 博客园 - zhouyu

[info]学习本节,你应该已了解过组件基础

prop类型

前面我们讨论过,props可以是一个字符列表的数组。

props: ['title', 'likes', 'isPublished', 'commentIds', 'author']

但是有时候,我们需要传递一些特别的类型数据。这种情况下,我们可以在列表中传递对象,同时传递属性名称和类型即可:

props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // 或其他任何结构
}

如果类型传递错误,不仅仅只是参考上面的文档自查,同时还会通过浏览器控制台向用户告警。如果想了解类型相关内容,请参考类型检测和props其它类型验证

传递静态或动态的props

前面传递一个静态prop的方法为:

<blog-post title="My journey with Vue"></blog-post>

你也可以使用v-bind或缩写为:来传递动态的props

<!-- 静态 -->
<blog-post :title="post.title"></blog-post>

<!-- 动态传递复杂的静态式 -->
<blog-post :title="post.title + ' by ' + post.author.name"></blog-post>

通过以上两个示例,我们可以传递任何类型数据到props

传递数字

<!-- 即使`42`是一个静态数字,我也要动态的告诉Vue -->
<!-- 使用JavaScript表达式比使用字符串更好       -->
<blog-post :likes="42"></blog-post>

<!-- 动态付值. -->
<blog-post :likes="post.likes"></blog-post>

传递布尔值

<!-- 空值为`true`. -->
<blog-post is-published></blog-post>

<!-- 即使`false`是静态值,也要`v-bind` -->
<!-- 使用JavaScript表达式比使用字符串更好          -->
<blog-post :is-published="false"></blog-post>

<!-- 动态传值. -->
<blog-post :is-published="post.isPublished"></blog-post>

传数组

<!-- 静态值也`v-bind` -->
<!-- js表达式比字符串好.            -->
<blog-post :comment-ids="[234, 266, 273]"></blog-post>

<!-- 动态 -->
<blog-post :comment-ids="post.commentIds"></blog-post>

传对象

如果你想把一个对象的所有属性传给prop,你可以使用v-bind(可以使用:代替)。例如有一个post对象:

post: {
  id: 1,
  title: 'My Journey with Vue'
}

模板:

<blog-post v-bind="post"></blog-post>

与下面效果一致

<blog-post v-bind:id="post.id" v-bind:title="post.title"></blog-post>

单向数据流

所有的props是父子组件间的单向绑定:当父组件属性更新时会传递给子组件,但反之却不行。这会阻止子组件意外的更改父容器的状态,会导致你的应用数据流难以理解。
另外,每次父组件更新时,所有子组件的props都会同步刷新。这意味着你不要在子组件中更改prop属性的值。如果你这样做了,Vue会在控制台告警。
有两种情形会尝试转变prop
1.prop传递一个初始值,然后子组件希望当成一个局部变量来使用。这种情部最后再定义一个局部变量并用prop赋值。

props: ['initialCounter'],
data() {
  return {
    counter: this.initialCounter  //这个局部变量只在这个子组件实例内有效
  }
}
  1. prop传递的是一个原始数据,需要进行转换才能使用。这种情况下最好用计算属性为转换prop
props: ['size'],
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
}

[info]提示
注意如果JavaScript的对象和数组类型是关联起来的,子组件更改这两种类型数据,会影响到父组件的状态。

prop验证

组件prop有专门的需求关系,如前面提到的数据类型。如果需求不满足,Vue就会通过浏览器控制台告警。这对组件计划给其他人使用时尤其有用。
props的验证,你可以提供一个含有需求验证的对象,来替代数组或字符串:

app.component('my-component', {
  props: {
    // 基础类型验证 (`null` 和`undefined` 可以传递任何类型)
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必传项,类型字符串
    propC: {
      type: String,
      required: true
    },
    // 含有默认值的数值类型
    propD: {
      type: Number,
      default: 100
    },
    // 含有默认值的对象类型
    propE: {
      type: Object,
      // 对象或数组的默认值必须来自
      // 一个工厂函数
      default: function() {
        return { message: 'hello' }
      }
    },
    // 自定义验证
    propF: {
      validator: function(value) {
        // 值必须是下面之一
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    },
    // 有默认值的函数
    propG: {
      type: Function,
      // 不像对象或数组的默认值, 这不是工厂函数 - 这是一个用着默认值的函数
      default: function() {
        return 'Default function'
      }
    }
  }
})

prop验证失败时,Vue会发送一个控制台告警(如果使用开发模式构建)

[info]提示
注意prop会在组件创建之前进行验证,所以实例属性(如data,computed等)在defaultvalidator函数内部都不可用

类型检测

类型可以是以下原生结构:

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

另外,类型可以是一个自定义构造函数且通过instanceof进行检查确认。例如下面的构造函数:

function Person(firstName, lastName) {
  this.firstName = firstName
  this.lastName = lastName
}

你可以这样使用:

app.component('blog-post', {
  props: {
    author: Person
  }
})

可以通过new Person来验证author参数。

prop大写小(短横线 VS 驼峰)

HTML标签大小写不敏感,所以浏览器会所有的大写字母理解为小写。这意味着你使用驼峰定义的prop在模板内使用时应该用短横线分隔,是等效的:

const app = Vue.createApp({})

app.component('blog-post', {
  // camelCase in JavaScript
  props: ['postTitle'],
  template: '<h3>{{ postTitle }}</h3>'
})
<!-- HTML中使用短横线分隔 -->
<blog-post post-title="hello!"></blog-post>

再说一遍,如果你使用字符串模板,这些限制都不会生效。