zoukankan      html  css  js  c++  java
  • Vue 组件


    组件化开发思想:

    组件化规范:  Web Components 规范草案

    1.我们希望尽可能多的重用代码

    2.自定义组件的方式不太容易(html、css、js)

    3.多次使用组件可能导师冲突

    Web Components 通过创建封装好的功能定制元素解决上述问题。(目前并没有广泛的被浏览器所支持。)

    官网: https://developer.mozilla.org/zh-CN/docs/Web/Web_Components

    不同的功能封装到不同的组件当中,不同的组件通过组合完成特定的需求。

    Vue实现了部分上述规范。


    组件注册:

    全局组件注册语法:

    Vue.component(组件名称, {

      data: 组件数据,

      template: 组件模版内容

    })

    用法:

    <div id='app'>

      <btn></btn>

    </div>

    注意事项:

    1.data 必须是一个函数。

    2.组件模版,必须为单个根元素。

    3.组件内容可以是模版字符串。(模版字符串需要浏览提供支持,ES6语法)。

    4.组件的命名方式:如果使用驼峰命名,那么在使用组件的时候,只能在字符串模版中使用驼峰的方式使用组件,但是在普通的标签模版中,必须转换成带短横线的标签。

    案例:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 
     4 <head>
     5   <meta charset="UTF-8">
     6   <meta name="viewport" content="width=device-width, initial-scale=1.0">
     7   <meta http-equiv="X-UA-Compatible" content="ie=edge">
     8   <title>Document</title>
     9   <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    10 </head>
    11 
    12 <body>
    13 
    14   <div id='app'>
    15     <btn></btn>
    16   </div>
    17 
    18 </body>
    19 
    20 <script>
    21   // 组件注册
    22   // 定义一个名为btn的组件
    23   Vue.component('btn', {
    24     data: function () {
    25       return {
    26         count: 0
    27       }
    28     },
    29     template: '<button v-on:click="count++">点击了{{count}}次</button>'
    30   })
    31 
    32   var vm = new Vue({
    33     el: '#app',
    34     data: {
    35 
    36     }
    37   })
    38 </script>
    39 
    40 </html>

     局部组件注册:

    局部组件只能在注册他的父组件中使用

    案例:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 
     4 <head>
     5   <meta charset="UTF-8">
     6   <meta name="viewport" content="width=device-width, initial-scale=1.0">
     7   <meta http-equiv="X-UA-Compatible" content="ie=edge">
     8   <title>Document</title>
     9   <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    10 </head>
    11 
    12 <body>
    13 
    14   <div id='app'>
    15     <component-a></component-a>
    16     <component-b></component-b>
    17     <component-c></component-c>
    18   </div>
    19 
    20 </body>
    21 
    22 <script>
    23   // 局部组件注册
    24   var ComponentA = {
    25     data: function () {
    26       return {
    27         msg: 'hello A'
    28       }
    29     },
    30     template: '<button>{{msg}}</button>'
    31   }
    32   var ComponentB = {
    33     data: function () {
    34       return {
    35         msg: 'hello B'
    36       }
    37     },
    38     template: '<button>{{msg}}</button>'
    39   }
    40   var ComponentC = {
    41     data: function () {
    42       return {
    43         msg: 'hello C'
    44       }
    45     },
    46     template: '<button>{{msg}}</button>'
    47   }
    48 
    49   var vm = new Vue({
    50     el: '#app',
    51     data: {
    52 
    53     },
    54     components: {
    55       'component-a': ComponentA,
    56       'component-b': ComponentB,
    57       'component-c': ComponentC
    58     }
    59   })
    60 </script>
    61 
    62 </html>

    组件之间数据交互

    1.组件内部通过props接受传递过来的值。

    父组件向子组件传值:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 
     4 <head>
     5   <meta charset="UTF-8">
     6   <meta name="viewport" content="width=device-width, initial-scale=1.0">
     7   <meta http-equiv="X-UA-Compatible" content="ie=edge">
     8   <title>Document</title>
     9   <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    10 </head>
    11 
    12 <body>
    13   <div id='app'>
    14     <div>{{pmsg}}</div>
    15     <menu-item title='(parent-component)'></menu-item>
    16     <menu-item :title='pmsg'></menu-item>
    17   </div>
    18 </body>
    19 <script>
    20   Vue.component('menu-item',{
    21     data: function () {
    22       return {
    23         msg:'(children-component)'
    24       }
    25     },
    26     props:['title'],
    27     template:'<div>{{msg + title}}</div>'
    28   })
    29 
    30   
    31   var vm = new Vue({
    32     el: '#app',
    33     data: {
    34       pmsg:'hello word'
    35     }
    36   })
    37 </script>
    38 
    39 </html>

    props属性名规则:

    1.在props中使用驼峰形式,模版中需要使用短横线的形式。

    2.字符串形式的模版中没有这个限制。

     props属性值类型:

    1.字符串类型 string

    2.数值类型 number

    3.布尔值 boolean

    4.数组 array

    5.对象 object


    子组件向父组件传值:

    props 传递数据原则是单向数据流。

    1.子组件通过自定义事件向父组件传递信息。

     <button v-on:click='$emit("hello")'>button</button>

     2.父组件监听子组件的事件

    <menu-item v-on:hello ='count+1'></menu-item>

    案例:子组件向父组件传值,携带参数

    <button v-on:click='$emit("hello","abc123")'>button</button>

    <menu-item v-on:hello ='$event'></menu-item>


    组件之间数据交互:

    1.单独的事件中心管理组件间的通讯。

    new 一个新的Vue实例对象作为事件中心

    var eventHub = new Vue()

    2.监听事件与销毁事件

    $on 事件监听,第一参数是自定义事件的名称,第二个参数是事件函数。

    eventHub.$on('add-todo',addTodo)

    $off 事件销毁

    eventHub.$off('add-todo')

    3.触发事件

    $emit  第一个参数为自定义事件名称,第二个参数为事件函数

    eventHub.$emit('add-todo', id)

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 
     4 <head>
     5   <meta charset="UTF-8">
     6   <meta name="viewport" content="width=device-width, initial-scale=1.0">
     7   <meta http-equiv="X-UA-Compatible" content="ie=edge">
     8   <title>Document</title>
     9   <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    10 </head>
    11 
    12 <body>
    13 
    14   <div id='app'>
    15     <test-tom></test-tom>
    16     <test-jerry></test-jerry>
    17   </div>
    18 
    19 </body>
    20 
    21 <script>
    22   // 事件中心
    23   var hub = new Vue()
    24 
    25   Vue.component('test-tom', {
    26     data: function () {
    27       return {
    28         num: 0
    29       }
    30     },
    31     template: `
    32     <div>
    33         <div>Tom:{{num}}</div>
    34         <div>
    35           <button @click='handle'>点击</button>
    36         </div>
    37     </div>
    38     `,
    39     methods: {
    40       handle: function () {
    41         // 触发兄弟组件的事件
    42         hub.$emit('jerry-event', 2)
    43       }
    44     }
    45   })
    46 
    47   Vue.component('test-jerry', {
    48     data: function () {
    49       return {
    50         num: 5
    51       }
    52     },
    53     template: `
    54     <div>
    55         <div>Jerry:{{num}}</div>
    56         <div>
    57           <button @click='handle'>点击</button>
    58         </div>
    59     </div>
    60     `,
    61     methods: {
    62       handle: function () {
    63         // 触发兄弟组件的事件
    64         hub.$emit('tom-event', 5)
    65       }
    66     }
    67   })
    68 
    69   var vm = new Vue({
    70     el: '#app',
    71     mounted: function () {
    72       hub.$on('tom-event', value => {
    73         this.num += value
    74       })
    75 
    76       hub.$on('jerry-event', value => {
    77         this.num += value
    78       })
    79     }
    80   })
    81 </script>
    82 
    83 </html>

    组件插槽

    组件插槽的作用:

    父组件向子组件传递内容(类似于React 中的 this.props.children)

    1.插槽位置

    1  Vue.component('alert-box',{
    2     template:`
    3     <div>
    4       hello
    5       <slot></slot>
    6     </div>
    7     `
    8   })

    2.插槽内容

     1 <alert-box>hello</alert-box>  

     案例:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 
     4 <head>
     5   <meta charset="UTF-8">
     6   <meta name="viewport" content="width=device-width, initial-scale=1.0">
     7   <meta http-equiv="X-UA-Compatible" content="ie=edge">
     8   <title>Document</title>
     9   <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    10 </head>
    11 
    12 <body>
    13   <div id='app'>
    14     <alert-box>
    15       <alert-item></alert-item>
    16     </alert-box>
    17   </div>
    18 </body>
    19 <script>
    20   // 插槽位置
    21   Vue.component('alert-box', {
    22     template: `
    23     <div>
    24       <div>box</div>
    25       <slot></slot>
    26       <div>box</div>
    27     </div>
    28     `
    29   })
    30 
    31   Vue.component('alert-item', {
    32     template: `
    33     <div>
    34      <div>item</div>
    35     </div>
    36     `
    37   })
    38 
    39   var vm = new Vue({
    40     el: '#app',
    41     data: {
    42 
    43     }
    44   })
    45 </script>
    46 
    47 </html>

    具名插槽:自 2.6.0 起被废弃 不推荐使用

    1.插槽定义

     1  <div>
     2       <header>
     3         <slot name='header'></slot>
     4       </header>
     5       <main>
     6         <slot></slot>
     7       </main>
     8       <footer>
     9         <slot name='footer'></slot>
    10       </footer>
    11   </div>

    2.插槽内容

    1  <div>
    2     <h1 slot='header'>标题</h1>
    3 
    4     <p>内容</p>
    5     <p>内容</p>
    6     <p>内容</p>
    7 
    8     <p slot='footer'>底部</p>
    9   </div>
  • 相关阅读:
    用Jquery控制文本框只能输入数字和字母
    Math:弧度制
    python学习之案例
    python自动化模块之实践一
    python学习之路 第六天
    python学习之路 第五天
    python学习之路 第四天
    python学习之路 第三天
    python学习之路 第二天
    python学习之路 第一天
  • 原文地址:https://www.cnblogs.com/liea/p/11784330.html
Copyright © 2011-2022 走看看