一、组件的概念

组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。
组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树
在这里插入图片描述
将一个页面拆分成一个个小组件更有利于我们对页面进行维护。熟悉组件之后我们可以使用vue做出更加科学更加完美的页面。在vue中可以按照一个文件中组件的个数划分为单文件组件与非单文件组件(一个文件有多个组件),我们在日常工作中最常用的还是单文件组件,将具有某功能的组件放进一个文件,可以使我们的程序更好的实现“高内聚,低耦合”


在使用组件的时候我们一般按照以下步骤:

  • 1.定义组件(创建组件实例)
  • 2.注册组件
    • 全局组件(component(‘组件名’,组件实例))
    • 局部组件(components:{组件实例…})
  • 3.使用组件(使用组件标签)
    • <组件名></组件名> 双标签写法
    • <组件名/> 单标签写法

具体应如何使用呢请往下看!

二、非单文件组件

将会结合代码示例进行讲解:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>组件的基本使用</title>
    <script type="text/javascript" src="../js/vue.js"></script>
  </head>
  <body>
    <div id="demo">
        <!-- 组件的写法有两种
             双标签法
             单标签法()
        -->
        
        <!-- 
        第三步:使用组件,这两个组件均是我们创建好的组件,使用方法如下
        -->
        <school></school>
        <student></student>
    </div>
    <div id="demo1">
        <school></school>
        <student></student>
    </div>
  </body>
  <script>
  	  //屏蔽掉vue生产提示
      Vue.config.productionTip = false;
      //-----------------第一步:定义组件------------------------//
      //创建一个组件实例school,并且命名为school
        const school = Vue.extend({
            name:"school",
            //指定一个模板,将来会使用这个模板挂载到父节点
            template: `
            <div>
                <h2>学校名称:{{name}}</h2>
                <h2>学校地址:{{address}}</h2>
                <button @click="showINfo">点击我提示信息</button>
            </div>
            `,
            //组件实例对象的属性
            data(){
                return {
                    name:"南阳理工学院",
                    address:"南阳市宛城区长江路80号"
                }
            },
            //组件实例的方法
            methods: {
                showINfo() {
                    alert('欢迎来到'+this.name+"这里的位置是"+this.address)
                }
            },
        })
        //定义的第二个组件student
        const student = Vue.extend({
        	//组件的模板
            template:`
            <div>
                <h2>学生名称:{{name}}</h2>
                <h2>学生年零:{{age}}</h2>
                <button @click="showINfo">点击我提示信息</button>
            </div>
            `,
            //组件的属性
            data(){
                return {
                    name:"张三",
                    age:18
                }
            },
            //组件的方法
            methods:{
                showINfo(){
                    alert('我叫'+this.name+"我今年"+this.age+"岁了")
                }
            }
            
        });
        //-----------------第二步:注册组件------------------------//
        // 标签的全局注册
        Vue.component("school",school)
        Vue.component("student",student)
        // 局部注册法(局部注册的标签在其他vue对象绑定的模板中不能使用)
        new Vue({
            el:"#demo",
            components:{
                school,
                student
            }
        })
        new Vue({
            el:"#demo1",
            components:{
            }
        })
 </script>
</html>

注意:

  • 该不该有el属性:
    通过观察我们发现局部注册组件时有el属性,而定义变量接收的方式没有el属性,这是因为定义为变量的组件有复用性,不可以确定以后为谁服务。而局部注册的组件以后肯定为本组件服务,所以一个有el属性,一个没有,el属性的作用就是将该组件挂载到包含指定选择器的dom下。

  • 从前vue对象的属性data为对象现在为什么成了函数?
    data属性为对象时相当于好几个组件共享了一个对象,组件内使用data属性的时候要写成函数的形式(如果一个组件被使用n次需创建n个对象,写对象的话没有复用性,会出现多次使用该组件该组件属性一样的情况)

  • 这里的复用性是指什么?
    复用性不是代码复用性,是功能复用性(不是cv而是让组件像类一样,可以以他为模板创建很多对象)

  • 其余注意项:
    Vue.extend()可以省略
    可以在组件中导入模板模板可以使用组件data中的属性
    组件中还可以指定name,指定后在Vue调试工具中将会有所体现

三、单文件组件

在上面也说过单文件组件的概念,就是一个文件内只有一个组件,并且文件名通常与组件名相照应。
单文件组件应包含以下几项:

  • 文件包含三部分(代码模板,js代码,style代码)
  • 一个Vue文件仅仅有一个组件
  • 应包含一个App.vue组件,汇总并管理其他的所有组件
  • main.js文件为其入口
  • index为其主页面

可以通过以下一个实例来了解单文件组件:
工作流程是通过main.js管理App组件,App组件去管理Student与School组件干活。然后将渲染出的页面挂载到index.html页面上,具体的功能都在代码注释上。

1.main.js

import App from "./App.vue"
// 直接在这个文件创建实例对象并将组件注册到对象内
new Vue({
	//未来渲染出的页面放在id为root的标签上
    el:"#root",
    data(){
        return{
            tag:0
        }
    },
    //注册app组件
    components:{App}
})

2.App.vue

//模板,相当于vue Component中的template属性中的东西
<template>
    <div class="demo">
    <School></School>
    <Student></Student>
    </div>
</template>

<script>
import School from "./School.vue" 
import Student from "./Student.vue" 
export default {
    name:"App",
    data(){
        return{
            name:"张三",
            age:18
        }
    },
    components:{
        School,
        Student
    }
}
</script>

<style>
    .data{
        background-color: yellow;
    }
</style>

3.school.vue

//被管理的组件
<template>
  <div class="demo">
      <div>学校名称:{{name}}</div>
      <div>学校地址:{{address}}</div>
  </div>
</template>

<script>
export default {
    name:"School",
    data(){
        return {
            name:"南阳理学院",
            address:"南阳市宛城区长江路80号"
        }
    }
}
</script>

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

4.student.vue

//被管理的组件
<template>
    <div class="demo">
      <div>学生名称:{{name}}</div>
      <div>学校年龄:{{age}}</div>
  </div>
</template>

<script>
export default {
    name:"Student",
    data(){
        return {
            name:"张三",
            age:18
        }
    }
}
</script>

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

5.index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="root">
        <App></App>
    </div>
    //这里将两个js放下面是因为vue渲染出的页面进行挂载时需要获取到相应的dom元素
<script   src="./vue.js"></script>
<script  src="./vue/main.js"></script>
</body>
</html>

直接打开index.html页面展示出的效果会抛出以下错误。不过很正常
Uncaught SyntaxError: Cannot use import statement outside a module:原因是main.js中的import App from "./App"浏览器不支持,解决方法就是使用vue脚手架运行代码或者使用webpack。常规的vue代码就是这样写的。

四、内容补充及原理剖析

1.组件命名注意点

  • 1.关于组件名:

    • 一个单词组成:
      第一种写法(首字母小写):school
      第二种写法(首字母大写):School
    • 多个单词组成:
      第一种写法(kebab-case命名):my-school
      第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)
    • 备注:
      (1).组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
      (2).可以使用name配置项指定组件在开发者工具中呈现的名字。
  • 2.关于组件标签:
    第一种写法:<school></school>
    第二种写法:<school/>
    备注:不用使用脚手架时,会导致后续组件不能渲染。

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

2.组件嵌套内置关系

通过嵌套实现main.js管理app组件,app组件管理其余功能性组件,组件可以嵌套在另一个组件之中,并让其管理。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>组件的嵌套</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
        <!-- 在使用组件嵌套的时候一定要注意,使用到的子组件要放在前面 -->
        <!-- 最终形成各个层级,每一级都有归属直至app组件 -->
	</head>
	<body>
		<!-- 准备好一个容器-->
		<div id="root">
			
		</div>
	</body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

		//定义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组件(管理school与student组件)
		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>
</html>

3.重要的内置关系

使用Vue的时候,可以注册很多个Component。
1.一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype
2.为什么要有这个关系?
可以让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。
关系图如下:
在这里插入图片描述
那么为什么要有这层内置关系?这种关系可以干什么?
如下图,是main.js中的一部分代码,这部分代码将插件绑定到Vue对象上,以便于在组件内部使用this调用。
组件跟插件有着不同的定义。插件一般是.js文件,而组件是vue文件。
在使用的时候也有明显的区别,一个使用use,一个使用components
在这里插入图片描述


Logo

前往低代码交流专区

更多推荐