【10】Vue基础:将原生事件绑定到组件


.native修饰符

我们有时候需要对封装好的组件做一些原生事件的操作,比如点击click事件,这个时候可以使用.native修饰符完成。
模版代码:

<v-demo @click.native="onClick"></v-demo>

示例代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>.native 修饰符</title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    </head>
    <body>
        <div id="app">
            <v-btn @click.native="onClick"></v-btn>
        </div>
        <script type="text/javascript">
            var VBtn = {
                template: `<button>点击我</button>`
            };
            new Vue({
                el: '#app',
                data() {
                    return {
                        msg: ''
                    }
                },
                components: {
                    'v-btn': VBtn
                },
                methods: {
                    onClick(event) {
                        alert('我被点击了');
                    }
                }
            });
        </script>
    </body>
</html>

在浏览器运行时,点击按钮时,弹出我被点击了,说明.native修饰符生效。如果去掉.native修饰符后,再次点击按钮没有任何反应。

其他情况

.native修饰符虽然在一定场景下很使用,但是在尝试监听一个类似<input>的元素时,该修饰符不起作用。为了解决这个问题,Vue 提供了一个 $listeners 属性,它是一个对象,里面包含了作用在这个组件上的所有监听器。
示例代码:

<!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>$listeners</title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    </head>
    <body>
        <div id="app">
            <div>文本框内容为:{{ msg }}</div>
            <v-input @input.native="onInput"></v-input>
        </div>
        <script type="text/javascript">
            var VInput = {
                // computed 是计算属性,这个后期会提到
                computed: {
                    inputListeners() {
                        var vm = this;
                        // `Object.assign` 将所有的对象合并为一个新对象
                        return Object.assign(
                            {},
                            // 从父级添加所有的监听器
                            vm.$listeners,
                            {
                                // 复写 input 事件
                                input(event) {
                                    vm.$emit('input', event.target.value);
                                }
                            }
                        )
                    },
                },
                template: `
                    <label>
                        <span>将原生事件绑定到组件:</span>
                        <input v-on="inputListeners">
                    </label>
                `
            };
            new Vue({
                el: '#app',
                data() {
                    return {
                        msg: ''
                    }
                },
                components: {
                    'v-input': VInput
                },
                methods: {
                    onInput(event) {
                        this.msg = event.target.value;
                    }
                }
            });
        </script>
    </body>
</html>

.sync修饰符

  • .sync 修饰符是为了解决prop进行“双向绑定”的问题。
  • 需要注意带有 .sync 修饰符的 v-bind 不能和表达式一起使用 (例如 v-bind:title.sync=”doc.title + ‘!’” 是无效的)。
    模版代码:
    <v-demo :title.sync="msg"></v-demo>
    示例代码:
    <!DOCTYPE html>
    <html>
      <head>
          <meta charset="utf-8">
          <title>.sync 修饰符</title>
          <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
      </head>
      <body>
          <div id="app">
              <div>父组件:{{ msg }}</div>
              <v-demo :title.sync="msg"></v-demo>
          </div>
          <script type="text/javascript">
              var VDemo = {
                  props: [ 'title' ],
                  template: `<div>{{ title }}</div>`,
                  mounted() {
                      setTimeout(() => {
                          this.$emit('update:title', 123)
                      }, 2000);
                  }
              };
              new Vue({
                  el: '#app',
                  data() {
                      return {
                          msg: '我是标题'
                      }
                  },
                  components: {
                      'v-demo': VDemo
                  }
              });
          </script>
      </body>
    </html>

文章作者: 技术潘
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 技术潘 !
  目录