<template> <div v-show="show" :class="`alert alert-${type} alert-dismissible`"> <button @click="close" type="button" class="close"><span>×</span></button> {{ msg }} </div> </template>
v-show
是一个条件渲染指令,它只切换元素 CSS 属性的 display
,这里当 show
值为 true
时,我们就显示该元素。
<script> export default { name: 'Message', props: { // 是否显示消息框 show: { type: Boolean, default: false }, // 消息框的类型 type: { type: String, default: 'success' }, // 消息 msg: { type: String, default: '' } }, watch: { show(value) { if (value) { this.$nextTick(() => { this.$el.scrollIntoView(true) }) } } }, methods: { close() { this.$emit('update:show', false) } } } </script>
props
是用来传递数据的,我们需要在子组件用 props
选项声明它预期的数据,上面的代码中我们声明了 3 个属性,并为其指定了 type
类型和 default
默认值,这样我们就能在父组件上传递这些值了,就像下面的代码一样
<Message :show.sync="msgShow" :type="msgType" :msg="msg"/>
type
可以是以下的类型:
String
Number
Boolean
Function
Object
Array
Symbol
关于侦听器:
watch: { show(value) { if (value) { this.$nextTick(() => { this.$el.scrollIntoView(true) }) } } }
watch
选项提供了一个方法来响应数据的变化,在上面的代码中,我们需要监听 show
的新值 value
,完整的传参是 show(val, oldVal)
,val
是新值,oldVal
是旧值。当新值返回 true
时,我们将当前元素滚动到可视区域的顶部。
关闭事件:
close() { this.$emit('update:show', false) }
$emit
用于触发当前实例上的事件,其第一个参数是事件名称,后面还可以附加若干参数。当点击关闭按钮时,我们触发一个 'update:show'
的事件,并附带一个参数 false
,用来关闭消息提示。(为什么事件名称是 'update:show'
,我们稍后结合 props
进行讲解。)
我们可以在组件模板内使用组件定义的 props
,但我们不应该直接修改 props
。要在组件内更新 props
选项的 show
值,需要显式地触发一个更新事件:
close() { // 可以触发一个事件来更新 show this.$emit('update:show', false) // 不可以直接修改 show,这会导致 Vue 在控制台发出错误警告 this.show = false }
props
的绑定默认是单向的,我们要在组件内部更新 show
值,需要在父组件上添加 .sync
修饰符,以创建『双向绑定』:
<Message :show.sync="msgShow"/>
上面的代码会被 Vue 扩展为:
<Message :show="msgShow" @update:show="val => msgShow = val" />
因为父组件有 update:show
事件监听,所以我们能在组件内部使用 $emit
来关闭消息提示:
close() { this.$emit('update:show', false) }