09、组件

https://blog.csdn.net/qq408896436/article/details/79250605

组件是什么?

 组件其实就是一片html代码


组件有什么用?

封装可重用的代码,类似我们以前把index.html的后缀改为index.shtml,然后使用#include引入页面


一个简单的例子

[javascript]  view plain  copy
  1. <div id='app'>    
  2.     <!--3、使用组件-->    
  3.     <aaa></aaa>    
  4. </div>    
  5. <script src='../js/vue.js'></script>    
  6. <script>    
  7.     
  8. //1、定义组件    
  9. var AAA = Vue.extend({    
  10.     template : '<h3>h3标签</h3>'    
  11. });    
  12.     
  13. //2、注册组件        
  14. Vue.component('aaa', AAA);    
  15.     
  16. var vm = new Vue({    
  17.     el : '#app'    
  18. });    
  19. </script>  


组件使用步骤 

1、定义组件 :Vue.extend

2、注册组件 :Vue.component该函数的第一个参数是组件的名字,第二个参数是组件对象

3、使用组件 :<aaa></aaa>


组件中的data”与“methods

组件里也可以像我们平常使用vue那样,使用datamethods来修改template里的数据或者给template中的标签添加事件。基本上,组件与我们平常使用vue的方式很类似。下面是在组件上添加datamethods的一个例子 :

[javascript]  view plain  copy
  1. <div id='app'>  
  2.     <aaa></aaa>  
  3. </div>  
  4. <script src='../js/vue.js'></script>  
  5. <script>  
  6. var AAA = Vue.extend({  
  7.     template : '<h3 @click="say">{{msg}}</h3>',  
  8.     data(){  
  9.         return {  
  10.             msg : 'h3标签'  
  11.         }  
  12.     },  
  13.     methods : {  
  14.         say : function(){  
  15.             alert('你点击了我呀!');  
  16.         }  
  17.     },  
  18.     created : function(){  
  19.         console.log('实例已经创建')  
  20.     },  
  21.     beforeCompile : function(){  
  22.         console.log('编译之前');  
  23.     },  
  24.     compiled : function(){  
  25.         console.log('编译之后');  
  26.     },  
  27.     ready : function(){  
  28.         console.log('插入数据到文档中');  
  29.     }  
  30. });  
  31.       
  32. Vue.component('aaa', AAA);  
  33. var vm = new Vue({  
  34.     el : '#app'  
  35. });  
  36. </script>    

需要注意的是上面的data和我们平常使用的data有些不一样。组件中的data必须以函数的形式并且需要return一个json

而且Vue.extend返回的其实是一个Vue对象,类似我们平常

[javascript]  view plain  copy
  1. var vm = new Vue({  
  2.  'el' : '#app'  
  3. });  
vm 对象,所以里面也会有一系列的钩子函数。

组件的另一种写法(简写)

Vue.extend这个步骤其实可以被省略。直接调用Vue.component即可完成一个组件的编写。如 :

[javascript]  view plain  copy
  1. Vue.component('组件名字',{  
  2.     'template' : 'xxxxx',  
  3.      data(){  
  4.         return {  
  5.             xxx : xxxx  
  6.         }  
  7.     },  
  8.     methods : {  
  9.         xxx : function(){  
  10.     }  
  11.     }  
  12. });  

或者

[javascript]  view plain  copy
  1. var json = {  
  2.     template : 'xxxxx',  
  3.     data(){  
  4.         return {  
  5.             xxx : xxxx  
  6.         }  
  7.     },  
  8.     methods : {  
  9.         xxx : function(){  
  10.         }  
  11.     }  
  12. }  
  13.   
  14.   
  15. Vue.component('组件名字', json);  


局部组件

我们上面说的都是全局组件,组件还有一种是局部的。定义局部组件和定义全局的类似,只要把定义组件的步骤放在我们的new Vue里面即可。

语法 

[javascript]  view plain  copy
  1. components :{  
  2.     '组件1' : {  
  3.         'template' : 'xxx',  
  4.         data(){  
  5.             return {  
  6.                 xxx : 'xxx'  
  7.             }  
  8.         },  
  9.         methods : {  
  10.             xxx : function(){  
  11.   
  12.             }  
  13.         }  
  14.     },  
  15.     '组件2' : {  
  16.         'template' : 'xxx',  
  17.         data(){  
  18.             return {  
  19.                 xxx : 'xxx'  
  20.             }  
  21.         },  
  22.         methods : {  
  23.             xxx : function(){  
  24.   
  25.             }  
  26.         }  
  27.     }  
  28. }   

