4.Vue组件


一、组件化开发概述   1.组件化开发思想     标准     分治:不同的功能分配到不同的组件中     重用:     组合   2.编程中的组件化思想体现   3.组件化规范:     Web Components       我们希望尽可能多的重用代码       自定义组件的方式不太容易(html、css和js)       多次使用组件可能导致冲突     Web Components通过创建封装好功能的定制元素解决上述问题     Vue部分实现了上述规范     不同的功能封装到不同的组件中,组件可以组合以形成完整的应用   二、组件的注册     2.1 全局组件注册语法     Vue.component(组件名称,{       data:组件数据,       template:组件模板内容     })     例:
1 // 定义一个名为button-counter的组件
2         Vue.component('button-counter',{
3             data:function(){
4                 return{
5                     count:0
6                 }
7             },
8             template:``
9         });
     2.2 组件的用法
1 <div id="app">
2         <button-counter>button-counter>
3         <button-counter>button-counter>
4         <button-counter>button-counter>
5  div>
    注:组件可以重用,且组件之间是相互独立的
  2.3 组件注册注意事项     1.data必须是一个函数       分析函数与普通对象的对比       2.组件模板内容必须是单个的根元素       分析实际演示效果       3.组件模板内容可以是模板字符串       模板字符串需要浏览器提供支持(ES6语法)       4.组件的命名方式       短横线       Vue.component('my-component',{/*...*/})       驼峰式       Vue.component('MyComponent',{/*...*/})            如果使用驼峰式命名组件,那么在使用组件的时候,只能在字符串模板中用驼峰的方式使用组件,但是在普通的标签模板中,必须使用短横线的方式使用组件
  2.4 局部组件注册     var ComponentA = { /* ... */}     var ComponentB = { /* ... */}     var ComponentC = { /* ... */}     new Vue({       el:'#app',       components:{         'component-a':ComponentA,         'component-b':ComponentB,         'component-c':ComponentC,       }     })
 1 var HelloWorld = {
 2             data:function(){
 3                 return{
 4                     msg:'Hello World'
 5                 }
 6             },
 7             template:`
{{msg}}
` 8 }; 9 10 var HelloTom = { 11 data:function(){ 12 return{ 13 msg:'Hello Tom' 14 } 15 }, 16 template:`
{{msg}}
` 17 }; 18 19 var HelloJerry = { 20 data:function(){ 21 return{ 22 msg:'Hello Jerry' 23 } 24 }, 25 template:`
{{msg}}
` 26 }; 27 var vm = new Vue({ 28 el:'#app', 29 data:{ 30 31 }, 32 components:{ 33 'hello-world':HelloWorld, 34 'hello-tom':HelloTom, 35 'hello-jerry':HelloJerry 36 } 37 })
    注:局部组件只能在父组件中使用,不能在其他的组件中使用   三、Vue调试工具
  3.1 调试工具安装     (1) 克隆仓库     (2) 安装依赖包     (3) 构建     (4) 打开Chrome扩展页面     (5) 选中开发者模式     (6) 加载已解压的扩展,选择shells/chrome   四、组件间数据交互       4.1 父组件向子组件传值       1.子组件中通过props接收父组件传递过来的内容,具体通过属性名来接收     2.父组件通过属性将值传递给子组件,属性绑定有两种方式,一是写死,二是动态绑定     3.属性可以传递多个,具体可以在props中多加参数
1 <div id="app">
2         {{pmsg}}
3         <menu-item title='来自父组件的值'>menu-item>
4         <menu-item :title='ptitle' content='hello'>menu-item>
5 div>
 1 Vue.component('menu-item',{
 2             props:['title','content'],
 3             data:function(){
 4                 return{
 5                     msg:'子组件自身的数据'
 6                 }
 7             },
 8             template:`
{{msg + '----' + title + '----' + content}}
` 9 }) 10 var vm = new Vue({ 11 el:'#app', 12 data:{ 13 pmsg:'父组件中的内容', 14 ptitle:'父组件传向子组件的动态绑定的数据' 15 } 16 })
   4.2 props属性名规则      1.在props中使用驼峰的形式,模板中需要使用短横线的形式      2.字符串形式的模板中没有这个限制   
1 <div id="app">
2         {{pmsg}}
3         <menu-item :menu-title='ptitle'>menu-item>
4 div>
 1 Vue.component('third-com',{
 2             props:['testTitle'],
 3             template:`
{{testTitle}}
` 4 }) 5 Vue.component('menu-item',{ 6 props:['menuTitle'], 7 template:`
{{menuTitle}}
` 8 }) 9 var vm = new Vue({ 10 el:'#app', 11 data:{ 12 pmsg:'父组件中的内容', 13 ptitle:'动态绑定属性' 14 }, 15 })
    4.3 props属性值类型         字符串  String       数值     Number       布尔值  Boolean       数组     Array       对象     Object 1<div id="app"> 2 9 <menu-item :pstr='pstr' :pnum='pnum' :pboo='pboo' :parr='parr' :pobj='pobj'>menu-item> 10 div>
 1 Vue.component('menu-item',{
 2             props:['pstr','pnum','pboo','parr','pobj'],
 3             template:`
4
{{"传递的是字符串" + pstr}}
5
{{"传递的是数字" + pnum}}
6
{{"传递的是布尔值" + pboo}}
7
数组:
8
    9
  • for='(item,index) in parr'>{{item}}
  • 10
11
{{"传递的是对象:"}}{{pobj.name}}{{pobj.age}}
12
` 13 }) 14 var vm = new Vue({ 15 el:'#app', 16 data:{ 17 pmsg:'父组件中的内容', 18 pstr:'hello', 19 pnum:12, 20 pboo:true, 21 parr:['apple','orange','banana'], 22 pobj:{ 23 name:'lisi', 24 age:12 25 } 26 } 27 })
    4.4 子组件向父组件传值         注:props传递数据原则: 单向数据流,只允许父组件向子组件传递数据,不允许子组件直接操作props的数据         1. 子组件通过自定义事件向父组件传值                  2. 父组件监听子组件事件           
