前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue.js-自定义事件例子 原

Vue.js-自定义事件例子 原

作者头像
tianyawhl
发布2019-04-04 10:51:04
1.7K0
发布2019-04-04 10:51:04
举报
文章被收录于专栏:前端之攻略前端之攻略

自定义组件的 v-model

2.2.0+ 新增

一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value 特性用于不同的目的。model 选项可以用来避免这样的冲突:

代码语言:javascript
复制
<body class="">
    <div id="app-7">
      <base-checkbox v-model="lovingVue"></base-checkbox>
    </div>
    <script src="js/vue.min.js"></script>
    <script>
    Vue.component("base-checkbox",{
	  model:{
	  prop:"checked",
	  event:"change"
	  },
	  props:{
	  checked:"Boolean"
	  },
	  template:`
	    <input type="checkbox" v-bind:checked="checked" v-on:change="$emit('change',$event.target.checked)"/>
	  `
	})
    var app7 = new Vue({
	    el: '#app-7',
	    data:{
		   lovingVue:true
		}
        
    })
	//正常情况下v-model="lovingVue"   是v-bind:value="lovingVue" 与 v-on:input="lovingVue=$event.target.value" 的语法糖,这种默认的情况在type="checkbox" 是不合适的,我们需要在组件中的model对象中指定event事件类型与prop为checked
	//复选框一般只有一个属性checked,指选中或者不选中,向子组件传递也只要传递这个属性
    </script>
</body>

将原生事件绑定到组件

你可能有很多次想要在一个组件的根元素上直接监听一个原生事件。这时,你可以使用 v-on 的 .native 修饰符:

代码语言:javascript
复制
<body class="">
    <div id="app" class="demo">
        <base-input v-on:focus.native="onFocus" label="标识" placeholder="请输入信息"></base-input>
    </div>
    <script src="js/vue-2.5.13.js"></script>
    <script>
    Vue.component('base-input', {
        inheritAttrs: false,
        props: ["label"],
        template: `
      <label>
          {{label}}
          {{$attrs.placeholder}}
          {{$attrs["data-date-picker"]}}
          <input v-bind="$attrs"/>
        </label>
  `
    })
    var app = new Vue({
        el: "#app",
        data: {

        },
        methods: {
            onFocus: function() {
                console.log("focused")
            }
        }
    })
    //v-on:focus.native="onFocus" 只作用在input上有效,此例中根元素是label,所以原生onFocus事件不起作用
    //若要执行onFocus事件,模板的根元素修改成input template:` <input v-bind="$attrs"/>`
    </script>

渲染为 

代码语言:javascript
复制
<div id="app" class="demo">
   <label>
     标识
     请输入信息
   <input placeholder="请输入信息"></label>
</div>

这时,父级的 .native 监听器将静默失败。它不会产生任何报错,但是 onFocus 处理函数不会如你预期地被调用。

为了解决这个问题,Vue 提供了一个 $listeners 属性,它是一个对象,里面包含了作用在这个组件上的所有监听器。例如:

代码语言:javascript
复制
{
  focus: function (event) { /* ... */ }
  input: function (value) { /* ... */ },
}

有了这个 $listeners 属性,你就可以配合 v-on="$listeners" 将所有的事件监听器指向这个组件的某个特定的子元素。对于类似 <input> 的你希望它也可以配合 v-model 工作的组件来说,为这些监听器创建一个类似下述 inputListeners 的计算属性通常是非常有用的:

完整例子

代码语言:javascript
复制
<body class="">
    <div id="app" class="demo">
        <base-input v-on:focus="onFocus" v-model="idata" label="标识" placeholder="please enter"></base-input>
        <div>{{idata}}</div>
    </div>
    <script src="js/vue-2.5.13.js"></script>
    <script>
    Vue.component('base-input', {
        inheritAttrs: false,
        props: ['label', 'value'],
        computed: {
            inputListeners: function() {
                var vm = this
                console.log(this.$listeners)
                // `Object.assign` 将所有的对象合并为一个新对象
                return Object.assign({},
                    // 我们从父级添加所有的监听器
                    this.$listeners,
                    // 然后我们添加自定义监听器,
                    // 或覆写一些监听器的行为
                    {
                        // 这里确保组件配合 `v-model` 的工作
                        input: function(event) {
                            vm.$emit('input', event.target.value)
                        }
                    }
                )
            }
        },
        template: `
    <label>
      {{ label }}
      <input
        v-bind="$attrs"
        v-bind:value="value"
        v-on="inputListeners"
      >
    </label>
  `
    })
    var app = new Vue({
        el: "#app",
        data: {
            idata: "hi"
        },
        methods: {
            onFocus: function() {
                console.log("focused")
            }
        }
    })
   
    </script>
</body>

Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。 语法:Object.assign(target, ...sources) this.$listeners {    focus: function (event) { /* ... */ }    input: function (value) { /* ... */ },  } $listeners 继承父级的所有事件,例子中的focus和input,其中的input是隐含在v-model中(在父级中v-model="idata" 是 v-bind:value="idata" 与 v-on:input="idata=$event"的语法糖,其中$event是子组件抛出的值event.target.value)

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018/07/20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 自定义组件的 v-model
    • 将原生事件绑定到组件
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档