Vue 学习笔记 9 —— Vue 组件

1. 创建组件

使用 Vue.component 创建组件:

Vue.component('button-click', {
    data: function() {
        return {
            counter: 0
        }
    },
    template: '<button v-on:click="counter++">you click me for {{counter}} times.</button>'
});

通过组件可以自定义一个标签:button-click

每一个组件都是一个可复用的 Vue 实例,同样可以添加 data、template、computed 和 methods,但组件没有 el 这种根实例才具有的选项!


接着在 HTML 中使用组件,可以在一个通过 new Vue 创建的 Vue 根实例中,把这个组件作为自定义元素来使用:

<div id="components-demo">
  <button-counter></button-counter>
</div>
let vm = new Vue({
    el: "#root"
})

注意

data 是一个函数,因为每次使用组件都需要分配新的 data !



2. 组件的组织

通常一个应用会以一棵嵌套的组件树的形式来组织:

为了能在模板中使用,组件必须先注册,Vue 才能识别。可以是全局注册或局部注册,通过 Vue.component 是全局注册:

Vue.component('component-name', {
    data: function() {
        // data
    },
    template: ''
})

使用全局注册的组件可以被任何通过 new Vue 创建的根实例使用。



3. Prop

# props 的使用

父组件可以通过 props 向子组件传递数据。Prop 是在组件上注册的自定义 attribute 属性,当一个值传递给一个 prop attribute 的时候,它就编程了那个组件实例(标签)的 property。如:

Vue.component('paper', {
    props: ['title', 'content'],
    template: '<h1>{{title}}</h1>'
})

所有 prop 都存放在数组 props 中(同时加了 ''),一个 prop 被注册后,可以把数据作为属性传递到组件实例(标签):

<paper title="Vue"></paper>

组件也可以和一般标签一样使用 v-bindv-for 等模板命令。

注意: prop 命名为 camelCase 命名的变量在 HTML 中属性对应 kebab-case 命名!


# prop 数据类型

可以以对象形式列出 prop,这些 property 的名称和值分别是 prop 各自的名称和类型:

new Vue({
    props: {
        title: String,
        // 必填
        author: {
            type: String,
            required: true
        },
        // 有默认值
        year: {
        	type: Number,
        	default: 2020
    	},
        callback: Function,
        tags: Array,
        isPblished: Boolean
    }
})


4. 单个根元素

当组件内不只包含一个标签时,需要将他们放在一个根元素内,如下面使用 div 包裹子标签(使用 ` 可以让字符串换行书写):

Vue.component('paper', {
    props: ['title', 'content'],
    template: `
        <div class="paper">
            <h1>{{title}}</h1>
            <p>{{content}}</p>
        </div>
        `
})
let vm = new Vue({
    el: "#root"
})
<div id="root">
    <paper title="Vue" content="Vue is awesome."></paper>
</div>

如果酶将多个元素放在根元素,则会报错提示:

Component template should contain exactly one root element


5. 监听子组件事件

子组件可以通过 $emit触发当前实例上的事件,事件可以被父组件检测到。

当我们使用子组件实现了 paper 排版,当需要能够调节字号的功能时,需要与父组件联系。


# 在父组件中添加一个控制字体的变量

let vm = new Vue({
    el: "#root",
    data: {
        // 使用 em 做单位,em 是相对度量单位
        paperFontSize: 1
    }
})

# 在子组件中添加按钮触发字号放大事件

Vue.component('paper', {
    props: ['title', 'content'],
    template: `
        <div>
            <h1>{{title}}</h1>
            <p>{{content}}</p>
            <button @click="$emit('enlarge-text')">Enlarge text</button>
        </div>`
})

上面的代码添加了 button,点击 button 后,调用内建的 $emit 方法来除法一个名为 enlarge-text 的事件,该事件可以被父组件监测到。


# 父组件处理子组件触发的事件

<div id="root" 
    v-bind:style="{fontSize: paperFontSize + 'em'}">
    <paper 
        title="Vue" 
        content="Vue is awesome."
        @enlarge-text="paperFontSize += 0.1"
    ></paper>
</div>

# 使用事件抛出一个值

子组件可以通过 $emit触发当前实例上的事件,事件可以被父组件检测到,事件也可以抛出一个值,可以使用 $emit 的第二个参数提供这个值:

$emit(event, args){
    // event 为抛出的事件名(字符串)
    // args 为可选的参数
}

如:

<button @click="$emit('enlarge-text', 0.1)">
  Enlarge text
</button>

在父级组件中通过 $event 可以访问这个值:

<paper
    ...
    @enlarge-text="paperFontSize += $event"
></paper>

或者通过函数来访问,这个值作为第一个参数传入方法:

<paper
    ...
    @enlarge-text="onEnlargeText"
></paper>
// 父组件
new Vue({
    el: "#root",
    methods: {
        onEnlargeText: function(amount){
            this.paperFontSize += amount;
        }
    }
})


6. 插槽

当需要向一个自定义组件传递内容时,需要设置插槽:

Vue.component('paper', {
    template: `
        <div>
            <slot></slot>
        </div>`
})

slot 可以插入 HTML 代码:

<paper>
    <p>this is the content.</p>
</paper>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值