0
点赞
收藏
分享

微信扫一扫

【Vue】快乐学习第三篇 组件及组件通信

color_小浣熊 2022-04-18 阅读 25

文章目录

什么是组件化 ❓

组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。仔细想想,几乎任意类型的应用界面都可以抽象为一个组件树:
在这里插入图片描述

组件化目的 📇

组件使用3步骤 🕒

♦️ 创建组件构造器
♦️ 注册组件
♦️ 使用组件

<body>
    <div id="app">
        <!-- 3.使用组件 -->
        <hello></hello>
        <hello></hello>
    </div>

    <script src="./vue.js"></script>

    <script>
        // 1.插件组件构造器
        const hello = Vue.extend({
            template:  `<div>
                            <h1>
                                Hello World
                            </h1>
                        </div>`
        })
        // 2.注册组件
        Vue.component('hello',hello)

        const vm = new Vue({
            el: '#app'
        })
    </script>
</body>

全局组件和局部组件 🍓

全局注册

<body>
    <div id="app">
        <!-- 3.使用组件 -->
        <hello></hello>
        <hello></hello>
    </div>
    <div id="app1">
        <hello></hello>
    </div>

    <script src="./vue.js"></script>

    <script>
        // 1.插件组件构造器
        const hello = Vue.extend({
            template:  `<div>
                            <h1>
                                Hello World
                            </h1>
                        </div>`
        })
        // 2.注册组件(全局注册,意味着可以在多个vue实例下使用)
        Vue.component('hello',hello)

        const vm = new Vue({
            el: '#app'
        })
        const vm1 = new Vue({
            el:'#app1'
        })
    </script>
</body>

局部注册

<body>
    <div id="app">
        <!-- 3.使用组件 -->
        <hello></hello>
        <hello></hello>
    </div>
    <div id="app1">
        <hello></hello>
    </div>

    <script src="./vue.js"></script>

    <script>
        // 1.插件组件构造器
        const hello = Vue.extend({
            template:  `<div>
                            <h1>
                                Hello World
                            </h1>
                        </div>`
        })
        // 2.注册组件(全局注册,意味着可以在多个vue实例下使用)


        const vm = new Vue({
            el: '#app',
            // 局部注册,只能在当前 vue 实例下使用
            components:{
                hello:hello
            }
        })
        const vm1 = new Vue({
            el:'#app1'
        })
    </script>
</body>

父子组件 🎨

<body>
<div id="app">
    <c2></c2>
</div>

<script src="./vue.js"></script>
<script>
    // 创建第一个组件
    const c1 = Vue.extend({
        template: `
        <div>
            <p>我是p1</p>
        </div>
        `
    })
    // 创建第二个组件
    const c2 = Vue.extend({
        template: `
          <div>
          <p>我是p2</p>
          <c1></c1>
          <c1></c1>
          </div>
        `,
        components: {
            c1: c1
        }
    })
    new Vue({
        el: '#app',
        data: {
            message: 'Hello World'
        },
        components: {
            c2: c2
        }
    })
</script>
</body>

在这里插入图片描述
注意如果在vue实例下写标签 c1 是不正确的,因为我们既没有全局注册 c1 组件,也没有在 vue 实例中进行注册,而是在 c2 组件内部进行了注册,作用域在 c2 组件,所以可以在 c2 的模板中使用,这一点需要注意


注册组件语法糖 🍬

<body>
<div id="app">
    <hello></hello>
</div>

<script src="./vue.js"></script>
<script>
    // 全局注册,语法糖,底层还是 extend
    Vue.component('hello',{
        template:`
        <div>
            <h1>Hello World</h1>
        </div>
        `
    })
    new Vue({
        el: '#app'
    })
</script>
</body>

在这里插入图片描述

<body>
<div id="app">
    <hello></hello>
</div>

<script src="./vue.js"></script>
<script>
    new Vue({
        el: '#app',
        components:{
            hello:{
                template:`
                    <div>
                        <h1>Hello World</h1>
                    </div>
                    `
            }
        }
    })
</script>
</body>

在这里插入图片描述

组件模板抽离的写法 ✍🏼

<body>

    <div id="app">
        <hello></hello>
        <world></world>
    </div>

    <!-- 1. 模板在script标签中写,但是类型必须是 text/x-template 类型 -->
    <script type="text/x-template" id="hello">
        <div>
            <h2>Hello Vue</h2>
        </div>
    </script>

    <!-- 2. 使用template标签 -->
    <template id="world">
        <div>
            <h2>Hello World</h2>
        </div>
    </template>

    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script>
        Vue.component('hello',{
            template:'#hello'
        })
        Vue.component('World',{
            template:'#world'
        })
        new Vue({
            el: '#app',
        })
    </script>
