(day67)三、组件、组件化、组件传参

一、初识组件

(一)概念

  1. 组件就是html、css和js的集合体,通过组件可以再次复用该集合体
  2. 组件分为根组件、局部组件、全局组件

(二)特点

  1. 每一个组件都是一个Vue实例
  2. 根组件作为最顶层父组件,局部和全局组件作为子组件,也可以成为其他局部和全局组件的父组件
  3. 每个组件都有自身的模板template,根组件的模板就是挂载点,template中有且只有一个根标签
  4. 组件中的出现的所有变量,都有组件自身提供
  5. 局部组件必须注册后才能使用,全局组件不需要注册,推荐使用局部组件
  6. 子组件的数据需要隔离(通过函数让每一个组件拥有自己的独立作用域,数据组件化)

二、组件的分类

(一)根组件

  1. 根组件:new Vue()生成的组件
  2. 根组件可以不明确template,template默认采用挂载点页面结构
  3. 如果设置了template,则挂载点内部内容会被替换
  4. 因此,html和body标签不能作为挂载点
<div id="app">
    {{ msg }}
</div>
<script>
    new Vue({
    el: '#app',  // 被组件 template 模块进行替换的占位符
    data: {
        msg: '组件信息'
    },
    template: '<p>{{ msg }}</p>'
})
</script>

(二)局部组件

  1. 局部组件:let 组件名={},{}内部采用的是Vue语法
  2. 局部组件要在其父组件中注册才能使用
<div id="app">
    <div class="wrap">
        <!--3. 渲染组件-->
        <local-tag></local-tag>
        <local-tag></local-tag>
        <local-tag></local-tag>
        <local-tag></local-tag>
    </div>
</div>
<script src="js/vue.js"></script>
<script>
        // 1. 声明组件
    let localTag = {
        template: `
    <div class="box" @click="fn">
        <img src="img/001.jpg" alt="">
        <h2>美女</h2>
    </div>`,
        methods: {
            fn() {
                console.log(this)
            }
        }
    };
    
    // 2. 注册组件
    new Vue({
        el: '#app',
        data: {},
        components: {  // 注册组件
            localTag,
        }
    })
</script>

(三)全局组件

  1. 全局组件:Vue.component('组件名',{}),{}内部采用的是Vue语法
  2. 全局组件不需要注册
<div id="app">
    <div class="wrap">
        <global-tag></global-tag>
        <global-tag></global-tag>
        <global-tag></global-tag>
        <global-tag></global-tag>
    </div>
</div>
<script src="js/vue.js"></script>
<script>
    // 全局组件
    Vue.component('global-tag', {
        template: `
            <div class="box" @click="fn">
            <img src="img/002.jpg" alt="">
            <h2>大长腿</h2>
                </div>`,
        methods: {
            fn() {
                console.log(this)
            }
        }
    });
    
    // Vue实例
    new Vue({
        el: '#app',
        data: {},
    })
</script>

二、数据组件化

  1. 局部或全局取件,一个组件可能会被复用多次,每个组件都应该有自己独立的变量名称空间
  2. 可以作为方法的返回值(方法执行后会产生一个局部作用域),从而实现数据组件化
<div id="app">
    <div class="wrap">
        <local-tag></local-tag>
        <local-tag></local-tag>
        <local-tag></local-tag>
        <local-tag></local-tag>
    </div>
</div>
<script>
    let localTag = {
        template: `
        <div class="box" @click="fn">
            <img src="img/001.jpg" alt="">
            <h2>捶了美女{{ count }}下</h2>
        </div>
        `,
        data() { //局部或全局取件,一个组件可能会被复用多次,每个组件都应该有自己独立的变量名称空间
            return {
                count: 0,
            }
        }, // 数据需要组件化,作为方法的返回值(方法执行后会产生一个局部作用域)
        methods: {
            fn() {
                console.log(this);
                this.count++;
            }
        }
    };

    new Vue({
        el: '#app',
        data: {},
        components: {
            localTag,
        }
    });
</script>

三、组件的传参

(一)父传子

  1. 子组件可以通过props自定义组件属性(采用反射机制,填写字符串,但是可以直接作为变量)
  2. 子组件会在父组件中渲染,渲染时,将父组件的变量绑定给子组件的自定义属性,从而将变量值传递给子组件
<div id="app">
    <localTag :sup_data1='sup_data1' :supData2='sup_data2'></localTag>
</div>
<script type="text/javascript">
    
     let localTag = {
        props: ['dog', 'def', 'xyz'],
        props:['sup_data1', 'supdata2'],
        template: '<div>{{ sup_data1 }} {{ supdata2 }}</div>'
    };
    
    new Vue({
        el: '#app',
        data: {
            sup_data1: '数据1',
            sup_data2: '数据2'
        },
        components: {
            localTag,
        }
    })
</script>

(二)子传父

  1. 通过发送事件请求的方式进行数据传递
  2. 自定义事件是属于子组件的,子组件在父组件中渲染并绑定事件方法,事件方法由父组件实现
  3. 子组件通过this.@emit('自定义事件名',触发事件回调的参数)触发自定义事件,将参数回调给父组件的事件方法
  4. 父组件触发事件方法获得传递的参数
<div id="app">
    <global-tag @send_action='receiveAction'></global-tag>
</div>
<script type="text/javascript">
    let localTag={
         data () {
            return {
                sub_data1: "数据1",
                sub_data2: '数据2'
            }
        },
        template: '<div @click="clickAction">发生</div>',
         methods: {
            clickAction () {
                this.$emit('send_action', this.sub_data1, this.sub_data2)
            }
        }
    }
   
    new Vue({
        el: '#app',
        methods: {
            receiveAction (v1, v2) {
                console.log(v1, v2)
            }
        }
    })
</script>

猜你喜欢

转载自www.cnblogs.com/wick2019/p/12064614.html