• Vue组件理解及非单文件组件


    对组件的理解

    传统前端编程(有Vue之前)存在的问题:

    依赖混乱,不易维护、代码复用率不高

    在这里插入图片描述

    组件化:

    提高服用率、依赖关系清晰

    在这里插入图片描述

    所有组件归一个vm管,组件可以嵌套

    在这里插入图片描述

    组件的定义:实现应用中局部功能代码资源集合

    • 模块:一个js文件
    • 组件:集合
    • 模块化:拆开js
    • 组件化:不同功能不同组件

    创建组件

    非单文件组件:

    一个文件中包含有n个组件。

    基本使用

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>组件基本使用title>
        <script src="../js/vue.js">script>
    head>
    <body>
        <div id="root">
            <h2>学校名称: {{schoolName}}h2>
            <h2>学校地址:{{address}}h2>
            <hr>
            <h2>学生姓名: {{studentName}}h2>
            <h2>学生年龄:{{age}}h2>
        div>
    body>
    <script>
        Vue.config.productionTip = false
        // 创建school组件
        const school = Vue.extend({
            el:'#root',
            data:{
                schoolName:'尚硅谷',
                address:'北京昌平',
                studentName:'张三',
                age:18,
            },
        })
    script>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    在这里插入图片描述

    组件不指定为谁服务
    组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。

    创建组件三步

    1. 创建组件
    2. 注册组件
    3. 使用组件
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>组件基本使用title>
        <script src="../js/vue.js">script>
    head>
    <body>
        <div id="root">
            <h2>{{ msg }}h2>
            <hr>
            <xuexiao>xuexiao>
            <hr>
            <xuesheng>xuesheng>
        div>
    body>
    <script>
        Vue.config.productionTip = false
        // 第一步:创建school组件
        const school = Vue.extend({
            // 根只能有一个标签
            template:`
                

    学校名称: {{schoolName}}

    学校地址:{{address}}

    `
    , // el:'#root', // 组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。 data(){ return { schoolName:'尚硅谷', address:'北京昌平' } } }) // 第一步:创建student组件 const student = Vue.extend({ template:`

    学生姓名: {{studentName}}

    学生年龄:{{age}}

    `
    , data(){ return { studentName:'张三', age:12 } } }) // 创建vm new Vue({ el:'#root', data:{ msg:'你好啊!', }, // 第二步:注册组件(局部注册) components:{ xuexiao:school, xuesheng:student } })
    script> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    在这里插入图片描述

    在这里插入图片描述

    学生同理了。

    局部注册与全局注册

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>组件基本使用title>
        <script src="../js/vue.js">script>
    head>
    <body>
        <div id="root">
            <hello>hello>
            <h2>{{ msg }}h2>
            <hr>
            
            <school>school>
            <hr>
            
            <student>student>
            <student>student>
        div>
        <div id="root2">
            <hello>hello>
            <student>student>
        div>
    body>
    <script>
        Vue.config.productionTip = false
        // 第一步:创建school组件
        const school = Vue.extend({
            // 根只能有一个标签
            template:`
                

    学校名称: {{schoolName}}

    学校地址:{{address}}

    `
    , // el:'#root', // 组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。 data(){ return { schoolName:'尚硅谷', address:'北京昌平' } } }) // 第一步:创建student组件 const student = Vue.extend({ template:`

    学生姓名: {{studentName}}

    学生年龄:{{age}}

    `
    , data(){ return { studentName:'张三', age:12 } } }) // 第一步:创建hello组件 const hello = Vue.extend({ template:`

    你好啊:{{ name }}

    `
    , data(){ return { name:'Tom', } }, }) //第二步:全局注册组件 Vue.component('hello',hello) // 创建vm new Vue({ el:'#root', data:{ msg:'你好啊!', }, // 第二步:注册组件(局部注册) components:{ school, //简写 student } }) new Vue({ el:'#root2', components:{ student, } })
    script> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95

    总结:
    Vue中使用组件的三大步骤:

    1. 定义组件(创建组件)

    2. 注册组件

    3. 使用组件(写组件标签)

    4. 如何定义一个组件?

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

      1. 局部注册:靠new Vue的时候传入components选项
      2. 全局注册:靠Vue.component(‘组件名’,组件)
    6. 编写组件标签:

    几个注意点

    1. 组件同名可以简写为一个名字。
    2. 定义组件时,可以使用正常写法和简写。以后编程中一般是简写形式居多。
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>几个注意点title>
        <script src="../js/vue.js">script>
    head>
    <body>
        <div id="root">
            <h1>{{msg}}h1>
            <school>school>
            
        div>
    body>
    <script>
        Vue.config.productionTip = false
        // 定义组件(简写形式)
        const s = {
            // name:'atguigu',
            template:`
                

    学校名称: {{name}}

    学校地址:{{address}}

    `
    , data(){ return { name:'尚硅谷', address:'北京', } }, } // 定义组件(正常形式) // const s = Vue.extend({ // // name:'atguigu', // template:` //
    //

    学校名称: {{name}}

    //

    学校地址:{{address}}

    //
    // `, // data(){ // return { // name:'尚硅谷', // address:'北京', // } // }, // }) new Vue({ el:'#root', data:{ msg:'欢迎学习vue' }, components:{ school:s, } })
    script> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    1. 关于组件名:
      • 一个单词组成:
        1. 第一种写法(首字母小写):school
        2. 第二种写法(首字母大写):School
      • 多个单词组成:
        1. 第一种写法(kebab-case命名):my-school
        2. 第二种写法(CamelCase命名):MySchool(需要Vue脚手架支持)
      • 备注:
        1. 组件名尽可能回避HTML中已有的元素名称,如:h2、H2都不行。
        2. 可以使用name配置项指定组件在开发者工具中呈现的名字。
    2. 关于组件标签:
      1. 第一种写法:
      2. 第二种写法:
      • 备注:不使用脚手架时,会导致后续组件不能渲染。
    3. 一个简写的方式:
      • const school = Vue.extend(options) 可简写为:const school = options

    组件的嵌套

    一般项目的Root下只管理一个app组件,由App组件管理多个其它子组件。

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>组件嵌套title>
        <script src="../js/vue.js">script>
    head>
    <body>
        <div id="root">
        div>
    body>
    <script>
        Vue.config.productionTip = false
    
        // 定义student组件
        const student = {
            template:`
                

    学生姓名: {{name}}

    年龄:{{age}}

    `
    , data(){ return { name:'尚硅谷', age:18, } }, } // 定义school组件 const school = { // name:'atguigu', template:`

    学校名称: {{name}}

    学校地址:{{address}}

    `
    , data(){ return { name:'尚硅谷', address:'北京', } }, // 注册组件(局部) components:{ student } } // 定义hello组件 const hello = { template:`

    欢迎来到你屋里

    `
    , } // 定义app组件 const app = Vue.extend({ template:`
    `
    , components:{ school, hello } }) //创建vm new Vue({ template:`
    `
    , el:'#root', //注册组件(局部) components:{app} })
    script> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    VueComponent

    一、school的本质到底是什么?

    数据类型??

    输出一下school看看是什么

    在这里插入图片描述

    是构造函数,代码里没有显式调用new VueComponent(),但是在源码中调用了这个构造函数。

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

    2.我们只需写,Vue解析时会帮我们创建school组件的实例对象(组件是构造函数,构造函数可以有实例对象),即Vue帮我们执行了:new VueComponent(options)

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>VueComponenttitle>
        <script src="../js/vue.js">script>
    head>
    <body>
        <div id="root">
            <school>school>
        div>
    body>
    <script>
        Vue.config.productionTip = false
        // 定义school组件
        const school = Vue.extend({
            name:'school',//组件想要显示在开发者工具里边的名字
            template:`
                

    学校名称: {{name}}

    学校地址:{{address}}

    `
    , data(){ return { name:'尚硅谷', address:'北京', } }, }) console.log('@',school) //创建vm new Vue({ el:'#root', components:{school}, })
    script> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

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

    在这里插入图片描述

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>VueComponenttitle>
        <script src="../js/vue.js">script>
    head>
    <body>
        <div id="root">
            <school>school>
            <hello>hello>
        div>
    body>
    <script>
        Vue.config.productionTip = false
    
        // 定义school组件
        const school = Vue.extend({
            name:'school',//组件想要显示在开发者工具里边的名字
            template:`
                

    学校名称: {{name}}

    学校地址:{{address}}

    `
    , data(){ return { name:'尚硅谷', address:'北京', } }, }) // 定义hello组件 const hello = Vue.extend({ template:`

    {{msg}}

    `
    , data(){ return { msg:'你好啊!' } } }) console.log('@',school) console.log('#',school) //创建vm const vm = new Vue({ el:'#root', components:{school,hello}, })
    script> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    判断school和hello是不是相同的?不同!

    console.log('@',school===hello)
    
    • 1

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

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

    问:如何能体现vm在管理着vc呢?看 vm中的children属性。

    在这里插入图片描述

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>VueComponenttitle>
        <script src="../js/vue.js">script>
    head>
    <body>
        <div id="root">
            <school>school>
            <hello>hello>
        div>
    body>
    <script>
        Vue.config.productionTip = false
        const school = Vue.extend({
            name:'school',
            template:`
                

    学校名称: {{name}}

    学校地址:{{address}}

    `
    , data(){ return { name:'尚硅谷', address:'北京', } }, }) const hello = Vue.extend({ template:`

    {{msg}}

    `
    , data(){ return { msg:'你好啊!' } } }) new Vue({ el:'#root', components:{school,hello}, })
    script> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    子组件中的子组件:

    在这里插入图片描述

    在这里插入图片描述

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>VueComponenttitle>
        <script src="../js/vue.js">script>
    head>
    <body>
        <div id="root">
            <school>school>
            <hello>hello>
        div>
    body>
    <script>
        Vue.config.productionTip = false
        const school = Vue.extend({
            name:'school',
            template:`
                

    学校名称: {{name}}

    学校地址:{{address}}

    `
    , data(){ return { name:'尚硅谷', address:'北京', } }, }) const test = Vue.extend({ template:`test子组件` }) const hello = Vue.extend({ template:`

    {{msg}}

    `
    , data(){ return { msg:'你好啊!' } }, components:{test} }) new Vue({ el:'#root', components:{school,hello}, })
    script> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    一个重要的内置关系

    vm可以指定el,为哪个容器服务。vm不能指定el(报错),vc只能跟着大哥vm混。另外data配置项,vc只能写成函数式,vm都可以。


    函数身上的prototype(显式原型属性)和对象身上的__proto__(隐式原型属性)都指向了一个对象(原型对象)。

    在这里插入图片描述

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>一个重要的内置关系title>
        <script src="../js/vue.js">script>
    head>
    <body>
        <div id="root">
        div>
    body>
    <script>
        Vue.config.productionTip = false
        // 定义一个构造函数
        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__)
        // 程序员通过显示原型属性操作原型对象,追加一个x属性,值为99
        Demo.prototype.x = 99
        console.log('@', d.__proto__.x)
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    修改上述,输出d,是Demo的实例对象。带着Demo,表示对象d是由Demo缔造出来的(好区分)。
    在这里插入图片描述

    console.log('@', d)
    
    • 1

    Vue构造函数身上有很多属性,其中一个是prototype,prototype的值是一个对象,对象是Vue的原型对象。
    Vue实例对象vm的__proto__的值也指向了Vue的原型对象。
    Vue的原型对象是一个普普通通Object对象,Vue的原型对象的__proto__的值指向的是Object的原型对象。
    一句话:实例的隐式原型属性永远指向自己缔造者的原型对象。

    在这里插入图片描述

    在这里插入图片描述

    VueComponent构造函数同理,身上有很多属性(且与Vue的相同)。
    VueComponent原型对象的原型对象是Vue原型对象。

    在这里插入图片描述

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

    单文件组件:

    一个文件中包含有1个组件。

  • 相关阅读:
    02_Bootstrap基础组件02
    程序员怎样才能学好算法?这本书送几本给大家!
    【黑马程序员pinik名师讲html】HTML很容易忘记?有它我不慌的
    X86函数调用模型分析
    自学软件测试,学到什么程度可以出去找工作?
    数字孪生10个技术栈:数据清洗-数据的洗衣机
    Edge浏览器打不开网页解决方法教学
    大模型的视觉能力
    【Python 千题 —— 基础篇】学生转学了
    Linux-环境变量
  • 原文地址:https://blog.csdn.net/weixin_44417441/article/details/126274431