1

本节要实现一个消息框组件。效果:

clipboard.png

Bulma 消息框

我们使用的是 Bulma消息框。Bulma 的消息框的基本界面如下:

<article class="message">
  <div class="message-header">
    <p>标题</p>
    <button class="delete"></button>
  </div>
  <div class="message-body">
    消息内容
  </div>

纯静态页面,删除功能需要我们去实现。

使用 slot

首先,我们考虑用之前学到过的 slot 来实现:

Vue.component('message',{
    template: `
        <article class="message" v-show="isVisible">
          <div class="message-header">
            <slot name="title">默认标题</slot>
            <button class="delete" @click="hideMessage"></button>
          </div>
          <div class="message-body">
            <slot></slot>
          </div>
        </article>
    `,
    data() {
        return {
            isVisible:true
        }
    },
    methods:{
        hideMessage() {
            this.isVisible = false
        }
    }
});


var vm = new Vue({
    el:"#root"
});

因为我们使用了多个 slot,为了能否区分,可以将标题的 slot 取名。这样,在父实例中就可以这样使用:

<div id="root">
    <message>
        <template slot="title">欢迎</template>
        你好,Vue
    </message>
</div>

使用 template 的好处是页面渲染时会保持子组件的样子。当然,也可以这样:

<message>
    <h1 slot="title">欢迎</h1>
    你好,Vue
</message>

那么就会被渲染成:

<h1>欢迎</h1>

使用 pros

我们在来看看另外一种实现方式:

<message title="欢迎" body="你好,Vue"></message>

应当如何实现呢?模板似乎可以这样写:

template: `
    <article class="message" v-show="isVisible">
      <div class="message-header">
        {{ title }}
        <button class="delete" @click="hideMessage"></button>
      </div>
      <div class="message-body">
        {{ body }}
      </div>
    </article>
`,

这种情景属于「组件的内部通信」,即 message 实例(parent)的数据要传递给 message 组件(child),这需要在组件的 props 属性中进行定义 :

Vue.component('message',{
    props: ['title','body'],
    template: `
        <article class="message" v-show="isVisible">
          <div class="message-header">
            {{ title }}
            <button class="delete" @click="hideMessage"></button>
          </div>
          <div class="message-body">
            {{ body }}
          </div>
        </article>
    `,
    data() {
        return {
            isVisible:true
        }
    },
    methods:{
        hideMessage() {
            this.isVisible = false
        }
    }
});


var vm = new Vue({
    el:"#root"
});

在组件的 props 属性中定义好之后,实例就可以直接通过属性的方式传递数据给组件了。


附录:


心智极客
1k 声望645 粉丝