1 <div id="app">
2         <div :style='{fontSize:fontSize + "px"}'>{{pmsg}}div>
3         <menu-item :parr='parr' @enlarge-text='handle'>menu-item>
4 div>
 1  /* 
 2             props传递数据原则: 单向数据流,只允许父组件向子组件传递数据,不允许子组件直接操作props的数据 
 3         */
 4         Vue.component('menu-item',{
 5             props:['parr'],
 6             template:`
 7                 
8
    9
  • for='(item,index) in parr'>{{item}}
  • 10
11 12 13
14 ` 15 }) 16 var vm = new Vue({ 17 el:'#app', 18 data:{ 19 pmsg:'父组件中内容', 20 parr:['apple','orange','banana'], 21 fontSize:10 22 }, 23 methods: { 24 handle:function(){ 25 // 扩大字体大小 26 this.fontSize += 5; 27 } 28 }, 29 })
             3. 子组件通过自定义事件向父组件传递消息                  4. 父组件监听子组件的事件         
        $event是固定的
1 <div id="app">
2         <div :style='{fontSize:fontSize + "px"}'>{{pmsg}}div>
3         <menu-item :parr='parr' @enlarge-text='handle($event)'>menu-item>
4 div>
 1  Vue.component('menu-item',{
 2             props:['parr'],
 3             template:`
 4                 
5
    6
  • for='(item,index) in parr'>{{item}}
  • 7
8 9 10 11
12 ` 13 }) 14 var vm = new Vue({ 15 el:'#app', 16 data:{ 17 pmsg:'父组件中内容', 18 parr:['apple','orange','banana'], 19 fontSize:10 20 }, 21 methods: { 22 handle:function(val){ 23 // 扩大字体大小 24 this.fontSize += val; 25 } 26 }, 27 })
        4.5 非父子组件间传值       1. 单独的事件中心管理组件间的通信         var eventHub = new Vue()
      2. 监听事件与销毁事件         eventHub.$on('add-todo',addTodo)         eventHub.$off('add-todo')
      3. 触发事件         eventHub.$emit('add-todo',id)    
1 <div id="app">
2         <div>父组件div>
3         <div><button @click='handle'>销毁事件button>div>
4         <test-tom>test-tom>
5         <test-jerry>test-jerry>
6     div>
 1  // 提供事件中心
 2         var hub = new Vue();
 3 
 4         Vue.component('test-tom',{
 5             data:function(){
 6                 return{
 7                     num:0
 8                 }
 9             },
10             template:`
11                 
12
TOM:{{num}}
13
14 15
16
17 `, 18 methods: { 19 handle:function(){ 20 // 触发兄弟组件的事件 21 hub.$emit('jerry-event',2); 22 } 23 }, 24 mounted:function(){ 25 // 监听事件 26 hub.$on('tom-event',(val) =>{ 27 this.num += val; 28 }); 29 } 30 }); 31 Vue.component('test-jerry',{ 32 data:function(){ 33 return{ 34 num:0 35 } 36 }, 37 template:` 38
39
JERRY:{{num}}
40
41 42
43
44 `, 45 methods: { 46 handle:function(){ 47 // 触发兄弟组件的事件 48 hub.$emit('tom-event',1); 49 } 50 }, 51 mounted:function(){ 52 // 监听事件 53 hub.$on('jerry-event',(val) =>{ 54 this.num += val; 55 }); 56 } 57 }); 58 59 var vm = new Vue({ 60 el:'#app', 61 data:{ 62 63 }, 64 methods: { 65 handle:function(){ 66 hub.$off('tom-event'); 67 hub.$off('jerry-event'); 68 } 69 }, 70 })
五、组件插槽     5.1 组件插槽的作用       父组件向子组件传递内容       hi ->            5.2 组件插槽的基本用法       1.插槽的位置         Vue.component('alert-box',{           template:`             
            Error!                          
              `         })       2.插槽的位置         Something bad happened       
1 <div id="app">
2         <alert-box>啦啦啦alert-box>
3         <alert-box>alert-box>
4 div>
 1 Vue.component('alert-box',{
 2             template:`
 3                     
4 ERROR: 5 默认内容 6
7 ` 8 }) 9 var vm = new Vue({ 10 el:'#app', 11 data:{ 12 13 } 14 })
    5.3 具名插槽用法       1.插槽定义       
        
                   
          
                   
          
                   
      
      2.插槽内容                    

标题内容

          

主要内容1

          

主要内容2

          

底部内容

        
      5.4 作用域插槽       应用场景:父组件对子组件内容进行加工处理  
vue