写点什么

Vue- 组件详解

  • 2022-11-02
    广东
  • 本文字数:2577 字

    阅读完需:约 8 分钟

Vue-组件详解

组件与复用

Vue 组件需要注册后才可以使用,注册有全局注册和局部注册两种方式


Vue.component('my-component', {})
复制代码


要在父实例中使用这个组件,必须要在实例创建前注册,之后就可以用<my-component></my-component>的形式来使用组件


Vue.component('my-component', {     template: `<div>这是一个组件</div>` });
复制代码


template的 DOM 结构必须被一个元素包含,缺少<div></div>会无法渲染并报错


在 Vue 实例中,使用components选项可以局部注册组件,注册后的组件只在该实例作用域下有效


组件中也可以使用components选项来注册组件,使组件可以嵌套


var Child = {     template: `<div>局部注册组件的内容</div>`}new Vue({     el:'#app',     components: {'my-component': Child     }, });
复制代码


Vue 组件的模板在某些情况下会受到 HTML 的限制,比如<table>内规定只允许是<tr><td><th>等这些表格元素,所以在<table>内直接使用组件时无效的。这种情况下,可以使用特殊的is属性来挂载组件


<div id="app">     <table>         <tbody is="my-component"></tbody>     </table> </div> Vue.component('my-component', {     template: `<div>这里是组件内容</div>` });
复制代码


常见的限制元素还有<ul><ol><select>


除了template选项外,组件中还可以像 Vue 实例那样使用其他的选项,比如datacomputedmethods


但是在使用data时,data必须是函数,然后将数据return出去


JavaScript 对象是引用关系,如果return的对象引用了外部的一个对象,那这个对象就是共享的,任何一方修改都会同步

使用Props传递数据

组件不仅要把模板的内容进行复用,更重要的是组件间进行通信。


通常父组件的模板中包含子组件,父组件要正向地向子组件传递数据或参数,子组件接收后根据参数的不同渲染不同的内容或者执行操作。这个正向传递数据的过程通过props来实现。


在组件中,使用选项props声明需要从父级接收的数据,props的值可以是两种,一种是字符串数组,一种是对象


<my-component message="来自父组件的数据"></my-component> 
props: ['message'], template: `<div>{{message}}</div>`,
复制代码


props中声明的数据与组件data函数中return的数据主要区别就是props的数据来自父级,而data中的是组件自己的数据,作用域是组件本身,这两种数据都可以在模板template及计算属性computed和方法methods中使用。


由于 HTML 特性不区分大小写,当使用 DOM 模板时,驼峰命名的props名称要转为短横线分割命名


<my-component text="aaaaaa"></my-component>
复制代码


有时候,传递的数据并不是直接写死,而是来自父级的动态数据,这时可以使用指令v-bind动态绑定props的值,当父组件的数据变化时,也会传递子组件


<div id="app">     <input type="text" v-model="parentMessage">     <my-component :message="parentMessage"></my-component> </div> 
props: ['message'], template: `<div>{{message}}</div>`, data: { parentMessage: '' }
复制代码


v-model绑定了父级的数据parentMessage,当通过输入框任意输入时,子组件接收到的props["message"]也会实时响应,并更新组件模板

数组验证

prop需要验证时,需要对象写法,一般当组件需要提供给别人使用时,推荐都进行数据验证。比如某个数据必须是数字类型,如果传入字符串,就会在控制台弹出警告


Vue.component('my-component', {    props: {        // 必须是数字        propA: Number,        // 必须是字符串或数字类型        propB: [String, Number],        // 布尔值,如果没有定义,默认值是true        propC: {            type: Boolean,            default: true        },        // 数字,而且是必传        propD: {            type: Number,            default: true        },        // 如果是数组或对象,默认值必须是一个函数来返回        propE: {            type: Array,            default: function () {                return []            }        },        // 自定义一个验证函数        propF: {            validator: function (value) {                return value > 10            }        }    }});
复制代码


验证的type类型可以是:String,Number,Boolean,Object,Array,Function

自定义事件

当子组件需要向父组件传递数据时,就要用到自定义事件,v-on除了监听 DOM 事件外,还可以用于组件之间的自定义事件


Vue 组件的子组件用$emit()来触发事件,父组件用$on()来监听子组件的事件


父组件也可以直接在子组件的自定义标签上使用v-on来监听子组件触发的自定义事件


<div id="app">    <p>总数:{{total}}</p>    <my-component @add="getTotal" @inc="getTotal"></my-component></div>
Vue.component('my-component', { template: ` <div> <button @click="add">+</button> <button @click="inc">-</button> </div> `, data() { return { count: 0 } }, methods: { add(){ this.count++; this.$emit('add', this.count); }, inc(){ this.count--; this.$emit('inc', this.count) } }});
new Vue({ el: '#app', data: { total: 0 }, methods: { getTotal(total){ this.total = total } }});
复制代码

Slot 插槽

在子组件内使用特殊的<slot>元素就可以为这个组件开启一个slot(插槽),在父组件模板里,插入在子组件标签内的所有内容将替代子组件的<slot>标签及它的内容,子组件的模板内定义了一个<slot>元素,并且用一个<p>作为默认的内容,在父组件没有使用slot时,会渲染这段默认的文本;如果写入了slot,就会替换整个<slot>


<div id="app">     <child-component>         <p>分发的内容</p>         <p>更多分发的内容</p>    </child-component> </div> 
Vue.component('child-component', { template: ` <div> <slot> <p>如果没有父组件插入内容,我将作为默认出现</p> </slot> </div> `, });
复制代码


<slot>元素指定一个name后可以分发多个内容,具名slot可以与单个slot共存,如果没有指定默认的匿名slot,父组件内多余的内容都将被抛弃

发布于: 刚刚阅读数: 4
用户头像

还未添加个人签名 2022-11-01 加入

还未添加个人简介

评论

发布
暂无评论
Vue-组件详解_vue.js_格斗家不爱在外太空沉思_InfoQ写作社区