当前位置: 首页 > article >正文

Vue(四) 组件、单文件组件、非单文件组件,重要的内置关系

文章目录

  • 1. 组件
  • 2. 非单文件组件
    • 2.1 定义组件
    • 2.2 注册组件
    • 2.3 使用组件
    • 2.4 组件命名、标签等注意点
    • 2.5 组件嵌套
    • 2.6 VueComponent构造(这部分看视频更易理解)
    • 2.7 内置关系
  • 3. 单文件组件

1. 组件

组件是实现局部功能代码和资源的集合

  • 传统方式:
    在这里插入图片描述
    复用的意思是只有一个文件,大家都可以用
    ​依赖关系混乱:a.js 中引入了b.js,c.js若引入想引入a,则必须也要引入b
  • 组件方式
    在这里插入图片描述
    所有组件都由vm掌管,且组件可以嵌套组件。一般vue实例对象vm直接掌管一个App的组件,App内管理着其他所有的组件。
    在这里插入图片描述

2. 非单文件组件

非单文件组件:一个文件中包含有n个组件
Vue使用组件的三大步骤:定义组件、注册组件、使用组件

2.1 定义组件

语法Vue.extend(options)
其中的options与创建vm时new Vue(options)的options几乎一样,区别有两点:

  • el不需要写,因为最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
  • data必须写成函数, 避免组件被复用时,数据存在引用关系。(如果把data定义为对象,若有两个school组件,则都指向都一个地址中的data,其中一个组件data中的属性值改了,另一个组件的data属性值也会变)

使用template选项可配置组件内容结构

<div id="root">
    <!-- 这里的标签名取决于注册组件时定义的名称 -->
    <school></school>
</div>
<script> 
    // 创建组件
 const school = Vue.extend({
     // 这里的name属性改变的仅是开发工具里显示的组件名
     name:'SCH',    
        template: `
            <div class="demo">
            <h2>学校名称:{{schoolName}}</h2>
            <h2>学校地址:{{address}}</h2>
                </div>
            `,
        data () {
            return {
                schoolName: '中学',
                address: '火星'
            }
        }
    }),
       // 创建第二个组件
       const student = Vue.extend({...})
    new Vue({
        el: '#root',
        ....
    })
</script> 

在这里插入图片描述

2.2 注册组件

  • 局部注册:new Vue的时候传入components配置项
new Vue({
    el: '#root',
...
    components: {
    // 2. 注册组件,这里写的什么名,模板里组件的标签就是什么名
    school
    //或 给组件定义新的名字
    // xuexiao: school
    }
})
  • 全局注册:

语法Vue.component('组件名',组件)
在上述局部注册中,root容器里可以使用school组件,若是再有一个vue实例对象,接管另一个容器,则另一个容器无法使用school组件。全局注册之后,则这个文件里的所有vm接管的容器都可以使用该组件

<div id="root">
    <school/>
</div>
<div id="root2">
    <school/>
</div>
<script>
    Vue.component('school',school)
    new Vue({el:'root',...})
    new Vue({el:'root2',...})
</script>

2.3 使用组件

写组件标签即可使用组件<school></school><school/>

2.4 组件命名、标签等注意点

组件命名:

  • 可以使用name配置项指定组件在开发者工具中呈现的名字。
  • 一个单词
    • 方式一:首字母小写school
    • 方式二:首字母大写School
  • 多个单词
    • 方式一:my-school
    • 方式二:MySchool(需要脚手架支持)

为了与开发者工具中的名字呼应,无论是一个单词还是两个单词,最好采用首字母大写的方式。
组件标签

  • 方式一:<school></school>
  • 方式二:<school/>,这种最好也是在使用脚手架的情况下使用,如果不使用脚手架,模板中有多个标签时,页面只渲染一个组件标签的内容

组件简写
const school = Vue.extend(options) 可简写为const school = options
这种简写方式其实底层也是给补上一个Vue.extend。也就是底层会做一个判断,要是写了Vue.extend,就不管了;要是没写,就补一个。

2.5 组件嵌套

用哪个组件就在components里注册哪个组件,
比如:app嵌套school,school嵌套student

// school组件(简写)
const school = ({
    template: `
        <div>
	        <student></student>
        </div> `,
    ...
    // 注册组件
    components: {
        student
    }
})

app只嵌套类school,因此不用注册student

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

2.6 VueComponent构造(这部分看视频更易理解)

1.组件的本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的(调用vue.extend则会生成student, student是VueComponent构造函数)

问题:组件的本质是什么?
答:VueComponent构造函数

// 创建组件
const student = Vue.extend({
    template: `
        <h2>学生姓名:{{stuName}}</h2>
        `,
    data () {
        return {
            stuName: 'tom'
        }
    }
})
console.log(student); 
// vue源码
var Sub = function VueComponent (options) {
    console.log('VueComponent构造函数');
    this._init(options);
};

