2.2.0+ 新增html
一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,可是像单选框、复选框等类型的输入控件可能会将 value 特性用于不一样的目的。model 选项能够用来避免这样的冲突:vue
<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
修饰符:app
<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>
渲染为 函数
<div id="app" class="demo"> <label> 标识 请输入信息 <input placeholder="请输入信息"></label> </div>
这时,父级的 .native
监听器将静默失败。它不会产生任何报错,可是 onFocus
处理函数不会如你预期地被调用。this
为了解决这个问题,Vue 提供了一个 $listeners
属性,它是一个对象,里面包含了做用在这个组件上的全部监听器。例如:spa
{ focus: function (event) { /* ... */ } input: function (value) { /* ... */ }, }
有了这个 $listeners
属性,你就能够配合 v-on="$listeners"
将全部的事件监听器指向这个组件的某个特定的子元素。对于相似 <input>
的你但愿它也能够配合 v-model
工做的组件来讲,为这些监听器建立一个相似下述 inputListeners
的计算属性一般是很是有用的:code
完整例子component
<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)htm