zoukankan      html  css  js  c++  java
  • Vue组件化开发

    组件注册

    • 组件
      • 组件 (Component) 是 Vue.js 最强大的功能之一
      • 组件可以扩展 HTML 元素,封装可重用的代码

    全局组件

    • 全局组件注册语法
      • Vue.component('组件名称', { }) 第1个参数是标签名称,第2个参数是一个选项对象
      • 全局组件 注册后,任何vue实例都可以用
    // 全局组件注册模板
    Vue.component(组件名称, {
        data: 组件数据,
        template: 组件模板内容,
        methods: {
            方法名: function(){
                this.组件数据
            }
        }
    })
    
    // 定义一个名为button-counter的新组件
    Vue.component('button-counter', {
        data: function(){
            return {
                count: 0
            }
        },
        template: '<button v-on:click="count++">点击了{{ count }}次.</button>'
    })
    
    • 组件注意事项
      • 组件参数的data值必须是函数同时这个函数要求返回一个对象
        • 分析函数与普通对象的对比
      • 组件模板内容必须是单个根对象
        • 具体查看特殊写法
      • 组件模板内容可以是模板字符串
        • 模板字符串需要浏览器提供支持(ES6语法)
      • 组件命名方式
        • 短横线方式
          • Vue.component('my-component',{/*...*/})
        • 驼峰方式
          • Vue.component('MyComponent',{/*...*/})
          • 如果使用驼峰方式,在使用组件时,组件调用时仍然需要短横线调用

    ``html

    ```
    <!-- 模板字符串 -->
    <section id='app'>
        <button-counter></button-counter>
        <button-counter></button-counter>
    </section>
    <script>
        Vue.component('button-counter', {
            data: function(){
                return {
                   count: 0
                }
            },
            template: `
                <div>
                    <button v-on:click="handle">点击了{{ count }}次.</button>
                    <button>测试</button>
                </div>
            `,
            methods: {
                handle: function(){
                    this.count+= 2;
                }
            }
        });
        var vm= new Vue({
            el: '#app',
            data: {
                
            }
        });
    </script>
    
    <!-- 驼峰式命名的调用 -->
    <section id='app'>
        <button-counter></button-counter>
        <button-counter></button-counter>
        <hello-world></hello-world>
    </section>
    <script>
        Vue.component('HelloWorld', {
          // 1、组件参数的data值必须是函数 
          // 同时这个函数要求返回一个对象
            data: function(){
                return {
                    msg: 'hello'
                }
            },
            template: '<div>{{ msg }}</div>'
        });
        Vue.component('button-counter', {
            data: function(){
                return {
                   count: 0
                }
            },
          //  2、组件模板必须是单个根元素
          //  3、组件模板的内容可以是模板字符串 
            template: `
                <div>
                    <button v-on:click="handle">点击了{{ count }}次.</button>
                    <button>测试</button>
                </div>
            `,
            methods: {
                handle: function(){
                    this.count+= 2;
                }
            }
        });
        var vm= new Vue({
            el: '#app',
            data: {
                
            }
        });
    </script>
    

    局部组件

    • 局部注册
      • 只能在当前注册它的vue实例中使用
    <section id="app">
        <hello-world></hello-world>
        <hello-tom></hello-tom>
        <hello-jerry></hello-jerry>
        <test-com></test-com>
    </section>
    <script>
        /*
          局部组件注册
          局部组件只能在注册他的父组件中使用
        */
        Vue.component('test-com',{
            // 全局注册
          template: '<div>Test<hello-world></hello-world></div>'
        });
        var HelloWorld = {
            // 局部组件的模板定义
          data: function(){
            return {
              msg: 'HelloWorld'
            }
          },
          template: '<div>{{msg}}</div>'
        };
        var HelloTom = {
          data: function(){
            return {
              msg: 'HelloTom'
            }
          },
          template: '<div>{{msg}}</div>'
        };
        var HelloJerry = {
          data: function(){
            return {
              msg: 'HelloJerry'
            }
          },
          template: '<div>{{msg}}</div>'
        };
        var vm = new Vue({
          el: '#app',
          data: {
            
          },
          components: {
              // 局部组件注册的定义
            'hello-world': HelloWorld,
            'hello-tom': HelloTom,
            'hello-jerry': HelloJerry
          }
        });
    </script>
    

    Vue组件之间传值

    父组件向子组件传值

    • 父组件向子组件传值

      • 父组件发送的形式是以属性的形式绑定值到子组件身上
      • 然后子组件用属性props接收
      • props中使用驼峰形式,
      • 模板中需要使用短横线的形式
      • 字符串形式的模板中没有这个限制
    • 父组件向子组件传值-基本使用

      • 组件中props数组内为模板解析标签内的属性名
      • 若没有v-bind绑定,传递的数据为直接数据,数据类型为字符串
      • 若有v-bind绑定,传递的数据为顶层组件中的数据。数据类型为基本类型
    <section id="app">
      <div>{{pmsg}}</div>
        <!--1、menu-item  在 APP中嵌套着 故 menu-item   为  子组件      -->
        <!-- 给子组件传入一个静态的值 -->
      <menu-item title='来自父组件的值'></menu-item>
      <!-- 2、 需要动态的数据的时候 需要属性绑定的形式设置 此时 ptitle  来自父组件data 中的数据 . 
        传的值可以是数字、对象、数组等等
    -->
      <menu-item :title='ptitle' content='hello'></menu-item>
    </section>
    <script type="text/javascript">
      Vue.component('menu-item', {
        // 3、 子组件用属性props接收父组件传递过来的数据  
        props: ['title', 'content'],
        data: function() {
          return {
            msg: '子组件本身的数据'
          }
        },
        template:  `<div>
                    {{ msg }}<br>
                    {{ title }}<br>
                    {{ content }}
                </div>`
      });
      var vm = new Vue({
        el: '#app',
        data: {
          pmsg: '父组件中内容',
          ptitle: '动态绑定属性'
        }
      });
    </script>
    
    • 父组件向子组件传值-命名规则
      • HTML大小写敏感,所以HTML中的命名只能是横线式的
      • 在props中使用驼峰形式,模板中需要使用短横线的形式
      • 传值规则:顶层组件的数据向次级组件的props属性传值,然后在解析的HTML页面中进行数据绑定,以期完成数据传递
        • Javascript中驼峰式:props: ['menuTitle']
        • HTML中短横线:<menu-item v-bind:menu-title='ptitle'></menu-item>
    <section id="app">
        <div>{{ pmsg }}</div>
        <menu-item v-bind:menu-title='ptitle'></menu-item>
    </section>
    <script type="text/javascript">
        /*  父组件向子组件传值-props属性名规则  */
        Vue.component('third-com', {
            props: ['testTitle'],
            template: `<div>
                    {{ testTitle }}
                </div>`
        });
        Vue.component('menu-item', {
            props: ['menuTitle'],
            template: `<div>
                {{ menuTitle }}
                <third-com testTitle='hello'></third-com>
                </div>`
        });
        var vm= new Vue({
            el: '#app',
            data: {
                pmsg: '父组件中的内容',
                ptitle: '父组件动态绑定属性'
            },
        });
    </script>
    
    • 父组件向子组件传值-传值类型
      • 字符串 String
      • 数值 Number
      • 布尔值 Boolean
      • 数组 Array
      • 对象 Object
    <section id="app">
        <div>{{ pmsg }}</div>
        <menu-item :pstr='pstr' :pnum='12' pboo='true' :parr='parr' :pobj='pobj'></menu-item>
    </section>
    <script type="text/javascript">
        /*  父组件向子组件传值-传值类型  */
        Vue.component('menu-item', {
          props: ['pstr','pnum','pboo','parr','pobj'],
          template: `
            <div>
              <div>{{pstr}}</div>
              <div>{{12 + pnum}}</div>
              <div>{{typeof pboo}}</div>
              <ul>
                <li :key='index' v-for='(item,index) in parr'>{{item}}</li>
              </ul>
                <span>{{pobj.name}}</span>
                <span>{{pobj.age}}</span>
              </div>
            </div>
          `
        });
        var vm = new Vue({
          el: '#app',
          data: {
            pmsg: '父组件中内容',
            pstr: 'hello',
            parr: ['apple','orange','banana'],
            pobj: {
              name: 'lisi',
              age: 12
            }
          }
        });
    </script>
    

    子组件向父组件传值

    • 子组件向父组件传值
      • 子组件可以使用$emit触发父组件的自定义事件
      • vm.$emit( event, arg ) 第一个参数为 自定义的事件名称,第二个参数为需要传递的数据,触发当前实例上的事件
      • vm.$on( event, fn ) 父组件用v-on监听子组件的事件
      • props传递数据原则:单向数据流
    <section id="app">
        <div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div>
        <menu-item :parr='parr' @enlarge-text='handle'></menu-item>
    </section>
    <script type="text/javascript">
        /*  子组件向父组件传值-基本用法  */
        Vue.component('menu-item', {
          props: ['parr'],
          template: `
            <div>
              <ul>
                <li :key='index' v-for='(item,index) in parr'>{{item}}</li>
              </ul>
              <button @click='$emit("enlarge-text")'>扩大父组件中字体大小</button>
              <button @click='$emit("enlarge-text, 10")'>扩大父组件中字体大小</button>
            </div>
          `
        });
        var vm = new Vue({
          el: '#app',
          data: {
            pmsg: '父组件中内容',
            parr: ['apple','orange','banana'],
            fontSize: 10
          },
          methods: {
            handle: function(){
              // 扩大字体大小
              this.fontSize += 5;
            }
          }
        });
    </script>
    

    兄弟组件之间数据传递

    • 兄弟组件之间数据传递
      • 兄弟之间传递数据需要借助于事件中心,通过事件中心传递数据
        • 提供事件中心var hub = new Vue()
      • 传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据)
      • 接收数据方,通过mounted(){}钩子中,触发hub.$on()方法名
      • 销毁事件 通过hub.$off()方法名销毁之后无法进行传递数据
    <section id="app">
        <div>父组件</div>
        <div>
          <button @click='handle'>销毁事件</button>
        </div>
        <test-tom></test-tom>
        <test-jerry></test-jerry>
    </section>
    <script type="text/javascript">
        /*  兄弟组件之间数据传递  */
        var hub = new Vue();
        Vue.component('test-tom', {
            data: function(){
                return {
                    num: 0
                }
            },
            template: `
                <div>
                    <div>TOM:{{num}}</div>
                    <div>
                        <button @click='handle'>点击</button>
                    </div>
                </div>
            `,
            methods: {
                handle: function(){
                    hub.$emit('jerry-event', 2);
                }
            },
            mounted: function() {
                // 监听事件
                hub.$on('tom-event', (val) => {
                    this.num += val;
                });
            }
            });
            Vue.component('test-jerry', {
            data: function(){
                return {
                num: 0
                }
            },
            template: `
                <div>
                    <div>JERRY:{{num}}</div>
                    <div>
                        <button @click='handle'>点击</button>
                    </div>
                </div>
            `,
            methods: {
                handle: function(){
                // 触发兄弟组件的事件
                hub.$emit('tom-event', 1);
                }
            },
            mounted: function() {
                // 监听事件
                hub.$on('jerry-event', (val) => {
                    this.num += val;
                });
            }
            });
            var vm = new Vue({
            el: '#app',
            data: {
                
            },
            methods: {
                handle: function(){
                    hub.$off('tom-event');
                    hub.$off('jerry-event');
                }
            }
        });
    </script>
    

    组件插槽

    • 组件插槽

      • 组件的最大特性就是复用性,而用好插槽能大大提高组件的可复用能力
    • 匿名插槽

      • 当组件渲染的时候,这个 <slot> 元素将会被替换为“组件标签中嵌套的内容”。
      • 插槽内可以包含任何模板代码,包括 HTML
    <section id="app">
      <!-- 这里的所有组件标签中嵌套的内容会替换掉slot  如果不传值 则使用 slot 中的默认值  --> 
        <alert-box>有bug发生</alert-box>
        <alert-box>有一个警告</alert-box>
        <alert-box></alert-box>
    </section>
    <script type="text/javascript">
        /*  组件插槽:父组件向子组件传递内容  */
        Vue.component('alert-box', {
          template: `
            <div>
              <strong>ERROR:</strong>
              
              <slot>默认内容</slot>
            </div>
          `
        });
        var vm = new Vue({
          el: '#app',
          data: {
            
          }
        });
    </script>
    
    • 具名插槽
      • 具有名字的插槽
      • 使用 <slot> 中的 "name" 属性绑定元素
      • 具名插槽的渲染顺序,完全取决于模板,而不是取决于父组件中元素的顺序
    <section id="app">
      <base-layout>
      <p slot='header'>标题信息</p>
      <p>主要内容1</p>
      <p>主要内容2</p>
      <p slot='footer'>底部信息信息</p>
    </base-layout>
    <base-layout>
      <template slot='header'>
        <p>标题信息1</p>
        <p>标题信息2</p>
      </template>
      <p>主要内容1</p>
      <p>主要内容2</p>
      <template slot='footer'>
        <p>底部信息信息1</p>
        <p>底部信息信息2</p>
      </template>
    </base-layout>
    </section>
    <script type="text/javascript">
      /*  具名插槽  */
      Vue.component('base-layout', {
        template: `
          <div>
            <header>
              <slot name='header'></slot>
            </header>
            <main>
              <slot></slot>
            </main>
            <footer>
              <slot name='footer'></slot>
            </footer>
          </div>
        `
      });
      var vm = new Vue({
        el: '#app',
        data: {
          
        }
      });
    </script>
    
    • 作用域插槽

      • 父组件对子组件加工处理
      • 既可以复用子组件的slot,又可以使slot内容不一致
    • 作用域插槽的应用

      • 当我们希望li 的样式由外部使用组件的地方定义,因为可能有多种地方要使用该组件, 但样式希望不一样 这个时候我们需要使用作用域插槽
      • 父组件中使用了<template>元素,而且包含scope="slotProps",slotProps在这里只是临时变量
      • 在子组件模板中,<slot>元素上有一个类似props传递数据给组件的写法msg="xxx"
      • 插槽可以提供一个默认内容,如果如果父组件没有为这个插槽提供了内容,会显示默认的内容。
      • 如果父组件为这个插槽提供了内容,则默认的内容会被替换掉
    <section id="app">
      <fruit-list :list='list'>
        <template slot-scope='slotProps'>
          <strong v-if='slotProps.info.id==3' class="current">{{slotProps.info.name}}</strong>
          <span v-else>{{slotProps.info.name}}</span>
        </template>
      </fruit-list>
    </section>
    <script type="text/javascript">
      /*  作用域插槽  */
      Vue.component('fruit-list', {
          props: ['list'],
          template: `
            <div>
              <li :key='item.id' v-for='item in list'>
                <slot :info='item'>{{item.name}}</slot>
              </li>
            </div>
          `
        });
      var vm = new Vue({
          el: '#app',
          data: {
            list: [{
              id: 1,
              name: 'apple'
            },{
              id: 2,
              name: 'orange'
            },{
              id: 3,
              name: 'banana'
            }]
          }
        });
    </script>
    
  • 相关阅读:
    Centos7 下安装python3及卸载
    centos python3 的 卸载 删除
    Centos7安装python3和pip3(一)
    python升级带来的yum异常(解决错误File "/usr/bin/yum", line 30 except KeyboardInterrupt, e:)
    python 错误信息是:sudo :apt-get:command not found
    优化页面访问速度(四) ——前端优化
    优化页面访问速度(三) ——服务端优化
    优化页面访问速度(二) ——数据库优化
    优化页面访问速度(一)——综述
    Redis专题——Redis管理工具
  • 原文地址:https://www.cnblogs.com/SharkJiao/p/13624705.html
Copyright © 2011-2022 走看看