10

Vue组件

 3 years ago
source link: https://blog.csdn.net/weixin_46085790/article/details/113108977
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Vue组件

     Vue组件介绍
     Vue组件使用步骤
     Vue组件的使用
     组件中data 和 el 选项
     使用 <script><template> 标签
     组件之间的通信
     通过props向子组件传递数据
     Vue的插槽

Vue组件

组件系统是Vue中一个重要的概念,他提供了一种抽象,可以独立使用和可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树。组件是可复用的Vue实例,切带有一个名字。组件可以扩展HTML元素,封装可重用的HTML代码,可以将组件看作自定义的HTML元素。

Vue组件使用步骤

    1.Vue组件的使用有以下3个步骤:

        1. 创建组件:调用Vue.extend()方法创建组件
        2. 注册组件:调用Vue.component()方法注册组件
        3. 使用组件:使用Vue实例页面内自定义标签组件

    2.样例Demo

在这里插入图片描述

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<script src="../js/vue.min.js"></script>
		
	</head>
<body>
	<div id="app">
		<!--使用组件-->
		<mycomp></mycomp>
	</div>
		<script>
			//创建组件
			var myComp=Vue.extend({
				template:"<h2>使用Vue组件</h2>"
			});
			//注册组件
			Vue.component("mycomp",myComp);
			//实例化组件
			var vm=new Vue({
				el:"#app"
			})
		</script>
</body>
</html>

注意:组件的命名方式有两种:

  1. kebab-case(短横线分隔命名)
  2. PasecalCase(首字母大写命名)
    因为直接在DOM中使用时只有 kebab-case(短横线分隔命名)是有效的,所有一般推荐 kebab-case(短横线分隔命名)方式命名。

Vue组件使用

    1.全局注册
<div id="app">
		<!--使用组件-->
		<mycomp></mycomp>
	</div>
		<script>
			//创建组件
			var myComp=Vue.extend({
				template:"<h2>使用Vue组件</h2>"
			});
			//注册组件
			Vue.component("mycomp",myComp);
			//实例化组件
			var vm=new Vue({
				el:"#app"
			})
		</script>
    2.局部注册
<div id="app">
		<!--使用组件-->
		<mycomp></mycomp>
	</div>
		<script>
			//创建组件
			var myComp=Vue.extend({
				template:"<h3>使用局部Vue组件</h3>"
			})
			var vm=new Vue({
				el:"#app",
				components:{
					"mycomp":myComp//局部注册组件
				}
			})
		</script>
    3.组件语法糖

- 简化全局注册

 <div id="app">
		<!--使用组件-->
		<my-comp></my-comp>
	</div>
	
		<script>
			//全局注册,my-comp是组件标签名
			Vue.component("my-comp",{
				template:"<div><h3>使用Vue组件</h3></div>"
			})
			var vm=new Vue({
				el:"#app"
			})
			
</script>

- 简化局部注册
<div id="app">
		<!--使用组件-->
		<mycomp></mycomp>
	</div>
		<script>
			var vm=new Vue({
				el:"#app",
				//局部注册,mycomp是组件标签名
				components:{
						"mycomp":{
						template:"<div><h3>使用Vue组件</h3></div>"
					}
				}
			})
			
		</script>

组件中data 和 el 选项

    一般实例化Vue的多数选项也可以用在Vue.extend)或Vue .component()中的,不过有两个特殊选项参数除外即data和el。Vue.js 规定:在定义组件的选项时,data 和el选项必须使用函数。如果data选项指向某个对象,这意味着所有的组件实例共用一个data。使用一个函数作为data选项,让这个函数返回一个新对象。

    1. 全局注册组件语法
<script>
//全局注册组件
			Vue.component("组件名称",{
						el:function(){...},
						data:function(){
							return{
								属性:值
							}
						},
						template:"组件模板"
					}
				}
			})
		</script>
    2. 局部注册组件语法
<script>
//局部注册组件
			var vm=new Vue({
				el:"#app",
				components:{
					"组件名称":{
						el:function(){...}
						data:function(){
							return{
								属性:值
							}
						},
						template:"组件模板"
					}
				}
			})
		</script>
    3. 样例Demo

在这里插入图片描述

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<script src="../js/vue.min.js"></script>
		
	</head>
	<body>
		<div id="app">
			<h3>新奇水果</h3>
			<fruit-list-comp></fruit-list-comp>
		</div>
		<template id="fruitTemplate">
			<div>
				<ul>
					<li v-for="fruit in items">{{fruit}}</li>
				</ul>
			</div>
		</template>
		<script>
			var vm=new Vue({
				el:"#app",
				components:{
					"fruit-list-comp":{
						data:function(){
							return{
								items:["火龙果","苹果","西瓜","草莓"]
							}
						},
						template:"#fruitTemplate"
					}
				}
			})
		</script>
	</body>
</html>

使用 <script><template> 标签

    尽管语法糖简化了组件注册,但在template 选项中拼接HTML元素比较麻烦,这也导致了HTML 和JavaScript 拼接的高耦合性。所有Vue提供了两种方式将定义在 JavaScript 中的 HTML 模板分离出来。

    1.使用 script 标签
<div id="app">
		<!--使用组件-->
		<my-comp></my-comp>
	</div>
	
	<script type="text/javascript" id="myComp">
		<div>
			<h4>使用Vue组件</h4>
		</div>
	</script>
	
		<script>
			//全局注册,my-comp是组件标签名
			Vue.component("my-comp",{
				template:"#myComp"
			});
			var vm=new Vue({
				el:"#app",
				components:{
					"my-comp":{
						template:"#myComp"
					}
				}
				
			})
		</script>

    template选项现在不再是HTML元素,而是一个id。Vue.js根据这个id查找对应的元素,然后将这个元素内的HTML作为模板进行编译

    2. 使用 template 标签

    如果使用 <template> ,则不需要指定type属性

<div id="app">
		<!--使用组件-->
		<my-comp></my-comp>
	</div>
	
	<template id="myComp">
		<div>
			<h4>使用Vue组件</h4>
		</div>
	</template>
	
		<script>
			//全局注册,my-comp是组件标签名
			
			var vm=new Vue({
				el:"#app",
				components:{
					"my-comp":{
						template:"#myComp"
					}
				}
				
			})		
		</script>

组件之间的通信

    1.组件中通信6个步骤:

1. var child=Vue.extend({…});/创建子组件
2. var parent=Vue.extend({ …});//创建父组件
3. template:"<p>这是父组件<child-compont></child-compont></p>"//在父组件内以标签的形式使用子标签
4. components:{ “child-compont”:child//注册子组件} //将子组件注册到父组件,并将子组件的标签设置为child-compont
5. Vue.component(“parent-compont”,parent) //全局注册父组件
6. 在页面中使用<parent-compont></parent-compont>标签渲染父组件内容,同时子组件的内容也被渲染出来

    2.样例Demo

在这里插入图片描述

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<script src="../js/vue.min.js"></script>
		
	</head>
	<body>
		<div id="app">
			<parent-compont></parent-compont>
		</div>
		<script>
			//创建子组件
			var child=Vue.extend({
				template:"<p>这是子组件</p>"
			});
			//创建父组件
			var parent=Vue.extend({
				//在父组件中使用parent-compont标签
				template:"<p>这是父组件<child-compont></child-compont></p>",
				components:{
					"child-compont":child//注册子组件
				}
			});
			//注册父组件
			Vue.component("parent-compont",parent)
			var vm=new Vue({
				el:"#app"
			})
		</script>
	</body>
</html>
    3.书写错误的两种方式
  1. 以子标签的形式在父组件中使用
<div id="app">
	<parent-compont>
		<child-compont></child-compont>
	</parent-compont>
</div>
  1. 在父组件标签外使用子标签
<div id="app">
	<parent-compont></parent-compont>
	<child-compont></child-compont>
</div>

通过props向子组件传递数据

   组件实例的作用域是孤立的,这意味着不能并且不应该在子组件的模板内直接引用父组件的数据,可以使用props把数据传给子组件。一个组件可以默认拥有任意数量的props(属性),任何值都可以传递给任何props。在组件中,使用选项props来声明需要从父组件中接收的数据。props的值可以是两种:一种是字符串数组,另一种是对象

    1. props的值是字符串数组
var component=Vue.extend({
				props:["属性名",...,"属性名"],
				template:"模板"
})
    2. props的值是字符串对象
var component=Vue.extend({
	props:{
				"属性名:String",
				"属性名:Number",
				"属性名:Boolean"
			},
	template:"模板"
})
    3.样例Demo
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<script src="../js/vue.min.js"></script>
		<style type="text/css">
			.banner{
				background-color: rgb(46,110,194);
				color: rgb(255,255,255);
				width: 600px;
				height: 50px;
				line-height: 600px;
				text-align: center;
				padding: 20px;
				margin: 0 auto;
			}
			span{
				font-feature-settings: 0.6em;
			}
		</style>
	</head>
	<body>
		<div id="app">
			<!--isShowStyle 动态绑定属性-->
            <!--message 静态绑定属性-->
			<banner-component v-bind:is-style="isShowStyle" message="Happy一下"></banner-component>
		</div>
		<!--子组件-->
		<template id="childComp">
			<span>{{subMessage}}</span>
		</template>
		
		<!--父组件-->
		<template id="parentComp">
			<div>
				<!--banner:isStyle 动态绑定属性-->
				<h2 :class="{ banner:isStyle}">
					{{message}}
					<!--sub-message(短横线分隔方式命名) 静态绑定属性-->
					<child-component sub-message="不玩就out了"></child-component>
				</h2>
			</div>
			
		</template>

		<script>
			var vm=new Vue({
				el:"#app",
				data:{
					isShowStyle:true
				},
				components:{
					"banner-component":{
						props:["message","isStyle"],//props字符串
						template:"#parentComp",//注册父组件
						components:{
							"child-component":{
								props:{//props对象
									subMessage:String//驼峰式命名
								},
								template:"#childComp",//注册子组件
							}
						}
					}
				}
			})
		</script>
	</body>
</html>

Vue的插槽

     插槽是Vue提出来的一个概念,用于将携带的内容插入到指定位置,从而从而使模块化,具有的模块化的特质和更大重要性。插槽显不显示,怎样显示是由父组件来控制,而插槽在哪里显示就有子组件来进行控制。

    1. 插槽的使用

  插槽一般在Vue的父子组件中使用,在子组件中使用标签将不同的DOM树组合在一起。 标签是组件内部的占位符,用户可以使用自己的标记来填充。通过定义一个或多个标签,可将外部标记引入到组件的虚拟DOM中进行渲染,相当于“在此处渲染用户的标记”。插槽有两种使用方式:默认插槽和具名插槽。

  1. 默认插槽
         声明组件模板中包含一个插槽标签,然后使用组件时将组件内容部分填充到插槽中。
 
 <div id="app">
			<p-comp>需要分发的内容</p-comp>
		</div>
		<template id="pComp">
			<div>
				<h3>使用默认插槽</h3>
				<slot></slot>
			</div>
		</template>
		<script>
			var vm=new Vue({
				el:"#app",
				components:{
					"p-comp":{
						template:"#pComp"
					}
				}
			})
		</script>
  1. 具名插槽
         默认插槽只能有一个,当需要多个插槽时,就需要具名插槽了。
<div id="app">
			<p-comp>
				<template slot="header">
					<div>
				<!--
                	作者:offline
                	时间:2021-01-26
                	描述:具名插槽填充内容
                -->
					<h3>商品管理</h3>
				</template>
				商品管理内容
				<template slot="foots">
					<h6>版权声明</h6>
				</template>
			</p-comp>
		</div>
		<template id="pComp">
			<div>
				<!--
                	作者:offline
                	时间:2021-01-26
                	描述:具名插槽
                -->
				<slot name="header"></slot>
				<!--
                	作者:offline
                	时间:2021-01-26
                	描述:默认插槽
                -->
				<slot></slot>
				<!--
                	作者:offline
                	时间:2021-01-26
                	描述:具名插槽
                -->
				<slot name="foots"></slot>
			</div>
		</template>
		<script>
			var vm=new Vue({
				el:"#app",
				components:{
					"p-comp":{
						template:"#pComp"
					}
				}
			})
		</script>
    2. 作用域插槽的使用

     插槽可以控制HTML模板的显示与不显示。作用域插槽( slot-scope)其实就是带数据的插槽。原来父组件可以通过绑定数据传递给子组件,而作用域插槽可以通过子组件绑定数据传递给父组件。作用域插槽的使用场景:既可以复用子组件的slot,又可以使slot内容不一致。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
		
	</head>
	<body>
		<div id="app">
			<book-list :books="bookList">
				<template slot="book" slot-scope="props">
					<li>{{props.bookname}}</li>
				</template>
			</book-list>
		</div>
		<template id="bookComp">
			<div>
				<ul>
					<slot name="book" v-for="book in books" :bookname="book.name"></slot>
				</ul>
			</div>
		</template>
		<script>
			var vm=new Vue({
				el:"#app",
				data:{
					bookList:[
					{name:"《111》"},
					{name:"《222》"},
					{name:"《333》"}
					]
				},
				components:{
					"book-list":{
						props:["books"],
						template:"#bookComp"
					}
				}
			})
		</script>

	</body>
</html>

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK