乐趣区

关于前端:03Vue组件机制

1. 概述

(1) 组件能够扩大 HTML 元素,外部封装了能够复用的 HTML、CSS、JS 代码片段。(2) 因为组件是可复用的 Vue 实例,所以它们与 new Vue 接管雷同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。(3) 组件相似于 vue 实例,组件外部有 template 属性,用于指定模板。vue 实例外部有 el 属性,用于指定模板。

2. 组件的特点

(1) 组件能够进行任意次数的复用
(2) 组件的 data 必须是一个函数,确保每个实例能够保护一份被返回对象的独立的拷贝,也就是任何一个组件的扭转不会影响到其余组件。

3. 组件定义

let component = {data() {
        return {
            // 返回对象值的惟一拷贝,保障复用的组件外部数据不会相互影响
            msg: "我是组件的数据"
        }
    },
    template: `
        <div>
            <p> 我是组件 </p>
            <h1>{{msg}}</h1>
        </div>
    `
}

4. 组件注册

(1) 全局注册的组件,能够在任意 vue 实例或者组件外部应用
(2) 部分注册的组件,只能在以后注册的实例或者组件外部应用
(3) 相似于 js 中的全局变量、局部变量
1、全局注册
    Vue.component('my-com', component);
    如果一个组件被多个其余组件调用,用全局注册较好。2、部分注册
    如果一个组件在一个实例或者组件外部被屡次调用,用部分注册较好。new Vue({
        el: "#app",
        data: {},
        components: {"my-com": component}
    })

5. 组件交互(通信)

(1) 父组件向子组件传参
    父组件应用 prop 属性,向子组件传参。<div id="app">
        <my-com :title="title" msg="hello"></my-com>
    </div>
    
    动静传参
        没有:传递的常量字符串
        有:传递 boolean, number, 对象, 数组, 变量
    子组件接管参数
        let component = {props: ["title", "msg"]
        }

    props 校验
        let component = {
            props: {
                title: {
                    type: String, // 验证数据类型
                    required: true, // 该参数必须传递的参数
                    // 根本数据类型间接写在 default 前面
                    default: "你好", // 以后参数的默认值
                    // 援用数据类型,应用工厂函数的模式返回一个对象或者数组
                    default(){return {}
                    }
                    validator(val){    
                        // 自定义的验证器
                        return val.lenth > 3 ;
                    }
                }
            }
        }
(2) 子组件向父组件传参
    <div id="app">
        <my-com @son-handler="fatherHandler" msg="hello"></my-com>
    </div>

    let component = {data(){
            return {comMsg: "我是子组件数据"}
        },
        template:`
            <div>
                <button @click="clickHandler"> 发送事件 </button>
            </div>
        `,
        methods: {clickHandler(){clickHandler(){this.$emit("son-handler", this.comMsg)
                }
            }
        }
    }

    new Vue({
        el: '#app',
        data: {fatherDate: ''},
        methods: {fatherHandler(val){
                //val 就是子组件发送事件时,携带的参数 this.comMsg
                this.fatherDate = val
            }
        },
        components: {myCom: component}
    })
(3) 单向数据流
    父级的 prop 数据的更新,会向下流动到子组件中,反过来不行
    父组件可能批改子组件中的数据,而子组件不能间接批改父组件中的数据
    作用:避免子组件意外变更状态,会影响父组件中的状态或者数据。

6. 插槽

(1) 一般插槽
    <my-com> hello vue </my-com>
    
    let com = {
        template: `
            <div>
                <slot></slot> // 默认插槽
            </div>
        `
    }

(2) 具名插槽
    <my-com>
        <template v-slot:header>
            我是头部内容
        </template>
        <template v-slot:default>
            <p> 你好组件插槽 </p>
        </template>
        <template v-slot:footer>
            我是脚步内容
        </template>
    </my-com>

    let com = {
        template: `
            <div>
                <header><slot name="header"></slot></header> // 具名插槽
                <main> <slot name="default"></slot > </main> // 匿名插槽
                <footer> <slot name="footer"> </slot> // 具名插槽 </footer>
            </div>
        `
    }
(3) 作用域插槽
    <my-com>
        <template v-slot:header="scope">
            {{scope.msg}} //scope 是作用域对象,外部封装了子组件传递上来的 msg 数据,能够应用对象的解构
            我是头部内容
        </template>
        <template v-slot:default>
            <h3> 你好组件插槽 </h3>
        </template>
        <template v-slot:footer> 我是脚步内容
        </template>
    </my-com>    
    
    let com = {data(){
            return {msg: "我是组件数据"}
        },
        template: `
            <div>
                <header><slot name="header" :msg="msg"></header>
            </div>
        `
    }

7. 动静组件

(1) 动态组件
    <component is="my-com1"><component>
(2) 动静组件
    <component :is="current"></component>
退出移动版