vue3的props和defineProps

文章目录

    • 1. Props 声明
      • 1.1 props用字符串数组来声明
        • Blog.vue
        • BlogPost.vue
      • 1.2 props使用对象来声明
        • Blog.vue
        • BlogPost.vue
    • 2. 传递 prop 的细节
      • 2.1 Prop 名字格式
      • 2.1 静态Prop & 动态 Prop
        • 静态prop
        • 动态prop
          • 示例
            • Blog.vue
            • BlogPost.vue
      • 2.3 传递不同的值类型
        • Number
        • Boolean
        • Array
        • Object
      • 2.4 使用一个对象绑定多个 prop
        • Blog.vue
        • BlogPost.vue
    • 3. 单向数据流(重要)
      • 3.1 更改对象 / 数组类型的 props
        • Blog.vue
        • BlogPost.vue
    • 4. Prop 校验
      • 4.1 运行时类型检查
    • 5. Boolean 类型转换
      • Blog.vue
      • BlogPost.vue

1. Props 声明

  • 一个组件需要显式声明它所接受的 props,这样 Vue 才能知道外部传入的哪些是 props,哪些是透传 attribute
  • props 需要使用 props 选项来定义

1.1 props用字符串数组来声明

看上去跟vue2没什么区别,就是先引入组件,然后注册组件,然后就使用组件。接着绑定属性。

Blog.vue

<template>
    <div>
        <h1>Blog组件</h1>
        <blog-post title="学习vue3"/>
    </div>
</template>

<script >
    import BlogPost from './BlogPost.vue'
    export default {
        name: 'Blog',
        components:{
            BlogPost
        }
    }

</script>

<style lang="scss"></style>

BlogPost.vue

<template>
    <h3>{{ title }}</h3>
</template>

<script>

    export default {
        name: 'BlogPost',
        props: ['title']
    }

</script>

<style lang="scss"></style>

1.2 props使用对象来声明

  • key 是 prop 的名称,而值则是该 prop 预期类型的构造函数
  • 如果在使用时,传递了错误的类型,会在浏览器控制台中抛出警告

Blog.vue

<template>
    <div>
        <h1>Blog组件</h1>
        <blog-post title="学习vue3" :likes="3"/>
    </div>
</template>

<script >
    import BlogPost from './BlogPost.vue'
    export default {
        name: 'Blog',
        components:{
            BlogPost
        }
    }

</script>

<style lang="scss"></style>

BlogPost.vue

<template>
    <h3>{{ title }}</h3>
    <span>{{ likes }}</span>
</template>

<script>

export default {
    name: 'BlogPost',
    props: {
        title: String,
        likes: Number
    }
}

</script>

<style lang="scss"></style>

2. 传递 prop 的细节

2.1 Prop 名字格式

  • 定义prop的名字时 ,建议使用 camelCase 形式(驼峰命名,首字母小写)
  • 向子组件传递 props 时,可以使用 camelCase 形式,但通常使用kebab-case形式(短横线形式)
  • 定义组件名时,建议使用PascalCase形式(驼峰命名,但首字母大写)

2.1 静态Prop & 动态 Prop

静态prop

<BlogPost title="My journey with Vue" />

动态prop

可以将组件中定义的属性值(响应式数据)传给子组件,当这些属性值发生变化时,子组件也会更新重新渲染

<!-- 根据一个变量的值动态传入 -->
<BlogPost :title="post.title" />

<!-- 根据一个更复杂表达式的值动态传入 -->
<BlogPost :title="post.title + ' by ' + post.author.name" />
示例

在这里插入图片描述

Blog.vue
<template>
    <div>
        <h1>Blog组件</h1>
        <button @click="addLike">addLike</button>
        <blog-post title="学习vue3" :likes="likes"/>
    </div>
</template>

<script >
    import BlogPost from './BlogPost.vue'
    export default {
        name: 'Blog',
        components:{
            BlogPost
        },
        data() {
            return {
                likes: 0
            }
        },
        methods: {
            addLike() {
                this.likes ++
            }
        }
    }

</script>

<style lang="scss">

</style>
BlogPost.vue
<template>
    <h3>{{ title }}</h3>
    <span>{{ likes }}</span>
</template>

<script>

export default {
    name: 'BlogPost',
    props: {
        title: String,
        likes: Number
    }
}

</script>

<style lang="scss"></style>

2.3 传递不同的值类型

  • 任何类型的值都可以作为 props 的值被传递。
  • 使用 v-bind绑定的值 将视为 js表达式

Number

<!-- 虽然 `42` 是个常量,我们还是需要使用 v-bind -->
<!-- 因为这是一个 JavaScript 表达式而不是一个字符串 -->
<BlogPost :likes="42" />

<!-- 根据一个变量的值动态传入 -->
<BlogPost :likes="post.likes" />

Boolean

注意会隐式转换,和 使用 v-bind绑定的值 将视为 js表达式

<!-- 仅写上 prop 但不传值,会隐式转换为 `true` -->
<BlogPost is-published />

<!-- 虽然 `false` 是静态的值,我们还是需要使用 v-bind -->
<!-- 因为这是一个 JavaScript 表达式而不是一个字符串 -->
<BlogPost :is-published="false" />

<!-- 根据一个变量的值动态传入 -->
<BlogPost :is-published="post.isPublished" />

Array

<!-- 虽然这个数组是个常量,我们还是需要使用 v-bind -->
<!-- 因为这是一个 JavaScript 表达式而不是一个字符串 -->
<BlogPost :comment-ids="[234, 266, 273]" />

<!-- 根据一个变量的值动态传入 -->
<BlogPost :comment-ids="post.commentIds" />

Object

<!-- 虽然这个对象字面量是个常量,我们还是需要使用 v-bind -->
<!-- 因为这是一个 JavaScript 表达式而不是一个字符串 -->
<BlogPost :author="{name: 'Veronica', company: 'Veridian Dynamics'}" />

<!-- 根据一个变量的值动态传入 -->
<BlogPost :author="post.author" />

2.4 使用一个对象绑定多个 prop

可以使用没有参数的 v-bind,即只使用 v-bind 而非 :prop-name。这样就可以将一个对象的所有属性都当作 props 传入

在这里插入图片描述

Blog.vue

<template>
    <div>
    
        <h1>Blog组件</h1>
        
        <blog-post v-bind="post"/>
        
        <blog-post :title="post.title" :likes="post.likes"/>
        
    </div>
</template>

<script >
    import BlogPost from './BlogPost.vue'
    export default {
        name: 'Blog',
        components:{
            BlogPost
        },
        data() {
            return {
                post: {
                    likes: 3,
                    title: '学习vue3'
                }
            }
        }
    }

</script>

<style lang="scss"></style>

BlogPost.vue

<template>
    <h3>{{ title }}</h3>
    <span>{{ likes }}</span>
</template>

<script>

export default {
    name: 'BlogPost',
    props: {
        title: String,
        likes: Number
    }
}

</script>

<style lang="scss"></style>

3. 单向数据流(重要)

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

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

    export default {
      props: ['foo'],
      created() {
        // ❌ 警告!prop 是只读的!
        this.foo = 'bar'
      }
    }
    
  • 子组件想修改prop,可以使用 “变通的手段来更改prop”(不是真正的修改)

    • prop 被用于传入初始值;而子组件想在之后将其作为一个局部数据属性。在这种情况下,最好是新定义一个局部数据属性,从 props 上获取初始值即可:

      export default {
        props: ['initialCounter'],
        data() {
          return {
            // 计数器只是将 this.initialCounter 作为初始值
            // 像下面这样做就使 prop 和后续更新无关了
            counter: this.initialCounter
          }
        }
      }
      
    • 需要对传入的 prop 值做进一步的转换。在这种情况中,最好是基于该 prop 值定义一个计算属性

      export default {
        props: ['size'],
        computed: {
          // 该 prop 变更时计算属性也会自动更新
          normalizedSize() {
            return this.size.trim().toLowerCase()
          }
        }
      }
      

3.1 更改对象 / 数组类型的 props

对 象数组 作为 props 被传入时,虽然子组件无法更改 props 绑定,但仍然可以更改对象或数组内部的值

  • 在最佳实践中,你应该尽可能避免这样的更改,除非父子组件在设计上本来就需要紧密耦合

  • 在大多数场景下,子组件应该抛出一个事件来通知父组件做出改变

