一、组件
组件可以扩展 HTML 元素,封装可重用的代码。组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树。
- 每一个组件都是一个vue实例
- 每个组件均具有自身的模板template,根组件的模板就是挂载点
- 每个组件模板只能拥有一个根标签
- 子组件的数据具有作用域,以达到组件的复用
组件是有html模板,有css样式,有js逻辑的集合体。
根组件的模板就使用挂载点,子组件必须自己定义template(局部子组件、全局子组件)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
<style>
h2{
color: yellowgreen;
}
</style>
</head>
<body>
<div id="app">
<h1>组件概念</h1>
</div>
<script>
// 组件:有html模板,有css样式,有js逻辑的集合体
// 根组件的模板就使用挂载点,子组件必须自己定义template(局部子组件、全局子组件)
new Vue({
el:'#app',
//反引号渲染
template:`
<div>
<h1 style="color: red">组件渲染的模板</h1>
<h2 @click="action">副标题</h2>
</div>
`,
data:{
},
methods:{
action:function () {
console.log('123')
}
}
})
</script>
</body>
</html>
我们发现原来的div已经被组件的替换了。
1.1、根组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>{{ msg }}</h1>
</div>
<script type="text/javascript">
// 通过new Vue创建的实例就是根组件(实例与组件一一对应,一个实例就是一个组件)
// 每个组件组件均拥有模板,template
var app = new Vue({
// 根组件的模板就是挂载点
el: "#app",
data : {
msg: "根组件"
},
// 模板: 由""包裹的html代码块,出现在组件的内部,赋值给组件的$template变量
// 显式书写模块,就会替换挂载点,但根组件必须拥有挂载点
template: "<div>显式模板</div>"
})
// app.$template
</script>
</body>
</html>
1.2、局部组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<!--css3语法:div.box>h1{标题}+(p.p${文本内容}*2)-->
<abc></abc>
<abc></abc>
</div>
<script>
//定义局部组件
let localTag = {
//1、data要达到组件的复用,必须为每个组件提供一个名称空间(作用域)
//2、data的值就是一个存放数据的字典
//需要满足1和2,data值为一个可以产生名称空间的函数的返回值,返回值是字典
data:function () {
return {
count: 0
}
},
template:`
<div class="box" style="border: solid;width: 100px">
<h1>标题</h1>
<p class="p1">文本内容</p>
<p @click="action" class="p2" style="background: yellowgreen">被点击了{{ count }}下</p>
</div>
`,
methods:{
action:function () {
this.count++
}
}
};
new Vue({
el:'#app',
data:{
},
//局部组件必须注册
components:{
'abc':localTag
}
})
</script>
</body>
</html>
1.3、全局组件
注册一个全局组件语法格式如下:
Vue.component(组件名, {组件主体});
Vue.component(tagName, options);
tagName 为组件名,options 为配置选项。注册后,我们可以使用以下方式来调用组件:
<tagName></tagName>
js中定义的全局组件名字如果是驼峰体的(globalParam),但是在html使用时,html是不区分大小写的,那么该怎么办呢?
当然有对策,直接在对应的大写前加一个-就好(global-param)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<!--在标签中建议使用 - 语法命名,对应js中就是驼峰命名-->
<old-boy></old-boy>
</div>
<script>
//语法:Vue.component(组件名, {组件主体});
Vue.component('oldBoy',{
data:function () {
return {
count: 0
}
},
template:`
<div class="box" style="border: solid; width: 100px">
<h1>全局</h1>
<p class="p1">文本内容</p>
<p @click="action" class="p2"style="background: yellowgreen">被点击了{{ count }}下</p>
</div>
`,
methods:{
action:function () {
this.count++
}
}
});
//全局组件无需注册
new Vue({
el:'#app',
data:{ }
})
</script>
</body>
</html>
1.4、父组件给子组件传递信息
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- local-tag就可以理解为自定义标签,使用msg变量值由父组件提供 -->
<!-- local-tag标签代表的是子组件,owen为标签的自定义属性 -->
<!-- 在子组件内部能拿到owen,就可以拿到父组件的信息 -->
<local-tag :owen="msg"></local-tag>
</div>
<script>
let localTag = {
//子组件拿自定义属性
props:['owen'],
template:`
<div>
<h1>信息</h1>
<p>{{ owen }}</p>
</div>
`,
};
new Vue({
el:'#app',
data:{
msg:'父级的信息'
},
components:{
// 本质上注册:'localTag': localTag,
// js自动转字符串,可以这么写:localTag: localTag,
//下面因为注册的标签名与组件名一样,可以简写
localTag //在页面local-tag
}
})
</script>
</body>
</html>
1.5、子组件给父组件传递信息
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>{{ title }}</h1>
<global-tag @recv="get_title"></global-tag>
</div>
<script>
Vue.component('global-tag',{
template:`
<div>
<input type="text" v-model="msg">
<button @click="action">修改标题</button>
</div>
`,
methods: {
action:function () {
let msg = this.msg;
//recv是自定义的事件
this.$emit('recv', msg)
},
},
// watch: {
// msg:function () {
// this.$emit('recv', msg)
// }
// }
});
new Vue({
el:'#app',
data:{
title:'父组件定义的标题'
},
methods:{
get_title:function (msg) {
this.title = msg
}
}
})
</script>
</body>
</html>