vue组件的一个总结

来源:互联网 发布:华夏免费版数据库 编辑:程序博客网 时间:2024/05/20 04:29

组件的介绍

全局组件

使用Vue.component进行全局注册,所有vue实例都会共享此组件

复制代码
 1   <div id="app"> 2         {{msg}} 3         <const-comp></const-comp> 4      5     </div> 6     <script> 7          8         Vue.component('constComp', { 9             template: "<h3>我是全局组件</h3>"10 11         });12 13         new Vue({14             el: "#app",15             data: {16                 msg: "hello component"17             }18         });19 20     </script>
复制代码

局部组件

局部组件只能在引入当前的vue实例中有效,在当前vue实例中components属性加上引入进来的组件实例即可

复制代码
    <div id="app">        {{msg}}        <!-- <const-comp></const-comp> -->        <local-comp></local-comp>    </div>    <script>                /*Vue.component('constComp', {            template: "<h3>我是全局组件</h3>"        });*/        let localComp = {            template: "<div>我是局部组件</div>"        };        new Vue({            el: "#app",            data: {                msg: "hello component"            },            components: {                localComp            }        });    </script>    
复制代码

单文件组件(xxx.vue)

其实就是将写在js中的组件提出到一个vue文件中写而已,这样组件更加的好维护以及阅读性也会好,提取出来了相应的引入即可,不会显得文件很多行很长。

其主要有<template></template><script></script><style></style>这三个标签,每个标签做自己的事。template就像我们在html中写dom,script写js代码当前的组件实例,style写组件样式,注意:加上scoped即可使当前样式只在当前组件生效,组件渲染的时候此组件的dom会加上data-v-xxx属性来选择当前组件样式。如果没加上scoped的话当前组件的样式就会在引入这个组件的实例中造成影响

如我写的一个found.vue文件demo

 View Code

组件的通信

vue组件的通信是vue组件的核心,组件不仅仅是要把模板的内容进行复用;更主要的是组件间要进行通信;组件之间的通信数据传递是组件的生命力之一。

props单向数据流,父组件向子组件传递数据

props可以是一个数据类型也可以是一个数组,也可以是对象,对象下的数据有3个属性type,default,require。其中default,require值都是布尔类型值。type有Number,String,Boolean,Array,Object,Function,Symbol。如果props数据是对象或数组时默认值default必须是一个函数来返回初始化数据。而且因为对象或数据是引用类型,指向的是同一个内存空间所以当props数据是这两个类型时,数据改变时子组件内改变是会影响父组件的。

 props数据类型及相关样例

 View Code

这里稍微改动一下局部组件的代码,父组件向子组件传递数据;

复制代码
 1    <div id="app"> 2         {{msg}} 3         <!-- <const-comp></const-comp> --> 4         <local-comp :props-a="info"></local-comp> 5     </div> 6     <script> 7          8         /*Vue.component('constComp', { 9             template: "<h3>我是全局组件</h3>"10 11         });*/12         let localComp = {13             template: "<div>我是局部组件<p>父组件传过来的数据为-->{{propsA}}</p></div>",14             props: {15                 propsA: {16                     type: String,17                     default: "",18                     require: true19                 }20             }21         };22         new Vue({23             el: "#app",24             data: {25                 msg: "hello component",26                 info: "hello props"27             },28             components: {29                 localComp30             }31         });32 33     </script>
复制代码

 

自定义事件$emit,子组件向父组件通信

这里还是在原来的基础上改,子组件使用$emit自定义一个send事件向父组件发送数据

复制代码
 1    <div id="app"> 2         {{msg}} 3         <!-- <const-comp></const-comp> --> 4         <div>子组件数据为---->{{fromChildData}}</div> 5         <local-comp :props-a="info" @send="getChildData"></local-comp> 6     </div> 7     <script> 8          9         /*Vue.component('constComp', {10             template: "<h3>我是全局组件</h3>"11 12         });*/13         let localComp = {14             template: "<div>我是局部组件\15                     <p>父组件传过来的数据为-->{{propsA}}</p>\16                     <button @click='sendMsg'>使用$emit子组件向父组件传递事件</button>\17                 </div>",18             props: {19                 propsA: {20                     type: String,21                     default: "",22                     require: true23                 }24             },25             data() {26                 return {27                     msg: "子组件数据"28                 }29             },30             methods: {31                 sendMsg(evt) {32                     this.$emit('send', this.msg);33                 }34             }35         };36         new Vue({37             el: "#app",38             data: {39                 msg: "hello component",40                 info: "hello props",41                 fromChildData: ""42             },43             components: {44                 localComp45             },46             methods: {47                 getChildData(val) {48                     this.fromChildData = val49                 }50             }51         });52 53     </script>
