Vue官方文档学习-自定义事件

  • 官方文档链接:https://cn.vuejs.org/v2/guide/components-custom-events.html

1.事件名


  • 不同于组件和 prop,事件名不存在任何自动化的大小写转换,触发的事件名需要完全匹配监听这个时间所用的名称;
// 提交事件
this.$emit('myEvent')
<!-- 写成kebab-case没有任何效果 -->
<my-component v-on:my-event="doSomething"></my-component>
  • 事件名不会被用作一个JavaScript变量名或property名;
  • v-on事件监听器在DOM模板中会被自动转换为全小写(因为HTML是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent——导致 myEvent 不可能被监听到;
  • 建议始终使用kebab-case的事件名而不要使用camelCase命名;

2.自定义组件的v-model


  • 一个组件上的 v-model 默认会利用名为 value 的 属性和名为 input 的事件;
  • 单选框、复选框等类型的输入控件可能会将 value 属性用于不同的目的。model 选项可以用来避免这样的冲突:
Vue.component('base-checkbox', {
  // 自定义model属性
  model: {
    prop: 'checked', //对应的属性名,需要在组件的props选项里声明checked这个属性
    event: 'change'  //对应的事件
  },
  props: {
    checked: Boolean
  },
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})
  • lovingVue 的值将会传入这个名为 checked 的 prop。同时当 触发一个 change 事件并附带一个新的值的时候,这个 lovingVue 的 property 将会被更新;
<!-- 使用 -->
<base-checkbox v-model="lovingVue"></base-checkbox>

3.将原生事件绑定到组件

(1) 场景

  • 想要在一个组件的根元素上直接监听一个原生事件,可以使用v-on的.native修饰符;

(2) 使用

  • 如果根元素上不支持该事件,则.native监听器将静默失败。不会产生任何报错,但是对应的事件处理函数也不会执行;
  • 举例:在<base-input>组件的根元素上监听focus事件;但是base-input组件根元素为label,不支持focus事件:
<!-- base-input组件内部 -->
<label>
  {{ label }}
  <input
    v-bind="$attrs"
    v-bind:value="value"
    v-on:input="$emit('input', $event.target.value)"
>
</label>
<!-- 使用base-input组件 -->
<base-input v-on:focus.native="onFocus"></base-input>

(3) $listeners属性

  • 解决.native在根元素不支持事件时静默失败的问题;
  • 该属性是一个对象,里面包含了作用在这个组件上的所有监听器,如:
{
  focus: function (event) { /* ... */ }
  input: function (value) { /* ... */ },
}
  • 可以配合v-on="$listeners"将所有的事件监听器指向这个组件的某个特定的子元素;
  • 对于类似 <input> 的你希望它也可以配合 v-model 工作的组件来说,为这些监听器创建一个类似下述 inputListeners 的计算属性通常是非常有用的:
Vue.component('base-input', {
  inheritAttrs: false,
  props: ['label', 'value'],
  computed: {
    inputListeners: function () {
      var vm = this
      // `Object.assign` 将所有的对象合并为一个新对象
      // 第二个参数:从父级添加所有的监听器
      // 第三个参数:添加自定义监听器或覆写一些监听器的行为,这里确保组件配合 `v-model` 的工作
      return Object.assign({}, this.$listeners, { input: function (event) {
            vm.$emit('input', event.target.value)
          }
        }
      )
    }     
  },
  template: `
    <label>
      {{ label }}
      <input
        v-bind="$attrs"
        v-bind:value="value"
        v-on="inputListeners"
      >
    </label>
  `
})
  • 现在 <base-input> 组件是一个完全透明的包裹器了,也就是说它可以完全像一个普通的 <input> 元素一样使用了:所有跟它相同的 attribute 和监听器都可以工作,不必再使用 .native 监听器。

4. .sync修饰符


## (1) 场景 - 在某些情况下,可能需要对一个属性进行“双向绑定”,但真正的双向绑定会带来维护上的问题,因为自组建可以变更父组件,且在父组件和自组件都没有明显的变更来源。 - 通常会使用`update:myPropName`的模式触发事件来维护数据。如:在一个包含`title`属性的组件中,可以用`this.$emit('update:title', newTitle)`来向父组件传递要修改属性的意图,然后在父组件监听该事件并更新一个本地的数据属性:
<text-document
  v-bind:title="doc.title"
  v-on:update:title="doc.title = $event"
></text-document>
  • 为了方便起见,vue为这种模式提供一个缩写,即.sync修饰符;

(2) 使用

  • <component v-bind.sync="prop"></componentv>
<text-document v-bind:title.sync="doc.title"></text-document>
  • 带有.sync 修饰符的 v-bind 不能和表达式一起使用 (例如 v-bind:title.sync="doc.title + '!' "是无效的)。取而代之的是,只能提供想要绑定的 属性名,类似 v-model;
  • 当用一个对象同时设置多个property时,可以将.sync修饰符和v-bind配合使用;此时会把对象中的每一个property都作为独立的rpop传进去,然后各自添加用于更新的v-on监听器;
<!-- doc对象中的每个属性都作为一个独立的prop传递到text-document中 -->
<text-document v-bind.sync="doc"></text-document>
  • 【注意】:将v-bind.sync 用在一个字面量的对象上,例如 v-bind.sync="{ title: doc.title }",是无法正常工作的,因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以通过在打印页面的底部添加自定义内容来实现自定义尾部。 在使用vue-print-nb插件打印页面的时候,可以使用自定义CSS样式来控制打印页面的布局和内容。您可以在打印样式中添加一个固定的底部元素来实现自定义尾部。 首先,在您的Vue组件中,引入vue-print-nb插件并设置相应的配置,确保插件可以正常使用。然后,您可以在组件的样式中添加一个自定义的打印样式,并在其中定义底部元素的样式。 例如,假设您想要在打印页面的底部添加一个版权信息,您可以按照以下步骤操作: 1. 安装vue-print-nb插件: ```bash npm install vue-print-nb --save ``` 2. 在您的Vue组件中引入vue-print-nb插件并设置配置项: ```vue <template> <!-- 页面内容 --> <div> <!-- ... --> </div> <!-- 打印按钮 --> <button @click="print">打印</button> </template> <script> import VuePrintNB from 'vue-print-nb'; export default { // ... methods: { print() { // 使用vue-print-nb插件打印页面 this.$print(this.$el); } }, // 注册vue-print-nb插件 plugins: [VuePrintNB] }; </script> ``` 3. 在组件的样式中添加自定义的打印样式: ```css @media print { /* 打印样式 */ .print-footer { position: fixed; bottom: 0; left: 0; width: 100%; height: 50px; background-color: #f0f0f0; text-align: center; line-height: 50px; } } ``` 4. 在组件的模板中添加底部元素,并为其添加相应的class: ```vue <template> <!-- 页面内容 --> <div> <!-- ... --> </div> <!-- 底部元素 --> <div class="print-footer"> 版权信息 </div> <!-- 打印按钮 --> <button @click="print">打印</button> </template> ``` 这样,当您点击打印按钮时,vue-print-nb插件会根据打印样式将页面打印成PDF或者纸质文档,并在底部添加自定义的版权信息。 请注意,以上只是一个示例,您可以根据实际需求进行适当的调整和修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值