在这里插入图片描述

Blog.vue

<template>
    <div>
        <h1>Blog组件</h1>
        <blog-post :post="post" @addLiking="addLiking"/>
    </div>
</template>

<script >
    import BlogPost from './BlogPost.vue'
    export default {
        name: 'Blog',
        components:{
            BlogPost
        },
        data() {
            return {
                post: {
                    likes: 3,
                    title: '学习vue3',
                    tags: ['java','spring','vue','ps']
                },
                
            }
        },
        methods: {
            addLiking(){
                this.post.likes += 2
            }
        }
    }

</script>

<style lang="scss"></style>

BlogPost.vue

  • 父组件通过props传递过来post
  • 子组件中直接修改通过props传过来的post(对象)里面内部的属性
  • 子组件中直接修改通过props传过来的post.tags(数组)里面内部的属性
<template>
    <h3>{{ post.title }}</h3>
    <span>{{ post.likes }}</span> 

    <br/>

    <span v-for="tag,idx in post.tags" :key="idx">{{ tag }}、</span>
    
    <br/>

    <button @click="addLike">addLike + 1</button>
    <button @click="emitLike">emitLike + 2</button>

    <br/>

    <button @click="post.tags[3] = 'redis'">changeArr</button>
    
</template>

<script>

export default {
    name: 'BlogPost',
    props: {
        post: Object
    },
    methods: {
        addLike() {
            this.post.likes++
        },
        emitLike() {
            this.$emit('addLiking')
        }
    }
}

</script>

<style lang="scss"></style>

4. Prop 校验

可以向 props 选项提供一个带有 props 校验选项的对象。

  • 所有 prop 默认都是可选的,除非声明了 required: true
  • 除 Boolean 外的未传递的可选 prop 将会有一个默认值 undefined
    • Boolean 类型的未传递 prop 将被转换为 false!!!(但是,可以通过default来修改,比如:default:undefined。)。
  • 如果声明了 default 值,那么在 prop 的值被解析为 undefined 时,无论 prop 是未被传递还是显式指明的 undefined,都会改为 default 值。
export default {

  props: {
  
    // 基础类型检查
    //(给出 `null` 和 `undefined` 值则会跳过任何类型检查)
    propA: Number,
    
    // 多种可能的类型
    propB: [String, Number],
    
    // 必传,且为 String 类型
    propC: {
      type: String,
      required: true
    },
    
    // Number 类型的默认值
    propD: {
      type: Number,
      default: 100
    },
    
    // 对象类型的默认值
    propE: {
      type: Object,
      // 对象或者数组应当用工厂函数返回。
      // 工厂函数会收到组件所接收的原始 props
      // 作为参数
      default(rawProps) {
        return { message: 'hello' }
      }
    },
    
    // 自定义类型校验函数
    propF: {
      validator(value) {
        // The value must match one of these strings
        return ['success', 'warning', 'danger'].includes(value)
      }
    },
    
    // 函数类型的默认值
    propG: {
      type: Function,
      // 不像对象或数组的默认,这不是一个
      // 工厂函数。这会是一个用来作为默认值的函数
      default() {
        return 'Default function'
      }
    }
    
  }
}

4.1 运行时类型检查

校验选项中的 type 可以是下列这些原生构造函数,也可以是自定义的类或构造函数,Vue 将会通过 instanceof 来检查类型是否匹配。

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

5. Boolean 类型转换

声明为 Boolean 类型的 props 有特别的类型转换规则

在这里插入图片描述

Blog.vue

  • 虽然diabled属性被声明为了Boolean类型,但是,如果传一个字符串过去,仍然就是字符串。
<template>
    <div>
        <h1>Blog组件</h1>
        <blog-post disabled/> <br/>
        <blog-post disabled/> <br/>
        <blog-post disabled="false"/> <br/>
        <blog-post disabled="false1"/> <br/>
        <blog-post :disabled="false"/>
    </div>
</template>

<script >
    import BlogPost from './BlogPost.vue'
    export default {
        name: 'Blog',
        components:{
            BlogPost
        },
        data() {
            return {}
        }
    }

