六十一、Vue中父子组件传值和组件参数校验

举报
毛利 发表于 2021/07/15 01:59:12 2021/07/15
【摘要】 @Author:Runsen @Date:2020/10/17 写在前面:我是「Runsen」,热爱技术、热爱开源、热爱编程。技术是开源的、知识是共享的。大四弃算法转前端,需要每天的日积月累,需要强大的自控自制能力。 文章目录 父组件向子组件传值子组件向父组件传值组件参数校验后言 父组件向子组件传值 传值步骤 ① 子组件在 props中创建一个属...

@Author:Runsen

@Date:2020/10/17

写在前面:我是「Runsen」,热爱技术、热爱开源、热爱编程。技术是开源的、知识是共享的。大四弃算法转前端,需要每天的日积月累,需要强大的自控自制能力。

父组件向子组件传值

  1. 传值步骤

① 子组件在 props中创建一个属性,用以接收父组件传过来的数据;

② 父组件中注册子组件。通过属性绑定( v-bind:)的形式,把需要传递给子组件的数据传递到子组件的内部,供子组件使用;

③ 在子组件标签中添加子组件 props中创建的属性;

④ 把需要传给子组件的值赋给该属性

  1. 代码示例
<body>
  <div id="app"> <!-- 子组件向父组件传值  --> <counter :count="1"></counter> <counter :count="2"></counter>
  </div>
  <script> // 定义一个局部组件 var counter = { props:["count"], template: "<div @click='HandleClick'>{{count}}</div>", methods: { HandleClick:function(){ // 修改了父组件中的count值(不建议),子组件不能修改从父组件传递过来的值 this.count ++ } }, } var vm = new Vue({ el:"#app", components:{ counter:counter } })
	</script>
</body>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

父组件可以修改传给子组件的值,但是子组件不能修改从父组件传递过来的值,因为可能会有其他组件共用这个值,因此Vue会报[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "count"的警告错误。
`

解决的方法:子组件可以将这个组件拷贝出来后操作拷贝值,最终的代码示例

<body>
  <div id="app"> <!-- 子组件向父组件传值  --> <counter :count="1"></counter> <counter :count="2"></counter>
  </div>
  <script> // 定义一个局部组件 var counter = { props:["count"], data() { return { //子组件需要将父组件拷贝出来后操作拷贝值 number: this.count } }, template: "<div @click='HandleClick'>{{number}}</div>", methods: { HandleClick:function(){ // 修改了父组件中的count值(不建议),子组件不能修改从父组件传递过来的值 this.number ++ } }, } var vm = new Vue({ el:"#app", components:{ counter:counter } })
	</script>
</body>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

子组件向父组件传值

子组件传值给父组件流程:

  • 1.子组件绑定事件

  • 2.子组件的事件处理函数中通过$emit()向外触发事件,可携带参数

  • 3.父组件监听子组件触发的事件

  • 4.在父组件的事件处理函数中拿到子组件传递的参数,处理子组件的请求

子组件对自己无法操作的数据向父组件抛出请求(通过$emit()向外触发事件),这个请求中可携带相关数据,等待父组件接收这个响应然后自行处理这个请求后更新的数据重新被传递给子组件。

代码示例

=<body>
  <div id="app"> <!-- 子组件向父组件传值  父组件监听子组件触发的事件--> <counter :count="3" @change="HandleChange"></counter> <counter :count="2" @change="HandleChange"></counter> <div>{{total}}</div>
  </div>
  <script> // 定义一个局部组件 var counter = { props:["count"], data() { return { //子组件需要将父组件拷贝出来后操作拷贝值 number: this.count } }, template: "<div @click='HandleClick'>{{number}}</div>", methods: { HandleClick:function(){ // 修改了父组件中的count值(不建议),子组件不能修改从父组件传递过来的值 this.number = this.number + 2 // 子组件向父组件$emit()向外触发事件,可携带参数 this.$emit("change",2) } }, } var vm = new Vue({ el:"#app", components:{ counter:counter }, data:{ total:5 }, methods:{ // 在父组件的事件处理函数中拿到子组件传递的参数,处理子组件的请求 HandleChange:function(step){ this.total += step } } })
	</script>
</body>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

总结:父组件向子组件传值用私有的data数据拷贝props数据,再操作data来实现。子组件传值给父组件一共四个流程。

在组件传值过程中,无论是父传子、还是子传父,它们都有一个共同点就是有一个中间介质。父传子的介质是 props中的属性,子传父的介质是自定义事件。

父子组件的关系可以总结为props向下传递,事件向上传递。父组件通过props给子组件下发数据,子组件通过事件给父组件发送信息。

父组件通过 v-bind:绑定参数传给子组件,子组件通过 props接收这个参数。
在组件的最底层开始写事件,由最底层组件逐步向上$emit事件流,并携带相应参数,最后在父组件内完成总的数据处理。

组件参数校验

props 可以是数组或对象,用于接收来自父组件的数据。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义验证和设置默认值。

<body>
  <div id="app"> <!-- :content="js表达式"  content="" 字符串 比如:content="123“ 是数字 content="123"是字符串 --> <Child content="Hello world"></Child>
  </div>
  <script> Vue.component("Child",{ // props可以用数组,也可以用对象 // props: ['content'], props:{ // 对content进行约束Number 如果约束是Number或者String,content: [Number,String] // content:Number // 在content中还有validator 复杂校验规则,自定义校验器 content:{ type:String, // 如果type不是String,默认是default required:false, default:"如果type不是String,默认是default", validator:function(value){ //复杂校验规则,自定义校验器 return (value.length>5) } } }, template:"<div>{{content}}</div>" }) var vm = new Vue({ el: "#app", })
  </script>
</body>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

参考资料:

后言

据说,放张小姐姐觉得照片可以提高阅读量,图是来源学校的2020新生。

这个时代做什么事,门槛都变得好高,想当个宅男,你买得起房子吗?看看学校的新生,养下眼,这种白日梦不要做!

文章来源: maoli.blog.csdn.net,作者:刘润森!,版权归原作者所有,如需转载,请联系作者。

原文链接:maoli.blog.csdn.net/article/details/109133872

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。