组件
组件化
利用组件化开发,拆分功能,封装组件,单独维护
组件注册
// 定义一个名为 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)})