</script>

<style lang="scss"></style>

BlogPost.vue

<template>
    
    {{ disabled }}

</template>

<script>

export default {
    name: 'BlogPost',
    props: {
        disabled:Boolean
    }
}

</script>

<style lang="scss"></style>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于YOLOv4的目标检测系统(附MATLAB代码+GUI实现)

摘要&#xff1a;本文介绍了一种MATLAB实现的目标检测系统代码&#xff0c;采用 YOLOv4 检测网络作为核心模型&#xff0c;用于训练和检测各种任务下的目标&#xff0c;并在GUI界面中对各种目标检测结果可视化。文章详细介绍了YOLOv4的实现过程&#xff0c;包括算法原理、MATLA…

C++知识点 -- 异常

C知识点 – 异常 文章目录 C知识点 -- 异常一、异常概念二、异常的使用1.异常的抛出和捕获2.异常的重新抛出3.异常安全4.异常规范 三、自定义异常体系四、C标准库的异常体系五、C异常的优缺点 一、异常概念 当一个函数发现自己无法处理错误时&#xff0c;就可以抛出异常&#…

14-3-进程间通信-消息队列

前面提到的管道pipe和fifo是半双工的&#xff0c;在某些场景不能发挥作用&#xff1b; 接下来描述的是消息队列&#xff08;一种全双工的通信方式&#xff09;&#xff1b; 比如消息队列可以实现两个进程互发消息&#xff08;不像管道&#xff0c;只能1个进程发消息&#xff…

kali: kali工具-Ettercap

kali工具-Ettercap ettercap工具&#xff1a; 用来进行arp欺骗&#xff0c;可以进行ARP poisoning&#xff08;arp投毒&#xff09;&#xff0c;除此之外还可以其他功能&#xff1a; ettercap工具的arp投毒可以截取web服务器、FTP服务器账号密码等信息&#xff0c;简略后打印出…

前端学习之使用JavaScript

前情回顾&#xff1a;网页布局 JavaScript 简介 avaScript诞生于1995年&#xff0c;它的出现主要是用于处理网页中的前端验证。所谓的前端验证&#xff0c;就是指检查用户输入的内容是否符合一定的规则。比如&#xff1a;用户名的长度&#xff0c;密码的长度&#xff0c;邮箱的…

SQL中去除重复数据的几种方法,我一次性都告你​

使用SQL对数据进行提取和分析时&#xff0c;我们经常会遇到数据重复的场景&#xff0c;需要我们对数据进行去重后分析。 以某电商公司的销售报表为例&#xff0c;常见的去重方法我们用到distinct 或者group by 语句&#xff0c; 今天介绍一种新的方法&#xff0c;利用窗口函数…

Github 的使用

3. Github 在版本控制系统中&#xff0c;大约90%的操作都是在本地仓库中进行的&#xff1a;暂存&#xff0c;提交&#xff0c;查看状态或者历史记录等等。除此之外&#xff0c;如果仅仅只有你一个人在这个项目里工作&#xff0c;你永远没有机会需要设置一个远程仓库。只有当你…

2001-2021年全国30省就业人数数据

2001-2021年全国30省就业人数数据/各省就业人数数据 1、时间&#xff1a;2001-2021年 2、范围&#xff1a;包括30个省市不含西藏 3、指标&#xff1a;就业人数 4、来源&#xff1a;各省NJ、社会统计NJ 5、缺失情况说明&#xff1a;无缺失 6、指标说明&#xff1a; 就业人…

实在智能出席第六届数字中国建设峰会,入围2022年信息技术应用创新优秀解决方案榜单

最美榕城四月天&#xff0c;山海之间尽显数字澎湃。这一周来&#xff0c;实在智能来到了“有福之州”&#xff0c;为数字中国建设增添实在色彩。 4月25日&#xff0c;实在华夏行抵达福州站&#xff0c;与众多生态合作伙伴携手共话数字发展新未来&#xff1b; 4月26日&#xff…

分布式事务 --- Seata事务模式、高可用

