Vue组件化

Vue组件化

注册组件的基本步骤

  1. 调用Vue.extend()方法创建组件构造器
  2. 调用Vue.component()方法注册组件
  3. 在Vue实例的作用范围内使用组件
<div id="app">
    
    <my-cpn>my-cpn>
    <my-cpn>my-cpn>
    <my-cpn>my-cpn>
div>
<script src="../js/vue.js">script>
<script>
    // 1.创建组件构造器对象
    const cpnC = Vue.extend({
        template: `
        

我是标题

我是第一行内容

我是第二行内容

`
}); // 2.注册组件 Vue.component('my-cpn', cpnC) const app = new Vue({ el: '#app', })
script>

全局组件和局部组件

  1. 全局组件可以在所有的Vue实例中使用
  2. 局部组件只能在对应的Vue实例中使用,通过实例化Vue对象的components属性
<div id="app">
    
    <my-cpn>my-cpn>
    <cpn>cpn>
div>
<script src="../js/vue.js">script>
<script>
    // 1.创建组件构造器对象
    const cpnC = Vue.extend({
        template: `
        

我是内容

`
}); // 2.注册全局组件 Vue.component('my-cpn', cpnC) const app = new Vue({ el: '#app', // 2.注册局部组件 components: { cpn: cpnC } })
script>

父组件和子组件

  1. 子组件在父组件构造器中进行注册就可在父组件的template中使用
  2. 子组件若只在父组件中注册则只能在父组件中使用
<div id="app">
    <cpn2>cpn2>
div>
<script src="../js/vue.js">script>
<script>
    // 1. 创建第一个组件构造器
    const cpnC1 = Vue.extend({
        template: `
        

标题一

11111111111111111111

`
}); // 2. 创建第二个组件构造器 const cpnC2 = Vue.extend({ template: `

标题二

22222222222222222222

`
, components: { // 注册子组件 cpn1: cpnC1 } }); // root组件 const app = new Vue({ el: '#app', components: { // 注册父组件 cpn2: cpnC2, } })
script>

组件的语法糖注册方式

<script src="../js/vue.js">script>
<script>
    // 语法糖形式注册全局组件
    Vue.component('my-cpn', {
        template: `
        

我是标题

我是第一行内容

我是第二行内容

`
}) const app = new Vue({ el: '#app', // 2.语法糖形式注册局部组件 components: { cpn: { template: `

我是标题

我是第一行内容

我是第二行内容

`
} } })
script>

组件模板的分离写法

  1. 使用script标签, 注意类型必须是text/x-template
  2. template标签
<div id="app">
    <cpn1>cpn1>
    <cpn2>cpn2>
div>

<script type="text/x-template" id="cpn1">
    <div>
        <h2>标题1</h2>
    </div>
script>

<template id="cpn2">
    <div>
        <h2>标题2h2>
    div>
template>
<script src="../js/vue.js">script>
<script>
    Vue.component(
        'cpn1', {
            template: '#cpn1'
        }
    )
    Vue.component(
        'cpn2', {
            template: '#cpn2'
        }
    )
    const app = new Vue({
        el: '#app',
    })
script>

组件中的数据存放问题

  1. 组件data必须是函数
  2. 组件中也有methods提供给组件里面使用的方法
<div id="app">
    <cpn1>cpn1>
    <cpn2>cpn2>
div>
<template id="cpn1">
    <div>
        <h2>{{title}}h2>
    div>
template>
<template id="cpn2">
    <div>
        <h2>{{title}}h2>
    div>
template>
<script src="../js/vue.js">script>
<script>
    // 全局组件
    Vue.component(
        'cpn2', {
            template: '#cpn2',
            data() {
                return {
                    title: '标题2'
                }
            }
        }
    )
    const app = new Vue({
        el: '#app',
        // 局部组件
        components: {
            'cpn1': {
                template: '#cpn1',
                data() {
                    return {
                        title: '标题1'
                    }
                }
            }
        }
    })
script>

父子组件的通信

  1. 通过props向子组件传递数据 - properties(属性)
<div id="app">
  	
    <cpn :childrenmovies="movies">cpn>
div>

<template id="cpn">
    <div>
        <ul>
          	
            <li v-for="movie in childrenmovies">{{movie}}li>
        ul>
    div>
template>

<script src="../js/vue.js">script>
<script>
    // 父传子: 通过props - 有很多种传递方式
    const cpn = {
        template: `#cpn`,
        // 1. 通过数组
        // props: ['childrenmovies']
        props: {
            // 2. 类型限制
            // childrenmovies: Array,

            // 3. 提供一些默认值以及必传值
            childrenmovies: {
                type: Array,
                default: ['1', '2', '3'],
                // required: true,
            }
        }
    }
    const app = new Vue({
        el: '#app',
        data: {
          	// 父组件的数据
            movies: ['葫芦娃', '机器猫', '海尔兄弟', '黑猫警长']
        },
        components: {
            cpn
        }
    })
