Vue组件化开发相应知识点
1.组件注册
1.1 全局注册
通过 Vue.component('组件名‘,{}) 方法进行注册;全局注册的组件任何实例都能使用。
基本实例代码如下:
<div id="app">
<button-counter></button-counter>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
Vue.component('button-counter', {
// data 是一个函数 返回后一个对象,数据存储于对象中
data: function(){
return {
count: 0
}
},
// 组件的模板必须是只有一个根元素,内容也可以是模板字符(``)串形式
template: '<button @click="handle">点击了{
{count}}次</button>',
methods: {
handle: function(){
this.count += 2;
}
}
})
var vm = new Vue({
el: '#app',
data: {
}
});
</script>
1.2 局部注册
局部注册的组件只能在当前实例中使用。
基本实例代码如下:
<div id="app">
<test-com></test-com>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
Vue.component('test-com',{
// 不会显示helloworld,因为hello-world组件是在vm中注册的
template: '<div>Test<hello-world></hello-world></div>'
});
var HelloWorld = {
data: function(){
return {
msg: 'HelloWorld'
}
},
template: '<div>{
{msg}}</div>'
};
var vm = new Vue({
el: '#app',
data: {
},
// 注册局部组件
components: {
'hello-world': HelloWorld,
}
});
2. Vue组件之间传值
2.1 父组件向子组件传值
父组件通过在模板中绑定相应的数据到子组件上,在子组件中使用props接收父组件传递来的值;直接嵌入html的组件,props中若使用驼峰的形式,在绑定数据的时候则需要使用短横线形式绑定,而使用字符串则无需考虑此类型的限制。
<div id="app">
<div>{
{
pmsg}}</div>
<menu-item :menu-title='ptitle'></menu-item>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/*
父组件向子组件传值-props属性名规则
*/
Vue.component('third-com', {
props: ['testTile'],
template: '<div>{
{testTile}}</div>'
});
Vue.component('menu-item', {
props: ['menuTitle'],
template: '<div>{
{menuTitle}}<third-com testTile="hello"></third-com></div>'
});
var vm = new Vue({
el: '#app',
data: {
pmsg: '父组件中内容',
ptitle: '动态绑定属性'
}
});
</script>
2.2 子组件向父组件传值
在子组件用$emit()
触发事件,$emit()
第一个参数为 自定义的事件名称 第二个参数为需要传递的数据,父组件中需要使用v-on监听子组件的事件,事件名称与子组件中自定义的事件名称一致。
<div id="app">
<div :style='{fontSize: fontSize + "px"}'>{
{
pmsg}}</div>
<menu-item @enlarge-text='handle($event)'></menu-item>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/*
子组件向父组件传值-携带参数
*/
Vue.component('menu-item', {
props: ['parr'],
template: `
<div>
<button @click='$emit("enlarge-text", 10)'>扩大父组件中字体大小</button>
</div>
`
});
var vm = new Vue({
el: '#app',
data: {
pmsg: '父组件中内容',
fontSize: 10
},
methods: {
// val为$emit()中传递过来的参数(可以是对象、数组)
handle: function(val){
// 扩大字体大小
this.fontSize += val;
}
}
});
</script>
2.3 兄弟组件之间传值
兄弟之间传递数据需要借助于事件中心,通过事件中心(提供事件中心 var hub = new Vue())传递数据;传递数据方,通过一个事件触发hub. e m i t ( 方 法 名 , 传 递 的 数 据 ) , 接 收 数 据 方 , 通 过 在 m o u n t e d ( ) 钩 子 函 数 中 触 发 h u b . emit(方法名,传递的数据),接收数据方,通过在mounted(){} 钩子函数中触发hub. emit(方法名,传递的数据),接收数据方,通过在mounted()钩子函数中触发hub.on()方法名;在数据传递结束后可以销毁事件 通过hub.$off()方法名销毁之后无法进行传递数据。
<div id="app">
<div>父组件</div>
<div>
<button @click='handle'>销毁事件</button>
</div>
<test-tom></test-tom>
<test-jerry></test-jerry>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/*
兄弟组件之间数据传递
*/
// 提供事件中心
var hub = new Vue();
Vue.component('test-tom', {
data: function(){
return {
num: 0
}
},
template: `
<div>
<div>TOM:{
{num}}</div>
<div>
<button @click='handle'>点击</button>
</div>
</div>
`,
methods: {
handle: function(){
hub.$emit('jerry-event', 2);
}
},
mounted: function() {
// 监听事件
hub.$on('tom-event', (val) => {
this.num += val;
});
}
});
Vue.component('test-jerry', {
data: function(){
return {
num: 0
}
},
template: `
<div>
<div>JERRY:{
{num}}</div>
<div>
<button @click='handle'>点击</button>
</div>
</div>
`,
methods: {
handle: function(){
// 触发兄弟组件的事件
hub.$emit('tom-event', 1);
}
},
mounted: function() {
// 监听事件
hub.$on('jerry-event', (val) => {
this.num += val;
});
}
});
var vm = new Vue({
el: '#app',
data: {
},
methods: {
handle: function(){
hub.$off('tom-event');
hub.$off('jerry-event');
}
}
});
</script>
3.组件插槽
组件的最大特性就是复用性,而用好插槽能大大提高组件的可复用能力。在子组件中设置默认内容,当父组件不向子组件传递内容时,显示默认内容。
3.1匿名插槽
在子组件中设置默认内容,当父组件不向子组件传递内容时,显示默认内容。
<div id="app">
<alert-box>有bug发生</alert-box>
<alert-box>有一个警告</alert-box>
<alert-box></alert-box>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/*
组件插槽:父组件向子组件传递内容
*/
Vue.component('alert-box', {
template: `
<div>
<strong>ERROR:</strong>
<slot>默认内容</slot>
</div>
`
});
var vm = new Vue({
el: '#app',
data: {
}
});
</script>
3.2 具名插槽
在slot 标签中使用name绑定相应的元素;而使用template标签能够将多个信息合并传递到某一插槽。
<div id="app">
<base-layout>
<p slot='header'>标题信息</p>
<p>主要内容1</p>
<p>主要内容2</p>
<p slot='footer'>底部信息信息</p>
</base-layout>
<base-layout>
<template slot='header'>
<p>标题信息1</p>
<p>标题信息2</p>
</template>
<p>主要内容1</p>
<p>主要内容2</p>
<template slot='footer'>
<p>底部信息信息1</p>
<p>底部信息信息2</p>
</template>
</base-layout>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/*
具名插槽
*/
Vue.component('base-layout', {
template: `
<div>
<header>
<slot name='header'></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name='footer'></slot>
</footer>
</div>
`
});
var vm = new Vue({
el: '#app',
data: {
}
});
</script>
3.3 作用域插槽
作用域插槽可以在父组件对子组件加工处理,既可以复用子组件的slot,又可以使slot内容不一致。
具体使用:在子组件中定义插槽,通过属性绑定的形式将数据传递到父组件中,而在父组件中需要使用template标签以及它的slot-scope属性获取子组件的数据。如子组件中通过绑定:info 属性,父组件中时使用slot-scope=’father‘接收;当父组件需要对数据进行处理则通过father.info获取数据后进行相应的操作。
<div id="app">
<fruit-list :list='list'>
<template slot-scope='slotProps'>
<strong v-if='slotProps.info.id==3' class="current">{
{
slotProps.info.name}}</strong>
<span v-else>{
{
slotProps.info.name}}</span>
</template>
</fruit-list>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/*
作用域插槽
*/
Vue.component('fruit-list', {
props: ['list'],
template: `
<div>
<li :key='item.id' v-for='item in list'>
<slot :info='item'>{
{item.name}}</slot>
</li>
</div>
`
});
var vm = new Vue({
el: '#app',
data: {
list: [{
id: 1,
name: 'apple'
},{
id: 2,
name: 'orange'
},{
id: 3,
name: 'banana'
}]
}
});
</script>