1.父组件向子组件传递数据:通过props
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<title>vue组件的使用</title>
<style>
body{
color:burlywood;
}
.header{
100%;
height: 40px;
background-color: #333;
line-height: 40px;
text-align: center;
}
.aside{
20%;
height: 1200px;
background-color:chocolate;
float: left;
}
.content{
80%;
height: 1200px;
background-color:crimson;
float: left;
}
.footer{
100%;
height: 40px;
background-color:darkcyan;
text-align: center;
line-height: 40px;
clear: both;
}
</style>
</head>
<body>
<div id='app'></div>
<script>
// 声明组件
var Vheader = {
template : `
<div class='header'>
头部区域
</div>
`,
}
var Vaside = {
template : `
<div class='aside'>
侧边栏区域
</div>
`,
}
var Vcontent = {
// 6.在标签中使用props中的数据
// 通过props传递数据时,若使用了v-for,必须绑定key
template : `
<div class='content'>
<ul>
<li v-for='(title,index) in titles' :key = 'index'>
<h3>{{title}}</h3>
</li>
</ul>
</div>
`,
// 5.通过props从父组件中拿到数据
props:['titles'],
}
var Vfooter = {
template : `
<div class='footer'>
脚部内容
</div>
`,
}
var Vmain = {
// 4.在当前组件中绑定属性,将从父组件中拿到的数据传入自己的子组件中
template : `
<div class='main'>
<Vheader/>
<Vaside/>
<Vcontent :titles = 'titles'/>
<Vfooter/>
</div>
`,
components:{
Vheader,
Vaside,
Vcontent,
Vfooter,
},
// 3.通过props从当前组件的父组件拿数据
props:['titles'],
}
new Vue({
el:'#app',
// 1.在data中声明数据
data(){
return{
titles:['标题一','标题二','标题三','标题四'],
}
},
// 使用组件
// 2.在父组件中绑定属性,将data中的数据传到子组件中
template:`
<Vmain :titles = 'titles'></Vmain>
`,
// Vue实例化对象的template中需要一个包裹所有元素的根元素,否则会报错
// 挂载组件
components:{
Vmain,
}
})
</script>
</body>
</html>
2.子组件向父组件传递数据:通过自定义事件
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<title>vue组件的使用</title>
<style>
body{
color:burlywood;
}
.header{
100%;
height: 40px;
background-color: #333;
line-height: 40px;
text-align: center;
}
.aside{
20%;
height: 1200px;
background-color:chocolate;
float: left;
}
.content{
80%;
height: 1200px;
background-color:crimson;
float: left;
}
.footer{
100%;
height: 40px;
background-color:darkcyan;
text-align: center;
line-height: 40px;
clear: both;
}
</style>
</head>
<body>
<div id='app'></div>
<script>
var Vheader = {
template : `
<div class='header'>
头部区域
</div>
`,
}
var Vaside = {
// 1.在html标签中绑定原生js事件
template : `
<div class='aside'>
工具
<br/>
<button @click='addFontSize'>字体+</button>
</div>
`,
methods:{
// 2.在methods中声明所使用的方法
addFontSize(){
// 3.调用内建的this.$emit()方法触发父组件的自定义事件
// this.$emit()方法,可传入两个参数,第一个参数时事件名称,第二个参数是传入事件的参数
this.$emit('addFontSize');
}
},
}
var Vcontent = {
template : `
<div class='content'>
<ul>
<li v-for='(title,index) in titles' :key = 'index'>
<h3>{{title}}</h3>
</li>
</ul>
</div>
`,
props:['titles'],
}
var Vfooter = {
template : `
<div class='footer'>
脚部内容
</div>
`,
}
var Vmain = {
// 5.在template中绑定自定义事件传给子组件
template : `
<div class='main' :style='{fontSize:fontSize+"px"}'>
<Vheader/>
<Vaside @addFontSize='addFontSize'/>
<Vcontent :titles = 'titles'/>
<Vfooter/>
</div>
`,
components:{
Vheader,
Vaside,
Vcontent,
Vfooter,
},
// 注意:data必须是一个函数
data(){
return {
fontSize:16,
}
},
methods:{
// 4.在methods中自定义事件
addFontSize(){
this.fontSize += 1;
}
},
props:['titles'],
}
new Vue({
el:'#app',
data(){
return{
titles:['标题一','标题二','标题三','标题四'],
}
},
template:`
<Vmain :titles = 'titles'></Vmain>
`,
components:{
Vmain,
}
})
</script>
</body>
</html>
3.平行组件通信:创建bus实例,通过bus挂载($on)和调用($emit)事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <App></App> </div> <script src="./vue.js"></script> <script> //1.实例化一个bus对象 const bus = new Vue(); // 中央事件总线 bus Vue.component('B', { data() { return { count: 0 } }, template: ` <div>{{count}}</div> `, created(){ // 2. $on 绑定事件 bus.$on('add',(n)=>{ this.count+=n; }) } }) Vue.component('A', { template: ` <div> <button @click='handleClick'>加入购物车</button> </div> `, methods:{ handleClick(){ // 3.触发绑定的函数 // $emit 触发事件 bus.$emit('add',1); } } }) const App = { template: ` <div> <A></A> <B></B> </div> `, } new Vue({ el: '#app', components: { App } }) </script> </body> </html>
4.嵌套组件通信,父组件 provide来提供变量,然后再子组件中通过inject来注入变量.无论组件嵌套多深
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <App></App> </div> <script src="./vue.js"></script> <script> Vue.component('B', { data() { return { count: 0 } }, inject:['msg'], created(){ console.log(this.msg); }, template: ` <div> {{msg}} </div> `, }) Vue.component('A', { created(){ console.log(this); }, template: ` <div> <B></B> </div> ` }) const App = { data() { return { title:"老爹" } }, provide(){ return { msg:"老爹的数据" } }, template: ` <div> <A></A> </div> `, } new Vue({ el: '#app', components: { App } }) </script> </body> </html>
5.$parrent $children