或者

[javascript]  view plain  copy
  1. var json1 = {  
  2.     template : 'xxxx'  
  3. }  
  4. var json2 = {  
  5.     template : 'xxxx'  
  6. }  
  7. components :{  
  8.     '组件1' : json1,  
  9.     '组件2' : json2  
  10. }  

例子

[html]  view plain  copy
  1. <div id='app'>  
  2.     <aaa></aaa>  
  3.     <bbb></bbb>  
  4. </div>  
  5. <div id='bpp'>  
  6. <!--调用app里的局部组件-->  
  7.     <aaa></aaa>  
  8.     <bbb></bbb>  
  9. </div>  
  10. <script src='../js/vue.js'></script>  
  11. <script>  
  12. var app = new Vue({  
  13.     el : '#app',  
  14.     components : {  
  15.         'aaa' : {  
  16.             template : '<h3 @click="say">{{msg}}</h3>',  
  17.             data(){  
  18.                 return {  
  19.                     msg : 'h3标签'  
  20.                 }  
  21.             },  
  22.             methods : {  
  23.                 say : function(){  
  24.                     alert('你点击了h3!')  
  25.                 }  
  26.             }  
  27.         },  
  28.         'bbb' : {  
  29.             template : '<h4 @click="say">{{msg}}</h4>',  
  30.             data(){  
  31.                 return {  
  32.                     msg : 'h4标签'  
  33.                 }  
  34.             },  
  35.             methods : {  
  36.                 say : function(){  
  37.                     alert('你点击了h4!')  
  38.                 }  
  39.             }  
  40.         }  
  41.     }  
  42. });  
  43.   
  44. var bpp = new Vue({  
  45.     el : '#bpp'  
  46. });  
  47. </script>  

需要注意的是,components后面是有s的,因为里面可以放很多个组件。以及局部组件只有app里面的能用,bpp用的话就直接报错了。


template写在外面

或许你已经发现了,template : '<h3>h3标签</h3>'这句语句的弊端。如果标签内容很多,都用字符串的形式编写html代码,那还不累死。解决方法是使用template标签,把组件写在外面。如 :

[html]  view plain  copy
  1. <div id='app'>  
  2.     <aaa></aaa>  
  3. </div>  
  4. <template id='zujian-1'>  
  5.     <h3>我是h3</h3>  
  6. </template>  
  7. <script src='../js/vue.js'></script>  
  8. <script>  
  9. var app = new Vue({  
  10.     el : '#app',  
  11.     components : {  
  12.         'aaa' : {  
  13.             template : '#zujian-1'  
  14.         }  
  15.     }  
  16. });  
  17. </script>  

component里面对应templateID即可。


子组件

组件里面还可以嵌套组件。实现子组件,只需要记住以下两点即可

1、子组件必须写在父组件的template

2、子组件必须要在父组件内部注册

例子:

[javascript]  view plain  copy
  1. <div id='app'>    
  2.     <aaa></aaa>    
  3. </div>    
  4. <template id='aaa-template'>    
  5.     <h2>我是aaa组件的内容</h2>    
  6.     <bbb></bbb>     //子组件必须写在父组件的template中    
  7. </template>    
  8.     
  9. <template id='bbb-template'>    
  10.     <h3>我是bbb组件的内容</h3>    
  11. </template>    
  12.     
  13. <script src='../js/vue.js'></script>    
  14. <script>    
  15. var app = new Vue({    
  16.     el : '#app',    
  17.     components :     
  18.     {    
  19.         'aaa' :     
  20.         {    
  21.             template : '#aaa-template',    
  22.             components :  //子组件必须要在父组件内部注册    
  23.     
  24.             {    
  25.                 'bbb' :     
  26.                 {    
  27.                     template : '#bbb-template'    
  28.                 }    
  29.             }    
  30.         }    
  31.     }    
  32. });    
  33. </script>   


父组件与子组件的数据传递

默认情况下,父组件与子组件的数据是互相不能访问的。但可以通过一些方法来获取。


父组件获取子组件数据

步骤 

1、子组件发送广播。(发送广播通过$emit方法,该方法接受两个参数 :第一个参数是 :广播的事件名

第二个参数是 :要发送给父组件的数据)

2、子组件接受广播。(通过v-on绑定子组件的广播事件然后接收数据)

3、父组件调用第2步的事件在修改值

