组件

202002060849

组件化

利用组件化开发,拆分功能,封装组件,单独维护

组件注册

// 定义一个名为 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特性

插槽

<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>

组件事件

当定义子组件时,默认的原生事件监听@xxx不会生效,可以加上.native修饰符

组件使用中的细节

组件化带来的问题

vue-router

import Info from '../views/Info.vue';
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)
})