18-非单文件组件

Posted 搞钱自律

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了18-非单文件组件相关的知识,希望对你有一定的参考价值。

组件的三大步骤
第一步:创建组件
第二步:注册组件
第三步:使用组件

1.局部注册

1.1第一步:创建组件

 //第一步:创建school组件
        const school = Vue.extend(
            // el:'#root',//组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
            template:`
                <div>
                    <h2>学校名称:name</h2>
                    <h2>学校地址:address</h2>
                    <button @click="showName">点我提示学校名</buttion>
                </div>
            `,
            data()
                return
                    name:'北大',
                    address:'北京'
                
            ,
            methods: 
                showName()
                    alert(this.name)
                
            ,
        )

第二步:注册组件

//创建vm
const vm = new Vue(
  el:'#root',
   //第二步:注册组件(局部注册)
   components:
     //组件名:组件引用变量名
     xuexiao:school,
     xuesheng:student
   
)

第三步:使用组件

<div id="root">
   <!-- 第三步:编写组件标签 -->
   <xuexiao></xuexiao>
   <hr>
   <xuesheng></xuesheng>
</div>

整体代码

<!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>

    <!-- 引入Vue -->
    <script type="text/javascript" src="../js/vue2.js"></script>

</head>
<body>

    <!-- 准备好一个容器 -->
    <div id="root">
        <!-- 第三步:编写组件标签 -->
        <xuexiao></xuexiao>
        <xuexiao></xuexiao>
        <hr>
        <xuesheng></xuesheng>
    </div>

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

        //第一步:创建school组件
        const school = Vue.extend(
            // el:'#root',//组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
            template:`
                <div>
                    <h2>学校名称:name</h2>
                    <h2>学校地址:address</h2>
                    <button @click="showName">点我提示学校名</buttion>
                </div>
            `,
            data()
                return
                    name:'北大',
                    address:'北京'
                
            ,
            methods: 
                showName()
                    alert(this.name)
                
            ,
        )

        //第一步:创建school组件
        const student = Vue.extend(
            // el:'#root',//组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
            template:`
                <div>
                    <h2>学校名称:name</h2>
                    <h2>学校地址:age</h2>
                </div>
            `,
            data()
                return
                    name:'张三',
                    age:12
                
            
        )

        //创建vm
        const vm = new Vue(
            el:'#root',
            //第二步:注册组件(局部注册)
            components:
                //组件名:组件引用变量名
                xuexiao:school,
                xuesheng:student
            
        )
    </script>
</body>
</html>

结果图

2.全局组件

2.1验证上述代码是局部组件

<!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>

    <!-- 引入Vue -->
    <script type="text/javascript" src="../js/vue2.js"></script>

</head>
<body>

    <!-- 准备好一个容器 -->
    <div id="root">
        <!-- 第三步:编写组件标签 -->
        <xuexiao></xuexiao>
        <xuexiao></xuexiao>
        <hr>
        <xuesheng></xuesheng>
    </div>

    <div id="root2">
        <xuexiao></xuexiao>
    </div>

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

        //第一步:创建school组件
        const school = Vue.extend(
            // el:'#root',//组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
            template:`
                <div>
                    <h2>学校名称:name</h2>
                    <h2>学校地址:address</h2>
                    <button @click="showName">点我提示学校名</button>
                </div>
            `,
            data()
                return
                    name:'北大',
                    address:'北京'
                
            ,
            methods: 
                showName()
                    alert(this.name)
                
            ,
        )

        //第一步:创建school组件
        const student = Vue.extend(
            // el:'#root',//组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
            template:`
                <div>
                    <h2>学校名称:name</h2>
                    <h2>学校地址:age</h2>
                </div>
            `,
            data()
                return
                    name:'张三',
                    age:12
                
            
        )

        //创建vm
        const vm = new Vue(
            el:'#root',
            //第二步:注册组件(局部注册)
            components:
                //组件名:组件引用变量名
                xuexiao:school,
                xuesheng:student
            
        )

        //创建vm
        const vm2 = new Vue(
            el:'#root2'
        )
    </script>