例子 

[javascript]  view plain  copy
  1. <div id='app'>    
  2.    <parent></parent>  
  3. </div>    
  4. <script src='vue.js'></script>    
  5. <script>  
  6.     new Vue({  
  7.         el : '#app',  
  8.         components :   
  9.         {  
  10.             'parent' : {  
  11.                 //第2步  
  12.                 template : '<h2>{{msg}}</h2><br/><child @send="get"></child>',   
  13.                 data(){  
  14.                     return {  
  15.                         msg : ''  
  16.                     }  
  17.                 } ,  
  18.                 methods : {  
  19.                     //第3步  
  20.                     get : function(msg){  
  21.                         this.msg = msg;  
  22.                     }  
  23.                 },  
  24.                 components :{  
  25.                     'child' :{  
  26.                         template : '<h2>{{msg}}</h2>',  
  27.                         data(){  
  28.                             return{  
  29.                                 msg : '我是子组件数据'  
  30.                             }  
  31.                         },  
  32.                         ready : function(){    
  33.                             //第1步  
  34.                             this.$emit('send'this.msg);      
  35.                         }    
  36.                     }  
  37.                 }  
  38.             }  
  39.         }  
  40.     });  
  41. </script>  


子组件获取父组件数据

1、在子组件中使用v-bind绑定要获取的父组件数据。如 :<bbb :xxx=’父组件数据’></bbb>

2、在子组件内部使用props

3、使用数据

例子 

[javascript]  view plain  copy
  1. <div id='app'>    
  2.    <parent></parent>  
  3. </div>    
  4. <script src='vue.js'></script>    
  5. <script>  
  6.     new Vue({  
  7.         el : '#app',  
  8.         components :   
  9.         {  
  10.             'parent' : {  
  11.                 //第1步  
  12.                 template : '<h2>{{msg}}</h2><br/><child :fmsg="msg"></child>',    
  13.                 data(){  
  14.                     return{  
  15.                         msg : '我是父组件数据'  
  16.                     }  
  17.                 },  
  18.                 components :{  
  19.                     'child' :{  
  20.                         //第2步  
  21.                         props :['fmsg'],  
  22.                         //第3步  
  23.                         template : '<h2>{{fmsg}}</h2>'  
  24.                     }  
  25.                 }  
  26.             }  
  27.         }  
  28.     });  
  29. </script>  


子组件修改父组件的值(vue2.0版本中是不允许这样修改的,这里了解下就好)

[javascript]  view plain  copy
  1. <!doctype html>  
  2. <html lang="en">  
  3. <head>  
  4.     <meta charset="UTF-8">  
  5.     <title>Document</title>  
  6. </head>  
  7. <body>  
  8. <div id='app'>      
  9.    <parent></parent>    
  10. </div>      
  11. <script src='vue.js'></script>      
  12. <script>    
  13.     new Vue({    
  14.         el : '#app',    
  15.         components :     
  16.         {    
  17.             'parent' : {    
  18.                 template : '<div><h2>{{msg}}</h2><br/><child :fmsg.sync="msg"></child></div>',      
  19.                 data(){    
  20.                     return{    
  21.                         msg : '我是父组件数据'    
  22.                     }    
  23.                 },    
  24.                 components :{    
  25.                     'child' :{    
  26.                         props :['fmsg'],    
  27.                         template : '<div><h2>{{fmsg}}</h2><button @click="change">点击我修改父组件数据</button></div>',  
  28.                         methods : {  
  29.                             change : function(){  
  30.                                 this.fmsg = 0;  
  31.                             }  
  32.                         }   
  33.                     }    
  34.                 }    
  35.             }    
  36.         }    
  37.     });    
  38. </script>  
  39. </body>  
  40. </html>  


使用$emit和$on互相发送数据

父组件和子组件传递数据除了上面说的那2种方法外,还可以使用$emit和$on来发送数据。发送的一方使用$emit,接受的一方使用$on即可。(推荐使用这种方法,简单好管理)

例子

子组件发送数据给父组件

