组件: 项目的开发,就是一个组件树,组件可以进行复用。
组件的名字
1.html标签不区分大小写
2.不能跟系统标签重名
3.遵循 W3C 规范中的自定义组件名 (字母全小写且必须包含一个连字符)
4.支持驼峰命名.myHeader,但是在引用的时候,需要使用my-header的方式组件支持两种定义方式
全局组件
语法:Vue.component('my-component-name', {// ... 选项 ...})
方式一:在{}中写入template模板结构方式二:将template模板结构写到组件外面,指定对应的模板名,即id属性。
局部组件
语法:在实例中添加components,注入即可。
方式一:在实例中添加components,注入子组件方式二:将template模板结构写到组件外面,声明变量接收,当使用的时候,在components中注入即可。
代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app1" style="border: 1px solid #333333;margin: auto;width: 500px;">
<my-header></my-header>
<my-cont></my-cont>
<my-btn></my-btn>
</div>
<br>
<div id="app2" style="border: 1px solid #333333;margin: auto;width: 500px;">
<my-header></my-header>
<my-cont></my-cont>
<genie></genie>
</div>
</body>
</html>
<template id="weizhuang">
<section>
<p>我是my-cont组件中的内容</p>
</section>
</template>
<template id="child">
<div>
<input type="text" placeholder="请输入用户名">
<br>
<textarea placeholder="请留言"></textarea>
</div>
</template>
<script>
// 1.注册全局组件:可以在任何一个实例中引入
// 方式一
Vue.component('my-header', {
// 指定组件的模板, 只有一个根标签,以下div为跟标签
template: `
<div>
<h1>全局组件my-header的h1标签</h1>
<p>全局组件my-header的p标签</p>
</div>
`
});
// 方式二
// 注意:在进行组件化开发的时候,每一个Vue文件都有一个template模板
Vue.component('myCont', {
// 指定组件的模板, 只有一个根标签
template: '#weizhuang'
});
// 2.注册局部组件
// 方式一:
new Vue({
el: '#app1',
components: {
myBtn: {
template: `
<div>
<button>我是app1中的button1按钮</button>
<button>我是app1中的button2按钮</button>
</div>
`
}
}
});
// 方式二:
// 备注:在组件化开发的时候,使用export defult = 该对象,如果在其他组件中要使用,直接在components中注入即可。
let child = {
template: '#child'
};
new Vue({
el: '#app2',
components: {
genie: child
}
});
</script>
举个栗子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.wrapper {
width: 400px;
margin: auto;
border: 1px solid #333333;
}
.wrapper img {
font-size: 0;
vertical-align: middle;
border-bottom: #333333 1px solid;
}
.details {
width: 100%;
display: flex;
user-select: none;
}
.details div {
flex: 1;
text-align: center;
}
.details div:nth-child(1) {
background: gainsboro;
line-height: 30px;
}
.btn {
width: 100px;
height: 30px;
border: none;
background: blue;
color: white;
font-size: 20px;
line-height: 30px;
text-align: center;
opacity: 0.5;
cursor: pointer;
}
.btn:hover {
opacity: 1;
}
.buy {
display: flex;
width: 100%;
}
.buy div {
flex: 1;
}
.tip {
color: red;
font-size: 18px;
text-align: center;
user-select: none;
}
</style>
</head>
<body>
<div id="app">
<!--注意: 必须引入,才会起效果-->
<child></child>
</div>
</body>
</html>
<template id="child">
<div class="wrapper">
<img src="http://iph.href.lu/400x400" alt="图片加载失败">
<div class="details">
<div>单价 ¥:{{price}}元</div>
<div class="btn" @click="doClick">购买</div>
</div>
<div class="buy">
<div class="tip" style="background: cadetblue">总计:{{getPrice}}元</div>
<div v-show="flag2" class="tip" style="background: gold">提示:未购该商品。</div>
<div v-show="flag" class="tip" style="background: gold">提示:您购{{num}}件商品。</div>
</div>
</div>
</template>
<script>
// 定义子组件
let child = {
template: '#child',
// 在组件中写data的时候,要把data写成一个函数
// 防止两个组件公用一个数据源
// 写法一:
// data: function () {
// return {
// name: '卫庄'
// };
// }
// 写法二:es6语法
data() {
return {
num: 0,
flag: false,
flag2: true,
price: 100
}
},
methods: {
doClick() {
this.flag = true;
this.flag2 = false;
this.num++;
}
},
// 计算属性
computed: {
getPrice() {
return this.num * this.price;
}
},
watch:{
}
};
new Vue({
el: '#app',
components: {
// es6语法会把child当做属性值与属性名
// 注意:定义的子组件一定要在父组件中注入
child
}
});
</script>
效果图