在Vue中组件Component是十分重要的概念。在单页面应用(SPA)中,需要通过组件的嵌套和组合来完成页面的各种显示与交互功能。
父子组件之间的传值和方法的相互调用,是经常需要用到的功能,现对这个功能左一个总结。
1.定义一个组件
在Vue中支持.vue格式的文件,这种文件可以用于定义一个单独的组件,通常情况下一个.vue文件包含三部分:
1 <template> 2 3 </template> 4 5 <script> 6 7 </script> 8 9 <style> 10 11 </style>
即template、script、style。
其中在<template></template>中编写html代码;
在<script></script>中编写JavaScript代码;
在<style></style>中编写CSS代码。
2父组件向子组件传值的方式
定义一个子组件Child.vue:
1 <template> 2 <div> 3 <div>子组件自己的值:{{child_msg}}</div> 4 <div>从父组件传递过来的值:{{parent_msg}}</div> 5 <input type="button" value="打印父组件的值" @click="show"> 6 </div> 7 </template> 8 9 <script> 10 export default { 11 name: "Child.vue", 12 data:function () { 13 return { 14 child_msg:'子组件的值' 15 } 16 }, 17 props:{ 18 parent_msg:String//用于接收父组件传的值 19 }, 20 methods:{ 21 show(){ 22 console.log(this.parent_msg) 23 } 24 } 25 } 26 </script> 27 28 <style scoped> 29 30 </style>
代码说明:
第18行的props是用于接收从父组件传递过来的值的。
在接收这个值之后,就可以在当前组件的js代码中使用这个值,如第22行将这个值输出到控制台。
也可以直接把这个从父组件传递过来的值显示在页面上,如第4行使用插值表达式显示在div中。
定义一个父组件Father.vue:
1 <template> 2 <div> 3 <child :parent_msg="msg"></child> 4 </div> 5 </template> 6 7 <script> 8 import child from './Child.vue' 9 export default { 10 name: "Father.vue", 11 data:function(){ 12 return { 13 msg:'父组件的值' 14 } 15 }, 16 components:{ 17 child 18 } 19 } 20 </script> 21 22 <style scoped> 23 24 </style>
代码说明:
第8行导入子组件的模块,这里使用的是ES6的模块导入语法。
第17行将子组件定义在当前父组件的components中,这是似有组件的定义方式。
第3行通过<child></child>引入子组件,并绑定parent_msg的值。
3父组件向子组件传递方法(子组件调用父组件的方法)
定义一个子组件Child.vue:
1 <template> 2 <div> 3 <input type="button" value="调用父组件的方法" @click="show"> 4 </div> 5 </template> 6 7 <script> 8 export default { 9 name: "Child.vue", 10 methods:{ 11 show(){ 12 this.$emit('parent_method') 13 } 14 } 15 } 16 </script> 17 18 <style scoped> 19 20 </style>
代码说明:
第12行,通过$emit()方法,调用父组件中定义的方法,此处的parent_method是一个任意名称的变量,类似于props中的parent_msg。
第3行,正常定义此子组件的点击事件。
定义一个父组件Father.vue:
1 <template> 2 <div> 3 <child @parent_method="showmsg"></child> 4 </div> 5 </template> 6 7 <script> 8 import child from './Child.vue' 9 export default { 10 name: "Father.vue", 11 methods:{ 12 showmsg(){ 13 console.log('这是父组件的方法') 14 } 15 }, 16 components:{ 17 child 18 } 19 } 20 </script> 21 22 <style scoped> 23 24 </style>
第8行导入子组件的模块,使用ES6语法。
第17行,将子组件模块定义为父组件的私有组件。
第3行,使用子组件,并绑定一个名为parent_method的方法。
第12行,正常定义父组件的一个方法。
4父组件调用子组件的值和方法
定义一个子组件Child.vue:
1 <template> 2 <div> 3 <div>{{child_msg}}</div> 4 </div> 5 </template> 6 7 <script> 8 export default { 9 name: "Child.vue", 10 data:function () { 11 return { 12 child_msg:'子组件的值' 13 } 14 }, 15 methods:{ 16 show(){ 17 console.log('子组件的方法被调用') 18 } 19 } 20 } 21 </script> 22 23 <style scoped> 24 25 </style>
代码说明:
第12行,正常定义子组件的一个属性child_msg。
第16行,正常定义子组件的一个方法show()。
定一个父组件Father.vue:
1 <template> 2 <div> 3 <child ref="mychild"></child> 4 <input type="button" value="父组件使用子组件的值" @click="getchildmsg"> 5 <input type="button" value="父组件调用子组件的方法" @click="dochildfunction"> 6 </div> 7 </template> 8 9 <script> 10 import child from './Child.vue' 11 export default { 12 name: "Father.vue", 13 methods:{ 14 getchildmsg(){//使用子组件的值 15 console.log(this.$refs.mychild.child_msg) 16 }, 17 dochildfunction(){//调用子组件的方法 18 this.$refs.mychild.show() 19 } 20 }, 21 components:{ 22 child 23 } 24 } 25 </script> 26 27 <style scoped>
代码说明:
第10行,通过ES6语法,导入子组件的模块。
第22行,将子组件定义为当前父组件的私有组件。
第3行,引入子组件时,通过ref定义一个名称。
第4,5行,正常定义两个按钮,及其点击事件。
第15行,通过$refs调用子组件中定义的值。
第18行,通过$refs调用子组件中定义的方法。
完整代码下载地址:
百度云:https://pan.baidu.com/s/1H9QEwHiBwuGNhlOGKP5opw
提取码:lhzj
总结:Vue中的父子组件的调用感觉很麻烦,甚至比直接操作Dom对象还要麻烦。
这种操作方式,对于开发人员是很不友好的,这种API的设计还不够完善,感觉就是个“半成品”。
Vue的主要用途是减少操作Dom的工作量,但是对于复杂的交互,因为无法操作Dom,反而增加了更多的工作量,感觉有点得不偿失。
在技术选型时,要对此问题高度重视。技术革新有风险,使用框架须谨慎!