组件
- 定义组件
- 组件通信
- 插槽slot实现分发内容
- 高级组价
组件定义
全局注册组件
Vue.compoment('组件名称',{
组件内容,最外层只能被一个元素包围;
template:组件模板,内容为组件文档内容
});
Vue.component('my-com', {
template: `
<div>
<h3>全局组件</h3>
<div>
<p>内容1</p>
<p>内容2</p>
</div>
</div>
`
});
局部组件
跟全局组件定义一样,局部组件就是把全局组件内部的{}抽离开来,然后赋值给一个变量,再将赋值后的变量注册到new vue中的components下,这样定义的组件就是一个简单的局部组件了。
var child_com = {
template: `
<div>
<h3>局部组件</h3>
<div>
<p>局部组件内容</p>
</div>
</div>
`
};
var vm = new Vue({
el: '#app',
components: {
child_com
}
});
组件通信
一般的组件通信方式有一下三种:
- 父子组件
- 兄弟组件、跨级组件
示意图:
父子组件通信
<body>
<div id="app">
<child-com :info="info" @say="childSay"></child-com>
</div>
<script>
var childCom = {
template: `
<div>
<h3>{{info.title}}</h3>
<div>
<p>{{info.desc}}</p>
</div>
<button @click='say'>通知父组件</button>
</div>
`,
props: {
info: {
type: Object
}
},
methods: {
say() {
this.$emit('say', '我被点击了');
}
}
};
var vm = new Vue({
el: '#app',
data() {
return {
info: {
title: '头部内容',
desc: '展示内容'
}
}
},
components: {
'child-com': childCom
},
methods: {
childSay(params) {
alert(params);
}
}
});
</script>
</body>
父子通信如上所述:
父组件通过:info="info"向下传递给子组件childCom,子组件通过props接受来自父组件信息,
然后子组件又通过this.$emit('say', '我被点击了');中的$emit向父组件提交一个say,父组件
通过 @say="childSay",拿到子组件传的通信,这样一个简单的父子组件通信就完成了。
注意:这里需要注意的是:
- 子组件通过props接受父组件信息时,props的对应属性值一定要跟父组件传过来的一样,比如上式的info
- 父组件接受来自子组件信息时,也一样,绑定的事件要跟子组件的一样,如上述中的@say="childSay"中的say要跟子组件this.$emit('say', '我被点击了');中的say一样。
兄弟组件、跨级组件
对于简单的兄弟组件,可以采用事件中间件形式,也通过一个创建一个空的Vue实例,并通过这个实例信息。
如下:
<body>
<div id="app">
<child-a></child-a>
<child-b></child-b>
</div>
<script>
var bus = new Vue();
var childA = {
template: `
<div>
<h3>组件1</h3>
<button @click='childAMethos'>兄弟组件通信</button>
</div>
`,
methods: {
childAMethos() {
bus.$emit("aInfo", '组件A给你传递信息了');
}
}
}
var childB = {
template: `
<div>
<h3>组件2</h3>
</div>
`,
mounted () {
bus.$on('aInfo', function (id) {
alert(id);
})
}
}
var vm = new Vue({
el: '#app',
components: {
'child-a': childA,
'child-b': childB,
}
});
</script>
</body>
组件childA通过 bus.$emit("aInfo", '组件A给你传递信息了');给组件childB传递数据aInfo,
组件childB通过 bus.$on('aInfo', function (id) {alert(id);})接受来及组件childA的数据.
更复杂的组件通信可以使用vuex做状态管理,关于vuex接下来会专门写一篇文章单独介绍。
想了解的可以移步到状态管理模式
插槽slot实现分发内容
实现组件的内容分发主要是通过slot插槽的方式进行。
- 单个插槽
- 具名插槽
- 作用域插槽
1.单个插槽
<body>
<div id="app">
<child-a>
<h3>标题</h3>
<p>文本内容</p>
</child-a>
</div>
<script>
var bus = new Vue();
var childA = {
template: `
<div>
<slot>33333333333</slot>
</div>
`,
}
var vm = new Vue({
el: '#app',
components: {
'child-a': childA,
}
});
</script>
</body>
只有一个slot插槽的称为单个插槽,使用slot时注意:
- 当slot存在内容时,若调用组件的父组件存在内容,则slot的内容会被覆盖掉,
如上述的 child-a的内容会覆盖childA中slot下的内容只显示,<div><h3>标题</h3><p>文本内容</p></div>
如图:
2.具名插槽
<body>
<div id="app">
<child-a>
<h3 slot="header">标题</h3>
<p slot="cont">文本内容</p>
</child-a>
</div>
<script>
var bus = new Vue();
var childA = {
template: `
<div>
<h3>
<slot name="header"></slot>
</h3>
<section>
<slot name="cont"></slot>
</section>
</div>
`,
}
var vm = new Vue({
el: '#app',
components: {
'child-a': childA,
}
});
</script>
</body>
具名插槽主要是,组件中在slot标签中定义一个name的属性,这个属性的名称就是引用此组件时对应的属性slot中的名称。
比如上述中的childA组件中的插槽<slot name="header"></slot><slot name="cont"></slot>中name的名称分别是引用组件<child-a><h3 slot="header">标题</h3><p slot="cont">文本内容</p></child-a>中slot对应的名称。
3.作用域插槽
<body>
<div id="app">
<child-a>
<template slot-scope="scope">
<h3>作用域插槽</h3>
<p>{{scope.desc}}</p>
</template>
</child-a>
</div>
<script>
var bus = new Vue();
var childA = {
template: `
<div>
<h3>
<slot desc="这是作用域插槽内容"></slot>
</h3>
</div>
`,
}
var vm = new Vue({
el: '#app',
components: {
'child-a': childA,
}
});
</script>
</body>
作用域插槽主要是用在可重用模板中
上述中的在子组件childA中定义<slot desc="这是作用域插槽内容"></slot>,name在父组件中调用子组件childA时,就可以通过设定作用域template的slot-scope属性来获取子组件childA内desc的信息。
源码地址:https://github.com/wqb2017/my...
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。