script>
  1. 通过==$emit(’事件名称‘, 参数)自定义事件==向父组件发送消息

<div id="app">
    
    <cpn @itemclick="getCategoryData">cpn>
div>


<template id="cpn">
    <div>
        <button v-for="category in categories" @click="btnClink(category.id)">{{category.name}}button>
    div>
template>
<script src="../js/vue.js">script>
<script>
    // 1.子组件
    const cpn = {
        template: '#cpn',
        data() {
            return {
                categories: [
                    {id: 1, name: 'Recharge'},
                    {id: 2, name: 'SIM'},
                    {id: 3, name: 'WiFi'}
                ]
            }
        },
        methods: {
            btnClink(id) {
                // 1. 发射事件, 自定义事件
                this.$emit('itemclick', id)
            }
        }
    }

    const app = new Vue({
        el: '#app',
        data: {
            message: '你好啊'
        },
        components: {
            cpn,
        },
        methods: {
            // 3. 处理事件
            getCategoryData(id) {
                console.log(id);
                console.log('cpnClick');
            }
        }
    })
script>

父子组件的访问方式

  1. 父访问子组件有两种方式

    • $children - 数组类型,访问所有的子组件对象
    • $refs - 对象类型,默认是空对象,只有当子组件设置了ref属性才能获取到含有ref属性的所有子组件对象
    <div id="app">
        <cpn>cpn>
        <cpn ref="bbb">cpn>
        <cpn ref="ccc">cpn>
        <button @click="btnClick">按钮button>
    div>
    
    <template id="cpn">
        <div>我是子组件div>
    template>
    <script src="../js/vue.js">script>
    <script>
        const app = new Vue({
            el: '#app',
            methods: {
                btnClick() {
                    // 1. $children  数组类型, 获取所有的子组件对象
                    console.log(this.$children);
                    this.$children[0].showMessage();
                    console.log(this.$children[0].name);
    
                    // 2. $refs 很多时候用的是refs  对象类型, 默认是空对象, 获取有ref属性的子组件对象
                    console.log(this.$refs);
                    console.log(this.$refs.ccc.name);
                    console.log(this.$refs.ccc.showMessage());
                }
            },
            components: {
                cpn: {
                    template: `#cpn`,
                    data() {
                        return {
                            name: '我是子组件的name'
                        }
                    },
                    methods: {
                        showMessage() {
                            console.log('showMessage');
                        }
                    }
                }
            }
        })
    script>
    
  2. 子访问父

    • $parent 访问父组件对象
    • $root 访问跟组件对象
    <div id="app">
        <cpn>cpn>
    div>
    
    <template id="cpn">
        <div>
            <h2>我是子组件h2>
            <button @click="btnClink">按钮button>
        div>
    template>
    <script src="../js/vue.js">script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: `你好啊`
            },
            components: {
                cpn: {
                    template: `#cpn`,
                    methods: {
                        btnClink() {
                            // 1. 访问父组件 $parent
                            console.log(this.$parent);
    
                            // 2. 访问根组件 $root
                            console.log(this.$root);
                        }
                    }
                },
            }
        })
    script>
    

组件的插槽

  1. 插槽通过slot标签实现
  2. 多个插槽通过具名插槽实现对应
<div id="app">
  	
    <cpn><span slot="center">标题span>cpn>
div>
<template id="cpn">
    <div>
      	
        <slot name="left"><span>左边的插槽span>slot>
        <slot name="center"><span>中间的插槽span>slot>
        <slot name="right"><span>右边的插槽span>slot>
    div>
template>
<script src="../js/vue.js">script>
<script>
    const app = new Vue({
        el: '#app',
        components: {
            cpn: {
                template: `#cpn`,
            }
        }
    })
script>
  1. 作用域插槽
    • 使用场景:父组件替换插槽的标签,但是数据由子组件来提供。
    • 实现方式:在子组件插槽slot中自定义属性名绑定子组件中的data后,就可以在父组件中替换插槽的标签,使用template标签替换插槽标签并添加==v-slot=“slot”==属性后即可在template标签中使用slot.data的方式获取子组件的数据。
<div id="app">
    <cpn>cpn>
    <cpn>
        
        <template v-slot="slot">
            <span v-for="language in slot.languages">{{language}} - span>
            <span>{{slot.languages.join('-')}}span>
        template>
    cpn>
div>

<template id="cpn">
    <div>
        
        <slot :languages="languages">
            <ul>
                <li v-for="language in languages">{{language}}li>
            ul>
        slot>
    div>
template>
<script src="../js/vue.js">script>
<script>
    const app = new Vue({
        el: '#app',
        components: {
            cpn: {
                template: `#cpn`,
                data() {
                    return {
                        languages: ['Python', 'Java', 'JavaScript', 'Go', 'C', 'C#']
                    }
                }
            }
        }
    })
script>

你可能感兴趣的:(vue,vue)