</body>
</html>


主要是添加以上两张图片的代码
然后会发现控制台会报错,如下图所示

2.2 全局注册

 //第二步:全局注册组件  第一个参数:组件名 第二个参数:组件引用变量名
 Vue.component('hello',hello)

2.3 全局引用


<!-- 准备好一个容器 -->
 <div id="root">
     <!-- 第三步:编写组件标签 -->
     <xuexiao></xuexiao>
     <xuexiao></xuexiao>
     <hello></hello>
     <hr>
     <xuesheng></xuesheng>
 </div>

 <div id="root2">
     <hello></hello>
 </div>

整体代码

<!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>

    <!-- 引入Vue -->
    <script type="text/javascript" src="../js/vue2.js"></script>

</head>
<body>

    <!-- 准备好一个容器 -->
    <div id="root">
        <!-- 第三步:编写组件标签 -->
        <xuexiao></xuexiao>
        <xuexiao></xuexiao>
        <hello></hello>
        <hr>
        <xuesheng></xuesheng>
    </div>

    <div id="root2">
        <hello></hello>
    </div>

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

        //第一步:创建school组件
        const school = Vue.extend(
            // el:'#root',//组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
            template:`
                <div>
                    <h2>学校名称:name</h2>
                    <h2>学校地址:address</h2>
                    <button @click="showName">点我提示学校名</button>
                </div>
            `,
            data()
                return
                    name:'北大',
                    address:'北京'
                
            ,
            methods: 
                showName()
                    alert(this.name)
                
            ,
        )

        //第一步:创建student组件
        const student = Vue.extend(
            // el:'#root',//组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
            template:`
                <div>
                    <h2>学校名称:name</h2>
                    <h2>学校地址:age</h2>
                </div>
            `,
            data()
                return
                    name:'张三',
                    age:12
                
            
        )

        //第一步:创建hello组件
        const hello = Vue.extend(
            template:`
                <div>
                    <h2>你好啊name</h2>
                </div>
            `,
            data()
                return
                    name:'Tom'
                
            
        )

        //第二步:全局注册组件  第一个参数:组件名 第二个参数:组件引用变量名
        Vue.component('hello',hello)

        //创建vm
        const vm = new Vue(
            el:'#root',
            //第二步:注册组件(局部注册)
            components:
                //组件名:组件引用变量名
                xuexiao:school,
                xuesheng:student
            
        )

        //创建vm
        const vm2 = new Vue(
            el:'#root2'
        )
    </script>
</body>
</html>

3.总结

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

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

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

三、编写组件标签:
    <hello></hello>  

4.组件的几个注意点

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

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

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

Vue 学习总结笔记

文章目录

1. Vue 组件化编程

1.1 模块 与 组件


什么是模块?

  • 向外提供特定功能的js程序,一般就是一个js文件。

什么是组件?

  • 用来实现局部(特定)功能效果的代码集合(html/css/js/image…)。

什么是模块化?

  • 当应用中的js都以模块来编写的,那这个应用就是一个模块化的应用。
    什么是组件化?
  • 当应用中的功能都是多组件的方式来编写的,那这个应用就是一个组件化的应用。

1.2 传统的编写方式 vs 组件化编写方式


传统的编写方式:

组件化编写方式:


其实Vue中,组件就是类似与封装。

此外,组件内部也是可以嵌套的。


组件定义:实现应用中的 局部功能代码(css,html,js等)和资源(mp3,mp4等资源)的集合。

2. 非单文件组件 和 单文件组件


非单文件组件:

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

单文件组件:

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

组件的效果就是:谁用到这个组件,它就可以直接调用。

3. 组件的使用


第一步:使用Vue.extend()来创建组件。

使用Vue.extend()创建组件的注意事项:

  • 创建组件中,一定不要写el配置项,不然会报错。
    原因:因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
    也就是让vm来决定这个组件放到哪里就放到哪里,不能让他它自己决定。
  • 组件的data配置必须要用函数式写法!
    对象式的形式,因为组件可以被多个地方使用,如果是对象式的话,一方变化其他的也都会跟这变化,因为只有一个对象。
    函数式的形式,就不用担心变化的问题了,因为多个地方调用函数式时,会得到多个对象,这样相互之间就不会影响了。