一、事务模式 1.1、XA模式 XA 规范 是 X/Open 组织定义的分布式事务处理&#xff08;DTP&#xff0c;Distributed Transaction Processing&#xff09;标准&#xff0c;XA 规范 描述了全局的TM与局部的RM之间的接口&#xff0c;几乎所有主流的数据库都对 XA 规范 提供了支持。…

ContextCapture Master 倾斜摄影测量实景三维建模技术应用

查看原文>>>ContextCapture Master 倾斜摄影测量实景三维建模技术应用 目录 第一部分、倾斜摄影测量原理及应用领域 第二部分、倾斜摄影测量数据采集方法 第三部分、CC支持数据类型及导入数据方法 第四部分、CC空三计算参数设置及数据处理方法 第五部分、CC控制…

电气电工相关专业知识及名词解释

一、电流电压 火线、零线、地线&#xff1a;火线和零线的区别就是&#xff1a;火线带电&#xff0c;零线不带电。火线是传电流的&#xff0c;而零线是回流的。 红色是火线&#xff0c;零线一般是绿色的&#xff0c;通常可用电笔来测。电笔一头亮了是火线&#xff0c;不亮的则…

Python使用CV2库捕获、播放和保存摄像头视频

Python使用CV2库捕获、播放和保存摄像头视频 特别提示&#xff1a;CV2指的是OpenCV2&#xff08;Open Source Computer Vision Library&#xff09;&#xff0c;安装的时候是 opencv_python&#xff0c;但在导入的时候采用 import cv2。 若想使用cv2库必须先安装&#xff0c;P…

InnoDB 引擎 底层逻辑

目录 0 课程视频 1 逻辑存储结构 1.1 结构图 1.2 表空间 -> 记录 索引 存储记录 等数据 1.2.1 储存在 cd/var/lib/mysql -> ll -> 目录 mysql.ibd 1.3 段 -> 索引 存储记录 具体存储 1.3.1 数据段 b树 叶子节点 1.3.2 索引段 b树的 非叶子节点 1.3.3 回滚段…

ChatGPT来了不用慌,广告人还有这个神器在手

#ChatGPT能取代广告人吗&#xff0c;#ChatGPT会抢走你的工作吗&#xff1f;#ChatGPT火了&#xff0c;会让营销人失业吗&#xff1f;自ChatGPT爆火以来&#xff0c;各种专业or非专业文章不停给广告人强加焦虑&#xff0c;但工具出现的意义&#xff0c;更多在于提效而非替代&…

【技术分享】防止根据IP查域名,防止源站IP泄露

有的人设置了禁止 IP 访问网站&#xff0c;但是别人用 https://ip 的形式&#xff0c;会跳到你服务器所绑定的一个域名网站上 直接通过 https://IP, 访问网站&#xff0c;会出现“您的连接不是私密连接”&#xff0c;然后点高级&#xff0c;会出现“继续前往 IP”&#xff0c;…

简单分享微信小程序上的招聘链接怎么做

招聘小程序的主要用户就是企业招聘端和找工作人员的用户端,下面从这两个端来对招聘小程序开发的功能进行介绍。 企业端功能 1、岗位发布:企业根据自身岗位需求,在招聘app上发布招聘岗位及所需技能。 2.简历筛选:根据求职者提交的简历选择合适的简历,并对公开发布的简历进行筛…

【五一创作】【Simulink】采用延时补偿的三相并网逆变器FCS-MPC

&#x1f449; 【Simulink】基于FCS-MPC的三相并网逆变器控制 上一篇博客介绍了FCS-MPC的基本操作&#xff0c;并且以三相并网逆变器为控制对象进行了Simulink仿真。 但实际仿真中没有考虑补偿延时。本篇博客将讨论为什么要考虑延时并进行补偿&#xff0c;最后对此仿真验证。 …

【Java数据结构】顺序表、队列、栈、链表、哈希表

顺序表 定义 存放数据使用数组但是可以编写一些额外的操作来强化为线性表&#xff0c;底层依然采用顺序存储实现的线性表&#xff0c;称为顺序表 代码实现 创建类型 先定义一个新的类型 public class ArrayList<E> {int capacity 10; //顺序表的最大容量int size …

【Java笔试强训 6】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525;不要二 …