什么是组件
- 每一个组件都是一个vue实例
- 每个组件均具有自身的模板template,根组件的模板就是挂载点
- 每个组件模板只能拥有一个根标签
- 子组件的数据具有作用域,以达到组件的复用
根组件
<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>
<div id="app">
<abc></abc>
<abc></abc>
<abc></abc>
</div>
<hr>
<div id="main">
<local-tag></local-tag>
<local-tag></local-tag>
</div>
</body>
<script src="js/vue.js"></script>
<script>
// 局部组件
var localTag = {
// 子组件的数据具有作用域,以达到组件的复用, 每一个复用的组件具有自身独立的一套数据
data: function () {
return { // 返回值是一个数据字典(一套数据)
count: 0
}
},
template: "<div @click='fn'>点击{{ count }}次</div>",
methods: {
fn: function () {
this.count += 1;
}
}
} // app根组件
new Vue({
el: "#app",
// 注册
components: {
'abc': localTag
}
})
// main根组件
new Vue({
el: "#main",
components: {
// localTag js中键值一样可以简写,只写一个就行 这样写比较装十三,一般不知道js标识符于css/html标识符的相互转换的可能不知道
'local-tag': localTag
}
})
</script>
全局组件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>全局组件</title>
</head>
<body>
<div id="app">
<global-tag></global-tag>
</div>
<div id="main">
<global-tag></global-tag>
</div>
</body>
<script src="js/vue.js"></script>
<script>
// 创建全局组件
Vue.component('global-tag', {
template: "<div @click='fn'>全局组件点击了 {{ count }} 次</div>",
data: function () {
return {
count: 0
}
},
methods: {
fn: function () {
this.count++;
}
}
}); new Vue({
el: "#app",
});
new Vue({
el: "#main",
});
</script>
</html>
父组件传递数据给子组件
通过绑定属性的方式进行数据传递
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>组件通信父到子</title>
</head>
<body>
<div id="app">
<input type="text" v-model="sup_data"> <global-tag :abcde="sup_msg" :sup_data="sup_data"></global-tag>
</div>
</body>
<script src="js/vue.js"></script>
<script>
// 创建全局组件
Vue.component('global-tag', {
props: ['abcde', 'sup_data'],
template: "<div @click='fn'>{{ abcde }}</div>",
data: function () {
return { }
},
methods: {
fn: function () {
alert(this.sup_data)
}
}
});
// 将父组件的信息传递给子组件
// 采用属性绑定的方式: 1,父级提供数据 2.绑定给子组件的自定义属性 3.子组件通过props的数组拿到自定义属性从而拿到数据
new Vue({
el: "#app",
data: {
sup_msg: "父级的msg",
sup_data: ""
}
});
</script>
</html>
子组件传递数据给父组件
通过发送事件请求的方式进行数据传递
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>组件通信子到父</title>
</head>
<body>
<div id="app">
<!-- abc为子组件的自定义事件,该事件的含义要在子组件内容声明规定 -->
<global-tag @abc="action"></global-tag>
<global-tag @abc="action"></global-tag>
{{ sup_info }}
</div> </body>
<script src="js/vue.js"></script>
<script>
// 创建全局组件
Vue.component('global-tag', {
template: "<div><input v-model='info'><p @click='sendMsg'>子组件</p></div>",
data: function () {
return {
info: "",
msg: "子组件的信息"
}
},
methods: {
sendMsg: function () {
// alert(123)
// 激活自定义事件 abc
this.$emit('abc', this.msg, this.info)
}, }
});
// 将子组件的信息传递给父组件
// 采用发生事件的方式:
// 1.在子组件的内容系统事件中来定义一个自定义事件,采用$emit发生到自定义组件名上(可以携带子组件内容数据)
// 2.在父组件复用子组件时, 实现子组件自定义数据的功能, 在父组件中的methods中为功能绑定函数(函数的参数就是携带出来的数据)
// 3.当在组件内部激活系统事件,就会激活自定义事件,$emit发生给父级,激活父级绑定的函数,该函数被执行,同时拿到数据
new Vue({
el: "#app",
data: {
sup_info: ""
},
methods: {
action: function (msg, info) {
alert(msg)
this.sup_info = info
}
}
});
</script>
</html>
组件实现留言板
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>留言板</title>
<style>
ul {
margin: 0;
padding: 0;
}
a {
color: black;
text-decoration: none;
display: block;
height: 21px;
}
p {
margin: 0;
color: orange;
float: left;
}
span {
color: red;
float: right;
}
</style>
</head>
<body>
<div id="app">
<input type="text" v-model="msg">
<button @click="btnClick">留言</button>
<hr>
<ul>
<!-- 如果每一个渲染的列表项是一个相对复杂的结构, 该复杂的结构可以封装成组件 -->
<li v-for="(v, i) in list">
<global-tag :value="v" :index="i" @delete="delAction"></global-tag>
</li>
</ul>
<!--<ul>-->
<!--<li v-for="(v, i) in list2">-->
<!--<global-tag :value="v" :index="i" @delete="delAction"></global-tag>-->
<!--</li>-->
<!--</ul>-->
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
msg: "",
list: [],
list2: []
},
methods: {
btnClick: function () {
if (this.msg) {
this.list.push(this.msg);
this.msg = "";
}
},
delAction: function (index) {
this.list.splice(index, 1)
}
}
}); Vue.component('global-tag', {
props: ['value', 'index'],
template: "<a href='javascript:void(0)'><p>{{ value }}</p><span @click='sendDel'>x</span></a>",
methods: {
sendDel: function () {
this.$emit('delete', this.index)
}
}
});
</script>
</html>