Vue.config.productionTip = false;

//创建school组件
const school = Vue.extend(
	
	/*
		注意点一:创建组件中,一定不要写el配置项,不然会报错。
		原因:因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
		也就是让vm来决定这个组件放到哪里就放到哪里,不能让他它自己决定。
		// el:"#root",
		
		注意点二:组件的data配置必须是函数式。
			对象式的形式,因为组件可以被多个地方使用,如果是对象式的话,一方变化其他的也都会跟这变化,因为只有一个对象。
			函数式的形式,就不用担心变化的问题了,因为多个地方调用函数式时,会得到多个对象,这样相互之间就不会影响了。
	*/
   
	data()
		return 
			schoolName:"北京大学",
			address:"北京"
		
	
	
);

//创建student组件
const student = Vue.extend(
	data()
		return 
			studentName:"张三",
			age:18
		
	
)

第二步:在vm对象中,注册组件。

Vue.config.productionTip = false;
			
//创建school组件
const school = Vue.extend(  
	data()
		return 
			schoolName:"北京大学",
			address:"北京"
		
	,
	//使用template为这个组件添加上结构。
	//注意每一个template必须要有并且只有一个div结构。
	template:`
			<div>
			<h2>学校名称:schoolName</h2>
			<h2>学校地址:address</h2>
			</div>
	`
);

//创建student组件
const student = Vue.extend(
	data()
		return 
			studentName:"张三",
			age:18
		
	,
	template:`
		<div>
			<h2>学生姓名:studentName</h2>
			<h2>学生年龄:age</h2>
		</div>
	`
)


//vm对象
new Vue(
	el:"#root",
	//使用components来注册组件(局部注册)
	components:
		//这里我们定义的组件名和上面的组件定义的变量名一样,可以直接简写为一个
		xuexiao:school,
		xuesheng:student
	
)

第三步:编写组件标签。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="./js/vue.js"></script>
	</head>
	<body>
		<div id="root">
			<!-- 编写组件标签。 -->
			<xuexiao></xuexiao>
			<hr>
			<xuesheng></xuesheng>
		</div>
		
		<script type="text/javascript">
		
			Vue.config.productionTip = false;
			
			//创建school组件
			const school = Vue.extend(
				data()
					return 
						schoolName:"北京大学",
						address:"北京"
					
				,
				//使用template为这个组件添加上结构。
				//注意每一个template必须要有并且只有一个div结构。
				template:`
						<div>
						<h2>学校名称:schoolName</h2>
						<h2>学校地址:address</h2>
						</div>
				`
			);
			
			//创建student组件
			const student = Vue.extend(
				data()
					return 
						studentName:"张三",
						age:18
					
				,
				template:`
					<div>
						<h2>学生姓名:studentName</h2>
						<h2>学生年龄:age</h2>
					</div>
				`
			)
			
			
			//vm对象
			new Vue(
				el:"#root",
				//使用components来注册组件(局部注册)
				components:
					xuexiao:school,
					xuesheng:student
				
			)
			
		</script>
	</body>
</html>

创建好的组件可以在开发者工具查看:


上面注册组件都是局部注册组件,也可全局注册组件

使用Vue.component(‘组件名’,组件变量名); 这样所有的vm对象都可以使用这个组件,不需要再在components中注册了。

4. 组件的注意事项


正常我们在组件命名可以用简写的方式。

Vue.config.productionTip = false;

//定义组件
const school = Vue.extend(
	template:`
		<div>
			<h2>学校名称:name</h2>
			<h2>学校地址:address</h2>
		</div>
	`,
	data()
		return 
			name:"北京大学",
			address:"北京"
		
	
)

new Vue(
	el:"#root",
	data:
		msg:"欢迎学习Vue!"
	,
	components:
		//正常写应该是school:school , 并且Vue的开发者工具中默认是变成大写开头的School。
		school
	
)

对于多个单词组成的组件名,要如下格式:

  • 一个使用首字母小写单词中间用 - 来分开的格式。例如:my-school。
  • 还有一种是在vue脚手架的情况下,操作就是每个单词首字母大写例如:MySchool。(必须有vue脚手架才行)
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript" src="./js/vue.js"></script>
	</head>
	<body>
		<div id="root">
			<h2>msg</h2>
			<my-school></my-school>
		</div>
		
		<script type="text/javascript">
		
			Vue.config.productionTip = false;
			
			//定义组件
			const school = Vue.extend(
				template:`
					<div>
						<h2>学校名称:name</h2>
						<h2>学校地址:address</h2>
					</div>
				`,
				data()
					return 
						name:"北京大学",
						address:"北京"
					
				
			)
			
			new Vue(
				el:"#root",
				data:
					msg:"欢迎学习Vue!"
				,
				components:
					'my-school':school
				
			)
			
		</script>
	</body>
</html>

==组件的名字不要与我们正常dom元素的名字相同!==例如:我定义了一个名字为h2的组件,那这样在dom上面就直接显示了dom元素的h2标签了。


我们创建组件的时候,可以设置一个name属性配置,一旦设置了name属性,Vue的开发者工具中,它就会使用name的值来读取了。


组件名标签可以缩写为这种样式:<xuexiao/> ,但是前提必须是Vue脚手架的环境下,记住。


创建组件可以将Vue.extend()省略,只留下一个配置就行。这个是可以的,要知道。

5. 组件的嵌套


嵌套就是在组件中,嵌套别的组件。

很简单,在组件中定义components就可以了。

有几个注意点:

  • 标椎开发会有一个app组件来统一管理组件,app组件专门为Vue实例对象服务的。
  • 如果我想让容器保持在空的状态下来,我们可以在Vue实例对象中配置tempalte标签给他设置<app></app>。
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript" src="./js/vue.js"></script>
	</head>
	<body>
		<div id="root">
			
		</div>
		
		<script type="text/javascript">
		
			Vue.config.productionTip = false;
			
			//定义student组件
			const student = Vue.extend(
				name:"student",
				template:`
					<div>
						<h2>学生姓名:name</h2>
						<h2>学生年龄:age</h2>
					</div>
				`,
				data()
					return 
						name:"张三",
						age:"19"
					
				
			)
			
			//注意这里有个顺序问题,school组件要使用student组件,student要先加载!
			
			//定义school组件
			const school = Vue.extend(
				name:"school",
				template:`
					<div>
						<h2>学校名称:name</h2>
						<h2>学校地址:address</h2>
						<student></student>
					</div>
				`,
				data()
					return 
						name:"北京大学",
						address:"北京"
					
				,
				//在组件中,注册组件,也就是嵌套组件
				components:
					student
				
			)
			
			//一般我们通过一个app的组件,来统一管理所有的组件。
			const app = Vue.extend(
				template:`
					<div>
						<school></school>
					</div>
				`,
				components:
					school,
					student
				
			)
			
			
			const vm = new Vue(
				template:"<app></app>",
				el:"#root",
				components:
					app
				
			)
			
		</script>
	</body>
</html>

6. VueComponent构造函数


先说一下,VueComponent是怎么出现的,它是通过Vue.extend()被创建出来的!

组件的创建全都依靠了VueComponent构造函数!!!(很重要!)

我们先console.log()一下组件,看看组件的本质。


本质上就是一个VueComponent的构造函数

VueComponent构造函数的注意事项:

  • 我们创建的组件本质上是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的这个VueComponent构造函数。
  • 我们在模板上面只需要调用组件名标签,Vue解析时,会帮我们创建对应组件的实例对象。即Vue帮我们执行的:new VueComponent(options)。
  • 特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!!也就是模板发现一次组件名对应的标签,就返回一个新的VueComponent。
  • 组件中配置的data函数,methods函数,watch函数,computed函数等等,这些组件的this指向VueComponent实例对象,而不是vue实例对象

通过控制台查看组件在Vue实体对象的位置,在$children。

7. VueComponent和Vue实例对象有一个重要的内置关系!


首先,了解对于js的原型链方面的知识。

显示原型属性,隐式原型属性。

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__)//隐式原型属性
//上面这两个对象都对应一个原型对象!

//这里我们设置了Demo的原型属性。
Demo.prototype.x = 99;

//对应的也能在d中找到他对应的原型属性。
console.log(d.__proto__.x);
console.log(d.x);


重要的内置关系就是:组件名.prototype.__prote__ === Vue.prototype 。注意这里的组件名就是VueComponent构造函数

下面的红线,蓝线,黄线都是通过原型链来指向的。

记住VueComponent的原型对象会先指向Vue的原型对象,这样他们之间就会有一个原型链的关系。

(上面这种方式的好处就是当我们设置Vue原型对象的一些属性,也能在组件对象中获取到。)

8. 单文件组件

8.1 单文件组件的样式


一说到单文件组件就立刻想到是xxx.vue形式的,我们开发中都是使用的单文件组件。

这里我们想要使用.vue文件就必须要使用vue脚手架的环境。

8.2 单文件组件的命名


组件的命名方式最好是下图粉色对号,因为Vue大多数都是这种形式的写法我们也按照这种写法写比较标准。

8.3 单文件组件 和 非单文件组件的对比


VS Code可能不认识xxx.vue文件类型的,我们可以下载一个叫Vetur的组件来解决。


单文件组件和非单文件组件的对比:

8.4 export 暴露


export暴露就是为了让别人能够引入它。组件就是哪里需要哪里搬。

export有三种暴露方式:

  • 分别暴露:
  • 统一暴露
  • 默认暴露(常用)

8.5 Vue组件的简化


因为const school = Vue.extend(…); 是可以简写为const school = …; 这是Vue的简写形式。

因此,我们可以直接简写!


并且我们一定要定义name属性,定义好组件的名字,这样别人使用的时候就可以用该名字来操作了。

大体结构如下:

<template>
	<!-- 组件结构 -->
	<div id="root">
		<div>
			<h2>学校名称:schoolName</h2>
			<h2>学校地址:address</h2>
			<button @click="showName">点我提示学校名字</button>
		</div>
	</div>
</template>

<script>
	// 组件交互的代码
	export default 
		name:"School",//给组件起名字,这里的name和我们的当前.vue文件要一致(标准写法)。
		data()
			return 
				schoolName:"北京大学",
				address:"北京"
			
		,
		methods:
			showName()
				alert(this.schoolName);
			
		
	
</script>

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

8.6 App.vue组件


这个组件是必不可少的,它是用来汇总所有组件的!

注意下面的注释!

App.vue文件:

<template>
	<!-- 模板里面必须有一个根元素,这个根元素div。 -->
	<div id="root">
		<School></School>
		<Student></Student>
		<!-- 
			在脚手架的环境下,可以简写为<School/>单标签。但是非脚手架环境不可以。
		-->
	</div>
</template>

<script>
	//引入组件
	import School from './School.vue'
	import Student from './Student.vue'
	
	export default
		name:"App",
		components:
			School,
			Student
		
	
</script>

<style>
</style>

8.7 main.js


在组件中是不可能有new Vue()对象的!但是在那里创建Vue实例对象呢?就是在main.js中创建Vue实例对象。

main.js不会导入其他的组件,只会导入App.vue组件。因为App.vue组件规定就是所有组件的汇总!

main.js文件:

import App from './App.vue'

new Vue(
	el:"#root",
	template:`<App></App>`,//在这里写好了就不用再去index.html或其他网页写标签了。
	components:
		App
	
)
以上是关于18-非单文件组件的主要内容,如果未能解决你的问题,请参考以下文章

学Vue就跟玩一样组件-非单文件组件的使用

vue.js 如何将 props 与单个文件组件一起使用

Vue组件系统 -- 2019-08-08 18:01:47

Vue组件系统 -- 2019-08-08 18:01:48

vue.js(18)--父组件向子组件传值

Vue.js(18)之 封装calendar组件