vue-day06

118 阅读5分钟

组件的定义:实现应用中局部功能代码和资源的集合,组件是可复用的Vue实例
一、非单文件组件(一个文件中包含有n个组件)
1、基本使用
使用组件可以将复杂的用户界面拆分为独立的、可重用的部件,每个部件负责自己的逻辑和显示。这样的模块化设计使得代码更易于维护和扩展,同时提高了开发效率。在Vue中,组件可以通过全局注册或局部注册来使用。

Vue中使用组件的三大步骤:
    一、定义组件(创建组件)
    二、注册组件
    三、使用组件(写组件标签)

    一、如何定义一个组件?
        使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也
        有点区别,区别如下:
            1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
            2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。
        备注:使用template可以配置组件结构。

    二、如何注册组件?
        1.局部注册:靠new Vue的时候传入components选项
        2.全局注册:靠Vue.component('组件名',组件)

    三、编写组件标签:
        <school></school>
局部注册组件
<body>
    <!-- 准备好一个容器-->
    <div id="root">
        <h1>{{msg}}</h1>
        <!-- 第三步:编写组件标签 -->
        <school></school>
    </div>
</body>
<script>
    //第一步:创建school组件
    const school = Vue.extend({
        // template必须有一个根节点
        template:`
            <div class="demo">
                <h2>学校名称:{{schoolName}}</h2>
                <h2>学校地址:{{address}}</h2>
                <button @click="showName">点我提示学校名</button>	
            </div>
        `,
        // el:'#root', //组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
        data(){
            return {
                schoolName:'华北理工',
                address:'北京昌平'
            }
        },
        methods: {
            showName(){
                alert(this.schoolName)
            }
        },
    })
    //创建vm
    new Vue({
        el:'#root',
        data() {
            return {
                msg:'你好'
            }
        },
        //第二步:注册组件(局部注册)
        components:{
            school,
        }
    })
</script>
全局注册组件
<body>
    <!-- 准备好一个容器-->
    <div id="root">
        <hello></hello>
    </div>
    <div id="root2">
        <hello></hello>
    </div>
</body>
<script>
    //第一步:创建hello组件
    const hello = Vue.extend({
        template:`
            <div>	
                <h2>你好啊!{{name}}</h2>
            </div>
        `,
        data(){
            return {
                name:'Tom'
            }
        }
    })
    //第二步:全局注册组件
    Vue.component('hello',hello)
    //创建vm
    new Vue({
        el:'#root',
    })

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

2、几个注意点

几个注意点:
    1.关于组件名:
        一个单词组成:
            第一种写法(首字母小写):school(<school></school>)
            第二种写法(首字母大写):School(<School></School>)
        多个单词组成:
            第一种写法(kebab-case命名):my-school(<my-school></my-school>)
            第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)(每一个单词的首字母
                                        都需要大写)(<MySchool></MySchool>)
        备注:
            (1).组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
            (2).可以使用name配置项指定组件在开发者工具中呈现的名字。
            (在创建组建的时候添加name配置项,那么在开发者工具中一直显示这个名字)

    2.关于组件标签:
        第一种写法:<school></school>
        第二种写法:<school/>
        备注:不使用脚手架时,<school/>会导致后续组件不能渲染。

    3.一个简写方式:
        const school = Vue.extend(options) 可简写为:const school = options

3、组件的嵌套(相当于vm直接管理的组件定义为app,app里面有两个组件,一个school、一个helo。school组件里面嵌套着一个student)

<body>
    <!-- 准备好一个容器-->
    <div id="root">

    </div>
</body>

<script> 
    //定义student组件
    const student = Vue.extend({
        name:'student',
        template:`
            <div>
                <h2>学生姓名:{{name}}</h2>	
                <h2>学生年龄:{{age}}</h2>	
            </div>
        `,
        data(){
            return {
                name:'张三',
                age:18
            }
        }
    })

    //定义school组件
    const school = Vue.extend({
        name:'school',
        template:`
            <div>
                <h2>学校名称:{{name}}</h2>	
                <h2>学校地址:{{address}}</h2>	
                <student></student>
            </div>
        `,
        data(){
            return {
                name:'华北理工',
                address:'北京'
            }
        },
        //注册组件(局部)
        components:{
            student
        }
    })

    //定义hello组件
    const hello = Vue.extend({
        template:`<h1>{{msg}}</h1>`,
        data(){
            return {
                msg:'欢迎来到北京!'
            }
        }
    })

    //定义app组件
    const app = Vue.extend({
        template:`
            <div>	
                <hello></hello>
                <school></school>
            </div>
        `,
        components:{
            school,
            hello
        }
    })

    //创建vm
    new Vue({
        template:'<app></app>',
        el:'#root',
        //注册组件(局部)
        components:{app}
    })
</script>

4、关于VueComponent

关于VueComponent1.school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。

    2.我们只需要写<school/>或<school></school>,Vue解析时会帮我们创建school组件的实例对象,
        即Vue帮我们执行的:new VueComponent(options)。

    3.特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!

    4.关于this指向:
            (1).组件配置中:
                data函数、methods中的函数、watch中的函数、computed中的函数
                它们的this均是【VueComponent实例对象】。
            (2).new Vue(options)配置中:
                data函数、methods中的函数、watch中的函数、computed中的函数 
                它们的this均是【Vue实例对象】。

    5.VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)。
        Vue的实例对象,以后简称vm。

5、一个重要的内置关系(P59)

1.一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype
2.为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。

补充:只要是函数,那么就有prototype(显示原型属性)
这个构造函数所构造出来的实例身上有一个__proto__(隐式原型属性)
它俩所指向的都是一个对象,这个对象成为原型对象

function Demo(){
    this.a = 1
    this.b = 2
}
//创建一个Demo的实例对象
const d = new Demo()
console.log(Demo.prototype) //显示原型属性
console.log(d.__proto__) //隐式原型属性
console.log(Demo.prototype === d.__proto__)    // true
//通过显示原型属性操作原型对象,追加一个x属性,值为99
Demo.prototype.x = 99
console.log(d.x)

二、单文件组件
1、XXXX.vue文件,经过加工和处理,变成.js文件,这样浏览器就可以解析了
2、使用脚手架来解析.vue文件
3、XXXXX.vue文件里面包含的内容

<template>
    
</template>


<script>
export default {
    
}
</script>

<style>
    
</style>

4、一个school.vue里面的内容

<template>
    <div class="demo">
        <h2>学校名称:{{name}}</h2>
        <h2>学校地址:{{address}}</h2>
        <button @click="showName">点我提示学校名</button>	
    </div>
</template>

<script>
     export default {
        name:'School',
        data(){
            return {
                name:'华北理工',
                address:'北京昌平'
            }
        },
        methods: {
            showName(){
                alert(this.name)
            }
        },
    }
</script>

<style>
    .demo{
        background-color: orange;
    }
</style>

######必须有一个App.vue,里面汇总的是所有的组件

<template>
    <div>
        <School></School>
        <Student></Student>
    </div>
</template>

<script>
    //引入组件
    import School from './School.vue'
    import Student from './Student.vue'

    export default {
        name:'App',
        // 注册
        components:{
            School,
            Student
        }
    }
</script>
引入App之后也得用上,有一个main.js(也叫做入口文件),里面的内容:
import App from './App.vue'

new Vue({
    el:'#root',
    template:`<App></App>`,
    components:{App},
})
创建一个index.html,然后引入main.js

顺序:先引入Vue.js,再引入main.js

image.png