复制代码

 

非子父组件通信,使用一个空的Vue实例作为一个事件总线监听数据变化

这种场景用于组件之间不为子父层级关系的时候相关通信,我们使用的那个空vue实例里也可以放vue的属性。用这个空的vue实例来$emit自定义一个事件然后再用这个实例来$on监听自定义事件,从而达到非子父组件之间的通信。(PS:这里暂时不讨论vuex),看demo代码。demo例子使用了ref组件索引。

复制代码
    <div id="app">        {{message}}        <component-a ref="a"></component-a>        <component-a ref="b"></component-a>    </div>    <script>        const bus = new Vue({});        Vue.component('component-a', {            data () {                return {                    msg: 1                }            },            template: '<button @click="handleEvent">传递事件</button>',            methods: {                handleEvent () {                    bus.$emit('on-message', '来自组件 com-a 的内容');                }            }        });        const app = new Vue({            el: '#app',            data: {                message: ''            },            mounted () {                bus.$on('on-message', (msg) => {                    this.message = msg;                });                this.$children.msg = 2;            }        })    </script>
复制代码

slot组件内容分发

单个就默认slot,多个使用具名slot,$slots访问对应slot,vue2.0新增;因为vue2使用render函数来渲染,所以需要使用this.$slots来访问slot。this.$slots.xxx访问具体的slot,即slot中name指定的值 值类型{ [name: string]: ?Array<VNode> }

如果需要给slot添加默认内容的时候直接在slot上写就可以了,这个时候默认的slot内容所在的作用域就是其所在的组件实例,可以根据其所在的组件来控制slot默认的内容展示如:<slot>{{msg}}</slot>。如果没有指定默认数据的话slot内容根据其父组件所在的作用域。

当 vue 组件中当需要组件混合使用的时候需要用到内容分发,内容不确定的时候需要用到slot内容分发。

看demo代码;

复制代码
 1        <div id="app"> 2         <com-out> 3             <div slot="b">{{msgB}}</div> 4             <div slot="a">{{msgA}}</div> 5              6         </com-out> 7     </div> 8     <template id="co"> 9         <div>10             hello 11             <slot name="a"></slot> 12             <slot name="b"></slot>13         </div>14     </template>15     <script>16         Vue.component('com-out', {17             template: "#co",18             mounted() {19                 console.log("com-out slot" + this.$slots.a[0]);20             }21         });22         new Vue({23             el: "#app",24             data: {25                 msgA: '父组件数据a',26                 msgB: '父组件数据b'27             }28         })29     </script>    
复制代码

递归组件

递归组件要记住两点:

1.递归组件必须要给组件设置name。

2.要在一个合适的时间(条件)跳出递归否则会报栈溢出异常。

复制代码
 1 <div id="app"> 2         <com :count="1"></com> 3     </div> 4     <template id="cr"> 5         <div><com :count="count + 1" v-if="count < 3"></com>{{count}}</div> 6     </template> 7     <script> 8         Vue.component('com', { 9             name: 'comr',10             template: "#cr",11             props: {12                 count: {13                     type: Number,14                     default: 115                 }16             }17         })18         new Vue({19             el: '#app'20         })21 22 23     </script>
复制代码

动态组件

vue动态组件其实就是在组件中使用:is属性根据值来判断显示哪个组件。

复制代码
 1 <div id="app">   2         <button @click="changeCom">点击让子组件显示</button>   3         <com v-bind:is="activeCom"></com>   4     </div>   5 <script>   6     new Vue({   7         el: '#app',   8         data: {   9             activeCom: "comA"  10         },  11         methods: {  12             changeCom: function () {   13                 let arr = ["comA", "comB", "comC"], index; 14                 index = Math.ceil(Math.random()*arr.length);15                 this.activeCom = arr[index];16             }  17         },  18         components: {  19             comA: {  20                 template: "<div>组件comA</div>"  21             },  22             comB: {   23                 template: "<div>组件comB</div>"  24             },  25             comC: {   26                 template: "<div>组件comC</div>"  27             },  28         }  29     });  30 </script>  
复制代码

异步组件

异步组件在性能上有一定的优势,不仅加快了渲染时间也减少了不必要的加载;在路由中经常用到

看demo;

复制代码
<div id="app">        <child-component></child-component>            </div>    <script>        Vue.component('child-component', function (resolve, reject) {            window.setTimeout(function () {                resolve({                    template: '<div>异步组件的内容</div>'                })            }, 2000)        });        new Vue({            el: '#app'        })    </script>
复制代码

 在路由中异步组件可以这样用:

1 {2     path:"/路由地址",3     name:"routeName",4     component: resolve => require(["../components/xxx.vue"],  resolve)5 }
原创粉丝点击