[javascript]  view plain  copy
  1. <!doctype html>  
  2. <html lang="en">  
  3. <head>  
  4.     <meta charset="UTF-8">  
  5.     <title></title>  
  6. </head>  
  7. <body>  
  8. <div id='app'>      
  9.    <parent></parent>    
  10. </div>      
  11. <script src='vue.js'></script>      
  12. <script>    
  13.   
  14.     var Event = new Vue();  
  15.   
  16.     new Vue({    
  17.         el : '#app',    
  18.         components :     
  19.         {    
  20.             'parent' : {    
  21.                 template : '<div><h2>{{msg}}</h2><br/><child></child></div>',      
  22.                 data(){    
  23.                     return{    
  24.                         msg : '空'    
  25.                     }    
  26.                 },    
  27.                 ready : function(){  
  28.                     console.log('父mounted');  
  29.                     Event.$on('msg'function(msg){  
  30.                         this.msg = msg;  
  31.                     }.bind(this));  
  32.                 },  
  33.                 components :{    
  34.                     'child' :{    
  35.                         template : '<div><h2>{{msg}}</h2></div>',  
  36.                         data(){    
  37.                             return{    
  38.                                 msg : '我是子组件数据'    
  39.                             }    
  40.                         },  
  41.                         ready  : function(){  
  42.                             setTimeout(function(){  
  43.                                 console.log('子mounted');  
  44.                                 Event.$emit('msg'this.msg);  
  45.                             }.bind(this),10)  
  46.                         },  
  47.                     }    
  48.                 }    
  49.             }    
  50.         }    
  51.     });    
  52. </script>    
  53. </body>  
  54. </html>  

父组件发送数据给子组件

[javascript]  view plain  copy
  1. <!doctype html>  
  2. <html lang="en">  
  3. <head>  
  4.     <meta charset="UTF-8">  
  5.     <title></title>  
  6. </head>  
  7. <body>  
  8. <div id='app'>      
  9.    <parent></parent>    
  10. </div>      
  11. <script src='vue.js'></script>      
  12. <script>    
  13.   
  14.     var Event = new Vue();  
  15.   
  16.     new Vue({    
  17.         el : '#app',    
  18.         components :     
  19.         {    
  20.             'parent' : {    
  21.                 template : '<div><h2>{{msg}}</h2><br/><child></child></div>',      
  22.                 data(){    
  23.                     return{    
  24.                         msg : '我是父组件数据'    
  25.                     }    
  26.                 },    
  27.                 ready : function(){  
  28.                     console.log('父mounted');  
  29.                     Event.$emit('msg'this.msg);  
  30.                 },  
  31.                 components :{    
  32.                     'child' :{    
  33.                         template : '<div><h2>{{msg}}</h2></div>',  
  34.                         data(){    
  35.                             return{    
  36.                                 msg : '空'    
  37.                             }    
  38.                         },  
  39.                         ready : function(){  
  40.                             console.log('子mounted');  
  41.                             Event.$on('msg'function(msg){  
  42.                                 this.msg = msg;  
  43.                             }.bind(this));  
  44.                         },  
  45.                     }    
  46.                 }    
  47.             }    
  48.         }    
  49.     });    
  50. </script>    
  51. </body>  
  52. </html>  

提示 :传递数据的时候,发送的一方不管是父还是子,一定要先$on了在$emit(先注册事件,在发送)才管用。所以我们在子组件发送数据给父组件 这个例子里,子组件用了setTimeout才$emit,因为vue会先去编译子组件。不用setTimeout的话就会先执行$emit了




总结

1、组件有全局组件与局部组件,全局组件在任何地方都能用,局部组件只有在绑定的eldiv内才能使用。

2、定义全局组件有2种方式,一种是Vue.extend +Vue.component,另外一种是直接使用Vue.component

3、定义局部组件,只要定义在new Vue({}) 的内部即可components这个单词后面是有s

4、组件中也可以有datamethods,需要注意的是在组件内部定义data必须以函数的形式定义,并且需要返回一个json

5、定义组件时,template可以写在外面。只要给template定义一个id,注册组件的时候,引用这个id即可。如 :

[javascript]  view plain  copy
  1. <template id='aaa'></template>  
  2. new Vue({  
  3.     el : '#app',  
  4.     components: {  
  5.         'aaa' : {  
  6.             template:'#aaa'  
  7.         }  
  8.     }  
  9. });   

6、组件之间是可以嵌套的,嵌套组件时记住两点 :

1)子组件必须写在父组件的template

2)子组件必须要在父组件内部注册

7、父获取子数据:通过$emit和v-on

8、子获取父数据:通过propsv-bind

9、$emit和$on也可以实现父/子组件的数据发送,需要注意的是一定要先on了才emit

猜你喜欢

转载自blog.csdn.net/uwenhao2008/article/details/80753449
09
今日推荐