3、组件

组件

组件就是实现应用局部功能代码和资源集合

声明并注册Vue组件的三种方式

组件必须在vue实例管理的元素范围内使用,是用Vue.extend可以构造出来一个VueComponent实例

组件中,Data必须是一个函数data(),返回一个对象,对象内部保存数据,避免多个组件实例之间的data互相干扰

1、先用Vue.extend声明组件构造,再将模板注册为全局组件

<div id="d1">
    <!-- 4、使用组件 -->
    <com1></com1>
</div>
<script>
    //1、声明组件
    let temp = Vue.extend({
        //在es6中,可以使用fj'yn``来定义字符串,这个字符串可以换行,不需要拼接
        template:`
                <form>
					uname:<input />
                    upwd:<input />
                    <button>add</button>
                </form>
                `,
        data(){
            return{}
        },
        name:"temp"
    });
    //2、注册为全局组件Vue.xomponent("组件名",组件对象)
    Vue.component("com1",temp);
    //3、挂载元素
    let v = new Vue({
        el:"#d1"
    })
</script>

2、直接将模板注册为全局组件

<div id="d1">
    <!-- 3、使用组件 -->
    <com1></com1>
</div>
<script>
    //1、声明并注册为全局组件,Vue会自动调用extenddv进行构造
    Vue.component("com1",{
        temlate:`
                <form>
					uname:<input />
                    upwd:<input />
                    <button>add</button>
                </form>
                `
    });
    //2、挂载元素
    let v = new Vue({
        el:"#d1"
    })
</script>

3、在html、vue代码中使用

<template>标签中,只可以有一个根标签,不然除了第一个根标签中内容,其他的不会显示

<template>标签也可以使用<script type="text/x-template"></script>替代

<div id="d1">
    <!-- 4、使用组件 -->
    <com1></com1>
</div>
<!-- 1、编写模板 -->
<template id="temp">
    <form>
        uname:<input />
        upwd:<input />
        <button>add</button>
    </form>
</template>
<script>
    //2、注册为全局组件
    Vue.component("com1",{
        temlate:"#temp"
    });
    //3、挂载元素
    let v = new Vue({
        el:"#d1"
    })
</script>

全局组件和局部组件的区别

重要内置关系

//VueComponent显示原型属性的隐式原型属性等于Vue的显示原型属性
VueComponent.prototype.__proto__ === Vue.prototype

这个关系的作用:让所有组件实例对象可以访问到Vue原型上的属性、方法

image-20220419160329816

单文件组件

<!-- 组件的模板 -->
<template>

</template>
<!-- 组件的js部分 -->
<script>
export default {
    name: "App",
    components: {
       
    },
    data() {
        return {
           
        };
    },
}
</script>
<!-- 组件的样式部分 -->
<style>

</style>

style

1、lang属性

css:默认可以解析原生css

less:脚手架需要安装less-loader

2、scoped属性

在多个组件中声明的style标签中的样式,最终会汇集到一起,这就导致了,如果样式中出现了同名的id、class,会发生冲突,为了解决这个问题,就需要使用scoped,这个属性不适合用与App组件

<!-- 在style标签上添加scoped属性即可 -->
<style scoped></style>

组件化编码流程

1、实现静态组件、抽取组件,使用组件实现静态页面效果

2、实现动态组件、并且考虑数据存放位置,操作数据的方法优先和数据放在一起

3、实现交互功能

组件的切换

可以使用标签<component>作为组件的载体,使用:is="componentName"设置搭载的组件

<div id="div1">
    <button @click="comName='com1'">temp1</button>
    <button @click="comName='com2'">temp2</button>
    <component :is="comName"></component>
</div>

<template id="temp1">
    <h1>This is temp1</h1>
</template>
<template id="temp2">
    <h1>This is temp2</h1>
</template>

<script>
    Vue.component("com1",{
        template:"#temp1"
    })
    Vue.component("com2",{
        template:"#temp2"
    })
    let v = new Vue({
        el:"#div1",
        data:{
            comName:"com1"
        }
    })
</script>

mixin混入

对于多个组件公用的配置项,可以抽离出来,声明一个独立的js文件

如果混合中声明了data、methods,那么会将混合中声明的和组件声明的混合一起,全部生效;如果混合中声明了mounted等钩子,那么会都执行

export default {
    //钩子函数,用于打印组件加载情况
    mounted () {
        console.log("组件",this.$options.name,"加载完成")
    }
}

在组件中进行局部引入,并且使用

//引入
import m from '../mixin/mixin'
export default {
    name: "Login",
    //使用
    mixins:[m]
}

也可以在main.js中进行全局引入混合

//引入
import m from '../mixin/mixin'
//声明全局混合,所有组件都会生效,可以声明多个Vue.mixin()
Vue.mixin(m);

插件

vue支持自定义插件,并且在main.js中,可以使用Vue.use(plugin)进行开启

定义插件(本质就是一个对象中,包含一个install函数,该函数接收Vue构造函数作为参数):

export default {
    install(Vue){
        //定义全局过滤器
        Vue.filter("priceFormat",function(value){
            return value + "元";
        })
        //定义全局指令
        Vue.directive("log",function(element,binding){
            console.log("自定义指令");
            console.log(element);
            console.log(binding);
        })
        //在Vue原型上添加函数,所有组件实例都可调用
        Vue.prototype.hello = function(){
            console.log("hello")
        }
    }
}

main.js中引入插件js,并且进行开启

//引入插件
import p from './plugin.js';
//开启插件,可以开启多个
Vue.use(p);