目录
Prop的命名 (camelCase vs kebab-case)
更多关于Vue前端相关技术点,敬请关注公众号:CTO Plus后续的文章,有问题欢迎后台留言交流。
注意:由于排版太费时间,所以还是多多注重技术干货的内容吧。
接下来的一段时间我将除了总结下关于【Python进阶系列】的知识点分享文章外,还将为各位前端读者(全栈开发者)分享下关于前端开发框架Vue3的内容,当然还会包括:H5、CSS3、JavaScript、JQuery、前端开发规范等前端内容。
然后对Python开发感兴趣的读者也可以关注公众号CTO Plus,关注【Python进阶系列】的内容,同时涉及到Web开发、爬虫开发、操作系统开发、网络安全开发应用领域这块,可以分别参考我的公众号CTO Plus【Flask进阶系列】、【Django进阶系列】、【DRF进阶系列】、【互联网分布式爬虫系列】和【网络安全系列】的内容,敬请关注,欢迎交流。
以下是【Vue3进阶系列】300多篇的部分内容
Vue3是一款流行的JavaScript框架,用于构建用户界面。其中一个核心概念是组件化,它允许开发者将界面拆分为独立、可复用的组件。
在前面文章《Vue3进阶:组件开发指南之构建可复用的UI组件》中我结合了几个实战案例已经介绍了组件的基本使用方法。那么当我们遇到希望多个组件之间互相传递数据的场景时我们该如何处理。
本文我将介绍如何在Vue3中使用Props来传递数据给组件,以及一些最佳实践案例,帮助你构建高质量、可复用的组件。
本篇代码示例届时将打包放在文末的QQ群里。
什么是Props
首先介绍下什么是Props,Props是Vue3中的一种属性,用于从父组件向子组件传递数据,并在子组件中使用这些数据。
组件通信
组件之间的通信是构建复杂应用程序的重要部分。在Vue 3中,组件之间的通信可以通过props和emit事件来实现。
定义和使用Props
在Vue3中,可以通过在子组件的选项对象中定义props属性来声明Props,用以接收父组件传递的数据,也即父组件可以通过props属性向子组件传递数据。props属性是一个数组,用于列出子组件可以接收的Props名称。
示例代码:
// 子组件
const ChildComponent = {
props: ['message'],
template: `<p>{ { message }}</p>`
}
// 父组件
const ParentComponent = {
template: `<div>
<child-component :message="greeting" />
</div>`,
// template: '<child-component message="Hello, SteveRocket"></child-component>',
data() {
return {
greeting: 'Hello, 微信公众号:CTO Plus'
}
},
components: {
ChildComponent
}
}
在上面的代码示例中,我们定义了一个子组件ChildComponent,并在props属性中声明了一个名为message的Props。在父组件ParentComponent中,我们使用子组件并通过:message="greeting"将父组件的greeting数据传递给子组件。
Emit事件
子组件可以通过emit事件向父组件发送消息。在子组件中,可以使用`$emit`方法触发一个自定义事件,并传递数据。父组件可以通过在子组件上使用`v-on`指令来监听子组件的自定义事件。例如:
const ChildComponent = {
template: '<button @click="$emit(\'custom-event\', \'Hello, SteveRocket\')">Send Message</button>'
}
const ParentComponent = {
template: '<div><child-component @custom-event="handleEvent"></child-component></div>',
components: {
ChildComponent
},
methods: {
handleEvent(message) {
console.log(message) // 输出:Hello, SteveRocket
}
}
}
在上面的代码中,我们在子组件的模板中定义了一个点击事件,并通过`$emit`方法触发了一个名为`custom-event`的自定义事件,并传递了消息。在父组件中,我们使用`v-on`指令来监听子组件的`custom-event`事件,并调用`handleEvent`方法来处理事件。
参考阅读:
Prop的命名 (camelCase vs kebab-case)
HTML 中的属性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的kebab-case (短横线分隔命名) 命名:
const app = Vue.createApp({})
app.component('blog-post', {
// 在字符串模板和单文件组件中,你可以使用驼峰式的prop名字
props: ['postTitle'],
template: '<h3>{ { postTitle }}</h3>'
})
<!-- 但在HTML模板中,我们只能使用短横线连接的名字 -->
<blog-post post-title="hello!"></blog-post>
代码示例1:prop基础使用
接下来看一下代码示例
<div id="steverocket">
<site-name blog="公众号:CTO Plus" age="28" author="SteveRocket"></site-name>
<site-name blog="Not BLOG" age="18" author="Cramer"></site-name>
<site-name blog="https://mp.weixin.qq.com/s/0yqGBPbOI6QxHqK17WxU8Q" age="38" author="cto plus"></site-name>
</div>
<script>
const VueApp = Vue.createApp({})
VueApp.component('site-name', {
props: ['blog','age','author'],
template: `<p>this is my blog:{ { blog }}. my old { { age }}. my name is { { author}}</p>`
})
VueApp.mount('#steverocket')
</script>
输出结果
一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。
代码示例2:动态Prop
类似于用 v-bind 绑定 HTML特性到一个表达式,也可以用 v-bind 动态绑定 props的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件:
<steverocket v-for="site in sites" :id="site.id" :content="site.content"></steverocket>
<script>
const Site = {
data() {
return {
sites: [
{id: 11, content: "mp.weixin.qq.com"},
{id: 12, content: "0yqGBPbOI6QxHqK17WxU8Q"},
{id: 13, content: "SteveRocket"},
{id: 14, content: "微信公众号:CTO Plus"},
]
}
}
}
const VueApp = Vue.createApp(Site)
VueApp.component('steverocket', {
props: ['id', 'content'],
template: `<p>{ {id}} { {content}}</p>`
})
VueApp.mount('body')
</script>
输出结果
Prop 类型与验证
在前面,我们只使用了以字符串数组形式列出的prop:
props: ['id', 'content']
或
props: ['blog','age','author']
但是,通常我们都希望能为每个 prop 指定值的数据类型。这样的好处非常多,比如用于为props 中的值提供一个带有验证需求的对象,建议作为开发规范来执行。组件可以为props 指定验证要求,为了定制 prop 的验证方式,我们只需要以对象形式列出 prop各自的名称和数据类型,键值对的名称和值分别是 prop的名称和数据类型:
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // 或任何其他构造函数
}
你可以将prop的数据类型(type)定义成下列原生构造函数(原生构造器)中的一个:
-
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
}
})
关于自定义构造器的详细介绍和使用,将在公众号CTOPlus后面的文章《Vue3进阶:自定义构造器扩展Vue实例的能力》中做详细介绍,敬请关注。
这不仅为你的组件提供了文档,还可以在浏览器的console控制台获取帮助信息。
更多关于Vue前端相关技术点,敬请关注公众号:CTO Plus后续的文章,有问题欢迎后台留言交流。
代码示例3:Prop验证
我们可以为组件的 prop 指定要进行哪些数据验证。如果验证未通过,Vue 会在浏览器控制台中弹出警告信息。具体方法就是为 props 中的值提供一个带有验证需求的对象,而不仅仅是一个字符串数组。例如:
<steverocket></steverocket>
<steverocket></steverocket>
<steverocket></steverocket>
<script>
const VueApp = Vue.createApp({})
VueApp.component('steverocket', {
data() {
return {propValue1:"12.34", propValue2:"CTO Plus"}
},
template: "<p>this is component,propValue1:{ {propValue1}} { {propValue2}}</p>",
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propValue1: Number,
// 多个可能的类型
propValue2: [String, Number],
// 必填的字符串
propValue3: {type: String, required: true},
// 带有默认值的数字
propValue4: {type: Number, default: 28},
// 带有默认值的对象
propValue5: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return {"blog": "https://mp.weixin.qq.com/s/0yqGBPbOI6QxHqK17WxU8Q"}
}
},
// 自定义验证函数
propValue6: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
},
validator02(value) {
return ['steverocket', 'cramer', 'CTO Plus'].includes(value)
}
},
// 具有默认值的函数
propDefaultValueFunction: {
type: Function,
// 与对象或数组默认值不同,这不是一个工厂函数 —— 这是一个用作默认值的函数
default() {
return 'Default Value Function'
}
}
}
})
VueApp.mount('body')
</script>
prop 会在一个组件实例创建之前进行验证,所以实例的选项(如 data、computed 等) 在 default 或 validator函数中是不可用的。当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。
更多关于Vue前端相关技术点,敬请关注公众号:CTO Plus后续的文章,有问题欢迎后台留言交流。
单向数据流
这里介绍下prop的数据单向流向,所有的 prop 都使得父子组件之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样可以防止子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
另外,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
下面有两种常见的试图变更一个 prop 的情形:
这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data 属性并将这个 prop 作为其初始值:
props: ['initialCounter'],
data() {
return {
counter: this.initialCounter
}
}
这其实就是化外部为内部,对数据做一份拷贝。
这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:
props: ['size'],
computed: {
normalizedSize() {
return this.size.trim().toLowerCase()
}
}
第一种方法的升级版,对数据做了处理再变为内部变量。
注意:在 JavaScript 中对象和数组是通过引用传入的(所谓的浅拷贝),所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态。
总结
Vue3的Props是一种用于在组件之间传递和管理数据的机制。通过声明Props并在父组件中传递数据,我们可以将数据有效地传递给子组件并在子组件中使用。同时,Vue3还提供了对Props进行类型验证和默认值设置的功能,以增加代码的健壮性和可读性。希望本文对你理解和使用Vue3 Props有所帮助!
大前端专栏
https://blog.csdn.net/zhouruifu2015/category_5734911.html
更多精彩,关注我公号,一起学习、成长
CTO Plus
一个有深度和广度的技术圈,技术总结、分享与交流,我们一起学习。 涉及网络安全、C/C++、Python、Go、大前端、云原生、SRE、SDL、DevSecOps、数据库、中间件、FPGA、架构设计等大厂技术。 每天早上8点10分准时发文。
306篇原创内容
公众号
Vue推荐阅读:
推荐阅读:
工具类推荐阅读:
最后,不少前端粉丝后台留言问加技术交流群,之前也一直没弄,所以为满足粉丝需求,现建立了一个关于前端开发相关的技术交流群,加群验证方式必须为本公众号的粉丝,群号如下: