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>
注意:组件的命名方式有两种:
- kebab-case(短横线分隔命名)
- 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.书写错误的两种方式
- 以子标签的形式在父组件中使用
<div id="app">
<parent-compont>
<child-compont></child-compont>
</parent-compont>
</div>
- 在父组件标签外使用子标签
<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中进行渲染,相当于“在此处渲染用户的标记”。插槽有两种使用方式:默认插槽和具名插槽。
- 默认插槽
声明组件模板中包含一个插槽标签,然后使用组件时将组件内容部分填充到插槽中。
<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>
- 具名插槽
默认插槽只能有一个,当需要多个插槽时,就需要具名插槽了。
<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>