前端小白入门Vue之组件


前言

组件作为Vue非常重要的思想,今天我们就一起来学习如何使用Vue中的组件


提示:以下是本篇文章正文内容,下面案例可供参考

一、什么是组件?

当我们遇到负责问题的时候,我们一般采取的解决方法是,将问题进行拆解。
Vue中的组件也是利用这种思想,将页面进行拆解,拆解成组件,把页面拆解成大组件,大组件拆解成小组件,最后形成一颗:组件树

二、组件的使用步骤

1.创建组件构造器
2.注册组件
3.使用组件

<div id="app">
        <!-- 3.使用组件 -->
        <my-cpn></my-cpn>
    </div>
    <script>
        // 1. 创建组件构造器对象
        const cpnC = Vue.extend({
                template: `
                <div>
                    <h1>我是标题</h1>
                    <p>我是内容</p>
                </div>
            `
            })
            // 2.注册组件
        Vue.component(`my-cpn`, cpnC)
        const app = new Vue({
            el: "#app",
            data: {
                message: "hello world"
            }
        })
    </script>

显示内容如下:
在这里插入图片描述

三、全居组件和局部组件

    <div id="app">
        <cpn></cpn>
        <cpn></cpn>
        <cpn></cpn>
    </div>
    <script>
        // 1.创建组件构造器
        const cpnC = Vue.extend({
                template: `
                    <div>
                        <h1>我是标题</h1>
                        <p>我是内容</p>
                    </div>`

            })
            // 2.在这里注册的组件(全局组件,意味着可以在多个Vue的实例下面使用)
            // Vue.component("my-can", can)
        const app = new Vue({
            el: "#app",
            data: {
                message: "hello world"
            },
            // 3.在这里注册的组件(局部组件,只能在这个Vue实例里面进行使用)
            components: {
                cpn: cpnC
            }
        })
    </script>

运行结果如下:
在这里插入图片描述

四、父组件和子组件的区别

注意:组件再使用之前就被编译好了

    <div id="app">
        <cpn2></cpn2>
    </div>
    <script>
        // 1.创建第一个组件(子组件)
        const cpnC1 = Vue.extend({
                template: `
                <div>
                    <h1>这个是标题1</h1>
                    <p>这个是标题的内容</p>
                </div>`
            })
            // 2.创建第二个组件(父组件)
        const cpnC2 = Vue.extend({
            template: `
                <div>
                    <h1>这个是标题2</h1>
                    <p>这个是标题的内容</p>
                    // 使用第一个组件
                    <cpn1></cpn1>
                </div>`,
            components: {
                // 对第一个组件进行注册
                cpn1: cpnC1
            }
        })
        // root组件
        const app = new Vue({
            el: "#app",
            data: {
                message: "hello world"
            },
            components: {
                // 对第二个组件进行注册
                cpn2: cpnC2
            }
        })
    </script>

运行结果如下:
在这里插入图片描述

五、注册组件语法糖的写法

Vue为了简化过程,提供了注册的语法糖
省去了调用Vue.extend()的步骤,而是可以直接使用一个对象来代替

    <div id="app">
        <cpn1></cpn1>
        <cpn2></cpn2>
    </div>
    <script>
        // 1.全局组件注册的语法糖
        Vue.component(`cpn1`, {
            template: `
                <div>
                    <h1>这个是标题1</h1>
                    <p>这个是标题的内容</p>
                </div>`
        })
        const app = new Vue({
            el: "#app",
            data: {
                message: "hello world"
            },
            components: {
                // 2.注册局部组件的语法糖
                'cpn2': {
                    template: `
                        <div>
                            <h1>这个是标题2</h1>
                            <p>这个是标题的内容</p>
                        </div>`
                }
            }
        })
    </script>

运行结果如下:
在这里插入图片描述

六、组件模板分离的方法

1.使用script的方法来分离
2.使用template的方法来分离

    <div id="app">
        <cpn1></cpn1>
    </div>
    <!-- 第一种分离组件模板的方法-script -->
    <script type="text/x-template" id="cpn">
        <div>
            <h1>我是标题1</h1>
            <p>我是内容</p>
        </div>
    </script>
    <!-- 第二中分离组件模板的方法-template -->
    <template id="cpn">
        <div>
            <h1>我是标题1</h1>
            <p>我是内容</p>
        </div>
    </template>
    <script>
        Vue.component(`cpn1`, {
            template: `#cpn`
        })
        const app = new Vue({
            el: "#app",
            data: {
                message: "hello world"
            }
        })
    </script>

七、为什么组件中data必须要是一个函数

1.组件对象也有一个data属性(也可以有methods属性)
2.data属性必须是一个函数
3.而且这个函数返回一个对象,对象内部保存着数据
原因:函数每次调用都会创建一个新的对象

    <div id="app">
        <cpn></cpn>
    </div>
    <template id="cpn">
        <!-- 必须用一个div包含 -->
        <div>
            <h1>当前的计数为:{{count}}</h1> 
            <button @click="increment">+</button>
            <button @click="decrement">-</button>
        </div>
    </template>
    <script>
        // 创建一个能计数的组件
        Vue.component(`cpn`, {
            template: `#cpn`,
            data() {
                return {
                    count: 0
                }
            },
            methods: {
                increment() {
                    this.count++
                },
                decrement() {
                    this.count--
                }
            }
        })
        const app = new Vue({
            el: "#app",
            data: {
                message: "hello world"
            }
        })
    </script>

八、组件之间的通信(父传子)

1.子组件不能直接引用父组件或者Vue实例的数据
2.使用props->propertles(属性)
3.props的数据验证

    <div id="app">
        <!-- 使用v-bind才会他变成一个变量 -->
        <cpn :cmovies="movies" :cmessage="message"></cpn>
    </div>
    <template id="cpn">
        <div>
            <p v-for="item in cmovies">{{item}}</p>
            <h2>{{cmessage}}</h2>
        </div>
    </template>
    <script>
        const cpn = {
            template: '#cpn',
            props: ['cmovies', 'cmessage'],
            data() {
                return {}
            },
            methods: {}
        }
        const app = new Vue({
            el: "#app",
            data: {
                message: "hello world",
                movies: ['海王', '海贼王', '海尔兄弟']
            },
            components: {
                cpn
            }
        })
    </script>

props中的数据验证:

    <div id="app">
        <!-- 使用v-bind才会他变成一个变量 -->
        <cpn :cmovies="movies" :cmessage="message"></cpn>
    </div>
    <template id="cpn">
        <div>
            <p v-for="item in cmovies">{{item}}</p>
            <h2>{{cmessage}}</h2>
        </div>
    </template>
    <script>
        const cpn = {
            template: '#cpn',
            // props: ['cmovies', 'cmessage'],
            props: {
                // 类型有String\Number\Boolean\Array\Object\Date\Function\Symbol
                // 1.类型限制
                cmovies: Array, //必须为数组
                cmessage: String, //必须为字符串
                // 2.提供一些默认值,必须传得值
                cmessage: {
                    type: String,
                    default: "默认值", //再没有传值得时候提供的默认值
                    required: true //必须传得值
                },
                // 类型是对象或数组时,默认值必须时一个函数
                cmovies: {
                    type: Array,
                    default () {
                        return []
                    }
                }
            },
            data() {
                return {}
            },
            methods: {}
        }
        const app = new Vue({
            el: "#app",
            data: {
                message: "hello world",
                movies: ['海王', '海贼王', '海尔兄弟']
            },
            components: {
                cpn
            }
        })
    </script>

九、父子组件通信-props驼峰标识

    <div id="app">
        <!-- v-bind在这里不支持驼峰,需要用-隔开 -->
        <cpn :c-info="info"></cpn>
    </div>
    <template id="cpn">
        <div>
            <h2>{{cInfo}}</h2>
        </div>
    </template>
    <script>
        const cpn = {
            template: `#cpn`,
            props: {
                cInfo: {
                    type: Object,
                    default () {
                        return {}
                    }
                }
            }
        }
        const app = new Vue({
            el: "#app",
            data: {
                message: "hello world",
                info: {
                    name: "xxx",
                    age: 18,
                    height: 1.88
                }
            },
            components: {
                cpn
            }
        })
    </script>

十、组件之间的通信(子传父)

1.通过事件向父组件发送消息
this.$emit(事件名,事件参数)

    <div id="app">
        <cpn v-on:item-click="cpnClick"></cpn>
    </div>
    <!-- 子组件模板 -->
    <template id="cpn">
        <div>
           <button @click="btnClick(item)" v-for="item in categories">{{item.name}}</button> 
        </div>
    </template>
    <script>
        const cpn = {
            template: `#cpn`,
            data() {
                return {
                    categories: [{
                        id: "aaa",
                        name: '热门推荐'
                    }, {
                        id: "bbb",
                        name: '手机家电'
                    }, {
                        id: "ccc",
                        name: '新鲜水果'
                    }, {
                        id: "ddd",
                        name: '米面粮油'
                    }]
                }
            },
            methods: {
                btnClick(item) {
                    // 发射事件,自定义事件
                    this.$emit('item-click', item)
                }
            }
        }
        const app = new Vue({
            el: "#app",
            data: {
                message: "hello world"
            },
            components: {
                cpn
            },
            methods: {
                // 监听我们按钮的事件
                cpnClick(item) {
                    console.log(item)
                }
            }
        })
    </script>

总结

小编也还在继续跟着B站:ilovecoding 老师一起学习
组件的通信主要是多打,理解其中的代码,理解来去的方法和其中的规则

今日推荐

工具:求字体网,将需要识别字体的图片上传上去,能够识别出字体

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值