• Vue组件


    Vue组件

    组件需要注册后才可以使用,注册分为全局注册和局部注册。

    全局注册

    全局注册后任何Vue实例都可以使用,子组件必须在父实例创建前注册。

    Vue.component('component-name', {
    	template: '<div>{{ message }}</div>',
        data: function () {
        	return {message: '组件内容'}
        }
    });
    

    component-name是组件的自定义标签名称,推荐使用小写字母加减号分割的形式命名。

    Vue.component方法的第二个参数是一个对象字面量,可以包含templatedatacomputedmethods等选项。其中data定义组件数据,必须是函数;template选项的值必须被一个html元素包裹

    局部注册

    app = new Vue({
    	el: '#app',
        components: {
        	'component-name': {
            	template: ''
            }
        }
    });
    

    Vue实例中使用components选项局部注册组件,注册后的组件只在该实例作用域下有效。

    组件通信

    所谓通信即组件之间传递数据,组件关系可分为父子组件通信、兄弟组件通信、跨级组件通信。

    父组件向子组件传递数据

    组件的props选项声明从父级接受的数据,props选项既可以是字符串数组也可以是对象。

    父级向子组件传递数据,可分为3步:

    1. 父组件使用子组件时,在子组件标签添加数据属性
    2. 子组件props选项声明从父级接受的数据
    3. 在子组件中应用从父级接受的数据
    <div id="app">
        <my-component message="来自父组件的数据"></my-component>
    </div>
    
    <script>
        Vue.component('my-component', {
        	template: '<div>{{ message }}</div>',
            props: ['message']
        });
        
        var app = new Vue({
        	el: '#app'
        });
    </script>
    

    props选项传入一个对象类型,对从父级接受的数据进行校验。

    子组件向父组件传递数据

    Vue通过自定义事件,实现子组件向父组件传递数据:

    1. 子组件通过$emit(eventName, eventArgument)方法触发自定义事件
    2. 父组件使用子组件时,在子组件标签使用v-on指令监听自定义事件
    <div id="app">
        <my-component @shownumber="handleShownumber"></my-component>
        <p>数值:{{ total }}</p>
    </div>
    
    <script>
        Vue.component('my-component', {
        	template: '<div @click="handleAdd"></div>',
            data : function () {
            	return {counter : 0};
            },
            methods : {
            	handleAdd: function () {
                	this.counter++;
                    this.$emit('shomnumber', this.counter);
                }
            }
        });
        
        var app = new Vue({
        	el: '#app',
            data: {
        		total: 0
        	},
            methods: {
            	handleShownumber: function (total) {
                	this.total = total;
                }
            }    
        });
    </script>
    

    可以通过v-model替代步骤2中的v-on的事件监听

    <div id="app">
        <my-component v-model="total"></my-component>
        <p>数值:{{ total }}</p>
    </div>
    
    <script>
        Vue.component('my-component', {
        	template: '<div @click="handleAdd"></div>',
            data : function () {
            	return {counter : 0};
            },
            methods : {
            	handleAdd: function () {
                	this.counter++;
                    this.$emit('shomnumber', this.counter);
                }
            }
        });
        
        var app = new Vue({
        	el: '#app',
            data: {
        		total: 0
        	}
        });
    </script>
    

    中央事件总线

    1. 创建空的Vue实例,作为中央事件总线
    2. 子组件触发事件时,指定事件发起者为中央事件总线($emit方法的调用方是中央事件总线实例)
    3. 父组件在mounted钩子函数里监听来自中央事件总线的事件
    <div id="app">
        <my-component></my-component>
        <p>数值:{{ total }}</p>
    </div>
    
    <script>
        var bus = new Vue();
        
        Vue.component('my-component', {
        	template: '<div @click="handleAdd"></div>',
            data : function () {
            	return {counter : 0};
            },
            methods : {
            	handleAdd: function () {
                	this.counter++;
                    bus.$emit('shomnumber', this.counter);
                }
            }
        });
        
        var app = new Vue({
        	el: '#app',
            data: {
        		total: 0
        	},
            mounted: function () {
                	var _this = this;
                	bus.$on('shownumber', function (total) {
                    	_this.total = total;
                    })
                }
        });
    </script>
    

    内容分发:slot

    具名插槽

    子组件模板中的<slot>标签添加name属性指定插槽名字

    <div class="container">
      <header>
        <slot name="header"></slot>
      </header>
      <main>
        <slot></slot>
      </main>
      <footer>
        <slot name="footer"></slot>
      </footer>
    </div>
    

    父组件分发的内容包裹在<template>中,使用 v-slot 指令 指定分发的插槽名字

    <base-layout>
      <template v-slot:header>
        <h1>Here might be a page title</h1>
      </template>
    
      <p>A paragraph for the main content.</p>
      <p>And another one.</p>
    
      <template v-slot:footer>
        <p>Here's some contact info</p>
      </template>
    </base-layout>
    

    <template> 元素中的所有内容都将会被传入相应的插槽。任何没有被包裹在带有 v-slot 的 <template> 中的内容都会被视为默认插槽的内容 .

    v-slot 只能添加在 <template>元素上

    作用域插槽

    父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的

    为了让父级中的插槽内容能访问子组件数据,引入作用域插槽:

    1. 子组件<slot>元素绑定子组件数据
    <span>
      <slot v-bind:user="user">
        {{ user.lastName }}
      </slot>
    </span>
    

    绑定在 <slot> 元素上的 attribute 被称为插槽 prop

    1. 父组件使用v-slot访问子组件绑定的插槽prop
    <current-user>
      <template v-slot:default="slotProps">
        {{ slotProps.user.firstName }}
      </template>
    </current-user>
    

    所有插槽prop会绑定到slotProps变量上

  • 相关阅读:
    Java后端面试题大汇总,冲刺金三银四
    面试官:小伙子,Mybatis的本质和原理说一下
    面试官问:大量的 TIME_WAIT 状态 TCP 连接,对业务有什么影响?怎么处理?
    便捷搭建 Zookeeper 服务器的方法,好用,收藏~
    10 个冷门但又非常实用的 Docker 使用技巧
    mitmproxy 抓包工具(1)
    基于alpine创建Scrapy镜像
    强大的输入框-应用快速启动uTools
    Interceptor、Filter、Servlet的区别
    利用三层判断sql数据库中编码是否已经存在(个人拙作,不喜勿喷)
  • 原文地址:https://www.cnblogs.com/weixia-blog/p/13873649.html
Copyright © 2020-2023  润新知