</body>

在这里插入图片描述


为什么组件data必须是函数 ❓

<body>

    <div id="app">
        <hello></hello>
    </div>

    <template id="hello">
        <div>
            <h2>{{hello}}</h2>
        </div>
    </template>

    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script>
        Vue.component('hello', {
            template: '#hello',
            data() {
                return {
                    hello: 'Hello World,Hello Vue.js'
                }
            }
        })

        new Vue({
            el: '#app',
        })
    </script>
</body>

在这里插入图片描述

<body>

    <div id="app">
        <counter></counter>
        <counter></counter>
        <counter></counter>
    </div>

    <template id="counter">
        <div>
            <button @click="sub">-</button>
            {{count}}
            <button @click="add">+</button>
        </div>
    </template>

    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script>
        Vue.component('counter', {
            template: '#counter',
            data() {
                return {
                    count: 0
                }
            },
            methods: {
                add() {
                    this.count++;
                },
                sub() {
                    this.count--;
                }
            },
        })

        new Vue({
            el: '#app',
        })
    </script>
</body>
<body>

    <div id="app">
        <counter></counter>
        <counter></counter>
        <counter></counter>
    </div>

    <template id="counter">
        <div>
            <button @click="sub">-</button>
            {{obj.count}}
            <button @click="add">+</button>
        </div>
    </template>

    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script>
        const obj = {
            count: 0
        }
        Vue.component('counter', {
            template: '#counter',
            data() {
                return {
                    obj
                }
            },
            methods: {
                add() {
                    this.obj.count++;
                },
                sub() {
                    this.obj.count--;
                }
            },
        })

        new Vue({
            el: '#app',
        })
    </script>
</body>

父子组件通信 父传子props ✉️

<body>

    <div id="app">
        <child :cmessage="message" :cmovies="movies"></child>
    </div>

    <template id="child">
        <div>
            <p>我是子组件</p>
            <p>{{cmessage}}</p>
            <ul>
                <li v-for="item in cmovies">{{item}}</li>
            </ul>
        </div>
    </template>

    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script>
        const child = {
            template: '#child',
            // 数组写法
            // props: ['cmessage']
            // 对象写法,还可以指定类型,
            props: {
                cmessage: {
                    // 类型
                    type: String,
                    // 默认值
                    default: '哈哈',
                    // 必须传值,否则报错
                    required: true
                },
                cmovies: {
                    type: Array,
                    default() {
                        return [];
                    }
                }
            }
        }

        new Vue({
            el: '#app',
            data: {
                message: '你好啊,子组件',
                movies: ['天气之子', '你的名字', '千与千寻']
            },
            components: {
                child
            }
        })

    </script>
</body>

在这里插入图片描述


父子组件通信 props驼峰标识 🛑

<body>
    <div id="app">
        <npm :c-npm="person"></npm>
    </div>

    <template id="npm">
        <div>
            <p>{{cNpm.width}}</p>
            <p>{{cNpm.height}}</p>
        </div>
    </template>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script>
        const npm = {
            template: '#npm',
            props: {
                cNpm: {
                    type: Object
                }
            }
        }

        new Vue({
            el: '#app',
            components: {
                npm
            },
            data: {
                person: {
                    height: 1.8,
                    width: 1.5
                }
            }
        })
    </script>
</body>

父子组件通信 子传父自定义事件 🥳

<body>
    <!-- 父组件模板 -->
    <div id="app">
        <!-- 监听自定义事件,接收到事件触发后调用aa函数 -->
        <hello @cclick="aa"></hello>
    </div>
    <!-- 子组件模板 -->
    <template id="zi">
        <div>
            <button v-for="item in shoppings" @click="btnClick(item.name)">{{item.name}}</button>
        </div>
    </template>

    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script>
        // 子组件
        const hello = {
            template: '#zi',
            data() {
                return {
                    shoppings: [
                        { id: 'a', name: '热门推荐' },
                        { id: 'b', name: '家用电器' },
                        { id: 'c', name: '数码办公' }
                    ]
                }
            },
            methods: {
                btnClick(name) {
                    // 自定义事件 cclick
                    this.$emit('cclick', name)
                }
            },
        }
        // 父组件
        new Vue({
            el: '#app',
            components: {
                hello
            },
            methods: {
                aa(name) {
                    console.log(name);
                }
            }
        })
    </script>
</body>

在这里插入图片描述

举报

相关推荐

python学习第三篇

maven篇---第三篇

第三篇:继承

MySQL篇---第三篇

openCV第三篇

寒假第三篇

【Linux】第三篇:进程

0 条评论