组件
组件化
利用组件化开发,拆分功能,封装组件,单独维护
组件注册
// 定义一个名为 button-counter 的全局组件
Vue.component('button-counter', {
data: function () {
// data必须是一个函数,如果data是一个对象的话,那么所有button-counter都会共享同一份数据
return { count: 0 }
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
});
new Vue({ el: '#app' });
<!-- 使用自定义组件,必须使用短横线的方式使用组件 -->
<button-counter></button-counter>
- 局部注册
new Vue({
el: '#app' ,
components:{
'compomenta':{
template:`
<div>componenta</div>
`
}
}
});
组件通信
- 父子组件通信
const introduce = {
template:'<h1 @click="fun()">{{msg}}</h1>',
methods: {
fun() {
// 触发上一层事件,第一个参数是事件名称,第二个参数是传递给父组件的参数
this.$emit('delete',"delete it");
}
},
props:['msg'] // 子组件需要声明要接收的参数
}
new Vue({
el: '#app',
data:{ msg:'大家好,我是渣渣辉' },
methods: {
handleDelete(args) { console.log(args); }
},
components:{ introduce }
});
<div id="app">
<!-- 父组件向子组件传递msg -->
<!-- 父组件监听子组件的delete事件 -->
<introduce :msg="msg" @delete="handleDelete"></introduce>
</div>
- 兄弟组件通信
使用一个事件中心,这个事件中心可以监听事件、触发事件
var hub = new Vue();
// 注册事件
hub.$on('event', (val) => {
this.num += val;
});
// 触发事件
hub.$emit('event', 2);
// 销毁事件
hub.$off('event');
组件参数校验
//...
props: {
// 要求传递过来的msg必须是String类型
msg: String,
id: [Number,String], // 可以是数字或者字符串类型
content: {
type: String,
required: false, // 非必传
defaultValue: 'cxk', // required必须为false这个值才会生效
validator: function(val) {
// 自定义校验器
retrun val.length === 3;
}
}
}
非props特性
- 父组件向子组件传递参数,但是子组件没在props声明接收,所以子组件就无法使用
- 非props特性的属性声明会在dom中显示
插槽
<child>
<!-- 给插槽起名 -->
<div slot='header'>header</div>
<div slot='footer'>footer</div>
<!-- 下面这个没有名字,所以会匹配到第一个slot(没有名字) -->
<div>no name</div>
</child>
'child':{
template: `
<div>
<slot></slot>
<slot name="header">default value</slot>
<slot name="footer"></slot>
</div>
`
}
动态组件
<component v-bind:is="currentTabComponent"></component>
- 添加v-once来提高性能
组件事件
当定义子组件时,默认的原生事件监听@xxx
不会生效,可以加上.native
修饰符
组件使用中的细节
- 使用
is='componentName'来解决html结构问题
- 子组件的data应该是一个函数,如果是对象的话,则所有的子组件的data都是共享的
- 可以通过ref来获取到子组件的引用
组件化带来的问题
- 组件状态管理(vuex)
- 多组件混合使用(vue-router)
- 组件间的合作(props,emit/on,bus)
vue-router
- 引入vue组件
import Info from '../views/Info.vue';
- 在router中添加
const routes = [
//...
{
path: '/info',
name: 'info',
component: Info,
},
];
单文件组件
<template>
<!-- 组件代码区域 -->
</template>
<script>
// js代码区域
export default {
...
}
</script>
<style scoped>
/* 样式代码区域 */
</style>
- 安装
npm install vue-loader vue-template-compiler vue -D
- 配置
const VueLoaderPlugin = require("vue-loader/lib/plugin");
const vuePlugin = new VueLoaderPlugin();
module.exports = {
....
plugins:[
...
new vueLoader()
],
module : {
rules:[
...
{
test:/\.vue$/,
loader:"vue-loader"
}
]
}
}
- 使用
import Vue from 'vue';
import App from './App.vue';
const vm = new Vue({
el:'#app',
render:h=>h(App)
})