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