在这里插入图片描述
结果证明这个函数被调用了。

  1. 我们只需写<student/><student></student>,Vue解析时会帮我们创建student组件的实例对象
<!--写两个组件标签,构造函数被调用两次-->
<student></student>
<student></student>

在这里插入图片描述
3. 特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent

// vue源码
// Vue.extend是个函数,所以他能被调用
 Vue.extend = function (extendOptions) {
    ...
      var Sub = function VueComponent (options) {
        console.log('VueComponent构造函数');
        this._init(options);
      };
    ...
      return Sub
    };
  }

所以每调用一次Vue.extend,都会生成一个Sub(Sub是VueComponent函数)。所以每次调用Vue.extend返回的VueComponent都是现定义的,所以返回的是一个全新的VueComponent。

//创建两个组件
const student = Vue.extend({..})
const school = Vue.extend({..})
console.log(school === student);// false
  1. 关于this指向:
  • 组件配置中:
    • data函数、methods中的函数、watch中的函数、computed中的函数,它们的this均是【VueComponent实例对象】(简称vc,也可称之为组件实例对象)
  • new Vue()配置中:
    • data函数、methods中的函数、watch中的函数、computed中的函数,它们的this均是【Vue实例对象】(简称vm)
      打印vm可以看出,vm管理着一个一个的vc
      在这里插入图片描述

2.7 内置关系

  • 一个重要的内置关系:VueComponent.prototype._proto === Vue.prototype
  • 为什么要有这个关系:让组件实例对象vc可以访问到Vue原型上的属性、方法。如果没有这个关系,Vue原型上的东西只能vm可以用。

回顾原型链的内容:

// 定义一个构造函数
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

// 程序员通过显式原型属性放东西
Demo.prototype.x = 99
// 通过隐式原型属性取东西
console.log(d.x); // 99

只有函数才有显式原型属性prototype
只要是对象,就有隐式原型属性__proto__
实例的隐式原型属性永远指向自己缔造者的原型对象

Vue的实例对象的__proto__永远指向自己缔造者(Vue)的原型对象,也就是蓝色框的蓝色虚线
在这里插入图片描述
Vue是个构造函数:
在这里插入图片描述

<div id="root">
    <!--写了这个标签才算是构建了VueComponentde的实例对象-->
    <student></student> 
</div>
<script>
    Vue.prototype.x = 99
    // student获得的是VueComponentde构造函数
    const student = Vue.extend({
       template: `
        <div>
        	<h2>学生姓名:{{stuName}}</h2>
        	<button @click="showX">点击显示x</button>
        </div>
        `,
        data () {
            return {
                stuName: 'tom'
            }
        },
        methods: {
            showX () {
                console.log(this.x); // 99
            }
        }
    })
    console.log(student.prototype.__proto__ === Vue.prototype);
</script>

3. 单文件组件

单文件组件的后缀名都是.vue。可借助插件运行.vue文件

在这里插入图片描述
.vue文件的内容包括:

<template>
	<!-- 组件结构 -->
</template>

<script>
	// 组件交互相关的代码(数据、方法)
</script>

<style>
	/* 组件的样式 */
</style>

http://www.kler.cn/a/284935.html

相关文章:

  • https网站 请求http图片报错:net::ERR_SSL_PROTOCOL_ERROR
  • vue elementui el-dropdown-item设置@click无效的解决方案
  • Golang常见编码
  • 【ARM Coresight OpenOCD 系列 5 -- arp_examine 使用介绍】
  • vue+Leaflet.PM插件实现创建和编辑几何图形(点、线、面、圆等)
  • 物流企业新闻稿怎么写?货运行业品牌宣传背书的报纸期刊杂志媒体有哪些
  • 【计组 | Cache原理】讲透Cache的所有概念与题型方法
  • 大模型好书案例——《BERT基础教程:Transformer大模型实战》(附PDF)
  • LuaJit分析(一)LuaJit交叉编译
  • TCP的连接与断开
  • java基础开发-xstream解析xml
  • 去中心化(Decentralization)
  • leetcode1514 最大概率路径(Bellman-ford算法详解)
  • 栈算法【基于顺序表】
  • centos 系统yum 安装 mariadb
  • UML类图中的组合关系
  • Vue3 + Axios双Token刷新解决方案
  • MySQL——多表操作(四)子查询(1)带 IN 关键字的子查询
  • Xilinx高速接口之GTP
  • CSS 预处理器
  • 10、ollama启动LLama_Factory微调大模型(llama.cpp)
  • opencv之形态学
  • 喜羊羊做Python真题
  • 基于Android+SQLite数据库开发Java考试App
  • 深度学习100问15:什么是交叉熵误差
  • 【Linux】Linux Bash Shell 教程