vue2封裝input組件方式(輸入的雙向綁定)
vue2封裝input組件
重點(diǎn)
首先我們要明白 vue中v-modle 的對(duì)于input 做了什么
<input type="text" v-model="username"> <input type="text" :value="username" @input="username = $event.target.value">
以上的兩行代碼,所呈現(xiàn)的效果是一樣的。也就是說(shuō): v-model=“username” 在input中做了兩件事情。
- :value 綁定了值
- @input=“username = $event.target.value” 監(jiān)聽(tīng)了值的改變
代碼示例:
父組件
<template> <div id="app"> <lj-input placeholder="請(qǐng)輸入" v-model="username"></lj-input> <div>{{username}}</div> </div> </template> <script> import ljInput from './components/inputCom/LjInput.vue' export default { name: 'App', components: { ljInput }, data(){ return{ username:'', } }, methods: { } } </script>
子組件
<template> <div class="lj-input"> <input :class="{'is-disabled':disabled}" :placeholder="placeholder" :type="type" :disabled ='disabled' :value="value" @input="handleInput" > </div> </template> <script> export default { name:'ljInput', props: { placeholder:{ type:String, default:'' }, type:{ type:String, default:'' }, disabled:{ type:Boolean, default:false }, value:{ type:String, default:'' } }, methods:{ handleInput(e){ // 這句代碼是關(guān)鍵 this.$emit('input',e.target.value) } } } </script> <style> .is-disabled{ cursor: not-allowed; } </style>
vue二次封裝input的幾種方式
下面就是自己封裝input 框?qū)崿F(xiàn)的效果
在看如何封裝之前,先來(lái)了解一下v-model是怎么回事。
其實(shí)說(shuō)白了,v-model就是change和value的結(jié)合體。
廢話不多說(shuō),下面就來(lái)看一下在vue中如何封裝自定義的input組件。
封裝原生input
<template> <input type="text" :value="value" @input="handleChange" /> </template> <script> export default { name: "AppInput", model: { prop: "value", event: "change", }, props: { value: "", }, data() { return { }; }, created() {}, mounted() {}, methods: { handleChange(e) { this.$emit("change", e.target.value); }, }, }; </script>
封裝el-input
<template> <!-- 對(duì)el-input進(jìn)行了包裝--> <div> <el-input v-model="localValue" @change="$emit('change', $event)"></el-input> <!-- el-input提供了input事件,讓我們感知el-input內(nèi)部原生input值的變化,通過(guò)$event可以獲取到具體的值 通過(guò)emit再次傳遞給父組件一個(gè)input事件,父組件中,v-on:input="searchText = $event"這句就能正常使用了 --> <span style="color: #f56c6c; font-size: 12px;"></span> </div> </template> <script> export default { name: "input-name", props: { // 保證父組件中,v-bind:value可以正常設(shè)置值 value: [String], }, data() { return { // 獲取props中value的值,并與el-input綁定,過(guò)程中不修改props中value的值,保證了單向數(shù)據(jù)流原則 localValue: this.value } } } </script> <style lang="less" scoped> </style>
上面的那種方式會(huì)在回顯數(shù)據(jù)時(shí)有問(wèn)題。解決辦法就是:如果出現(xiàn)異步回顯數(shù)據(jù)那么就需要用計(jì)算來(lái)作為中間值轉(zhuǎn)換。
<template> <!-- 對(duì)el-input進(jìn)行了包裝--> <div> <el-input v-model="localValue" @change="$emit('change', $event)"></el-input> <!-- el-input提供了input事件,讓我們感知el-input內(nèi)部原生input值的變化,通過(guò)$event可以獲取到具體的值 通過(guò)emit再次傳遞給父組件一個(gè)input事件,父組件中,v-on:input="searchText = $event"這句就能正常使用了 --> <span style="color: #f56c6c; font-size: 12px;"></span> </div> </template> <script> export default { name: "input-name", props: { // 保證父組件中,v-bind:value可以正常設(shè)置值 value: [String], }, data() { return { } }, computed: { localValue: { get: function () { console.log(this.value) return this.value; }, set: function (v) { v; }, }, }, } </script> <style lang="less" scoped> </style>
VUE高級(jí)用法封裝input
這種方式更加簡(jiǎn)潔,并且不會(huì)出現(xiàn)第二種封裝方式出現(xiàn)的bug。
<template> //這里不能使用v-model,會(huì)報(bào)子組件不能直接操作父組件傳入?yún)?shù)的錯(cuò)誤 //使用value的話其實(shí)就是做一個(gè)回顯因?yàn)橥鈱拥膙-model在這里使用已經(jīng)改變了外層的值了 <el-input v-bind="$attrs" v-on="$listeners" :value="value" ></el-input> </template> <script> export default { name: "f-input", data() { return { }; }, props: { value:"" }, created() {}, mounted() {}, methods: {} }; </script>
//正常的使用方式 <f-input v-model="number"></f-input> //不用v-model語(yǔ)法糖的方式 <f-input :value="number" @change="number = $event,target.value"></f-input>
這里核心用到了兩個(gè)方法 attrs 和 listeners 其中 atters 可以把父組件標(biāo)簽上的所有自定義屬性(不包括props,tyle,class)同步到當(dāng)前元素中,listeners 可以把 f-input 標(biāo)簽上的所有方法同步到子組件中當(dāng)前元素中。
那么上面已經(jīng)知道 v-model 就是 change 和 value 的語(yǔ)法糖,那在 f-input 上綁定 listeners 就可以讀取到 f-input 的 v-model 的 change 事件,atters 可以讀取到 f-input 的 v-model 的 value 值。
$ 符號(hào)打不出來(lái)了,將就著看吧。如果還是不明白 atters和 listeners是怎么回事的可以看一下vue官網(wǎng)中的介紹。
看官網(wǎng)又出了一種封裝的寫法,感覺(jué)挺有意思,在這里記錄一下。
默認(rèn)情況下,組件上的 v-model 使用 modelValue 作為 prop 和 update:modelValue 作為事件。我們可以通過(guò)向 v-model 傳遞參數(shù)來(lái)修改這些名稱
子組件將需要一個(gè) firstName prop 和 lastName prop并發(fā)出 update:firstName 和 update:lastName要同步的事件
var Component = { props: { firstName: String, lastName: String }, emits: ['update:firstName', 'update:lastName'], //vue3可以支持多個(gè)根元素,所有這個(gè)地方不會(huì)有報(bào)錯(cuò),vue2是會(huì)報(bào)錯(cuò)的。 template: ` <input type="text" :value="firstName" @input="$emit('update:firstName', $event.target.value)"> <input type="text" :value="lastName" @input="$emit('update:lastName', $event.target.value)"> ` }
<template> <my-component v-model:first-name="firstName" v-model:last-name="lastName"> </my-component> firstName:{{firstName}} lastName:{{lastName}} </template> <script> const App = { setup(props, context) { const data= reactive({ firstName: 0, lastName: 0, }); return { ...toRefs(data), } }, components: { 'my-component': Component, }, methods: { }, }; const app = createApp(App).mount('#app'); </script>
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- vue中使用echarts實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)綁定以及獲取后端接口數(shù)據(jù)
- vue2與vue3雙向數(shù)據(jù)綁定的區(qū)別說(shuō)明
- vue中v-model雙向綁定input輸入框問(wèn)題
- 使用vue初用antd 用v-model來(lái)雙向綁定Form表單問(wèn)題
- vue中@click綁定事件點(diǎn)擊不生效的原因及解決方案
- Vue中使用element-ui給按鈕綁定一個(gè)單擊事件實(shí)現(xiàn)點(diǎn)擊按鈕就彈出dialog對(duì)話框
- Vue?數(shù)據(jù)綁定事件綁定樣式綁定語(yǔ)法示例
相關(guān)文章
如何通過(guò)Vue自帶服務(wù)器實(shí)現(xiàn)Ajax請(qǐng)求跨域(vue-cli)
從A頁(yè)面訪問(wèn)到B頁(yè)面,并且要獲取到B頁(yè)面上的數(shù)據(jù),而兩個(gè)頁(yè)面所在的端口、協(xié)議和域名中哪怕有一個(gè)不對(duì)等,那么這種行為就叫跨域,這篇文章給大家介紹如何通過(guò)Vue自帶服務(wù)器實(shí)現(xiàn)Ajax請(qǐng)求跨域(vue-cli),感興趣的朋友一起看看吧2023-10-10nuxt中刷新頁(yè)面后防止store值丟失問(wèn)題
這篇文章主要介紹了nuxt中刷新頁(yè)面后防止store值丟失問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10Vue3中無(wú)法為el-tree-select設(shè)置反選問(wèn)題解析
這篇文章主要介紹了Vue3中無(wú)法為el-tree-select設(shè)置反選問(wèn)題分析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04Vue 解決通過(guò)this.$refs來(lái)獲取DOM或者組件報(bào)錯(cuò)問(wèn)題
這篇文章主要介紹了Vue 解決通過(guò)this.$refs來(lái)獲取DOM或者組件報(bào)錯(cuò)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07創(chuàng)建和運(yùn)行Vue.js項(xiàng)目方法demo
這篇文章主要為大家介紹了創(chuàng)建和運(yùn)行Vue.js項(xiàng)目方法demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12詳解Vue學(xué)習(xí)筆記進(jìn)階篇之列表過(guò)渡及其他
本篇文章主要介紹了詳解Vue學(xué)習(xí)筆記進(jìn)階篇之列表過(guò)渡及其他,具有一定的參考價(jià)值,有興趣的可以了解一下2017-07-07Vue3+Vite+TS實(shí)現(xiàn)二次封裝element-plus業(yè)務(wù)組件sfasga
這篇文章主要介紹了在Vue3+Vite+TS的基礎(chǔ)上實(shí)現(xiàn)二次封裝element-plus業(yè)務(wù)組件sfasga,下面文章也將圍繞實(shí)現(xiàn)二次封裝element-plus業(yè)務(wù)組件sfasga的相關(guān)介紹展開(kāi)相關(guān)內(nèi)容,具有一定的參考價(jià)值,需要的小伙伴可惡意參考一下2021-12-12解決axios發(fā)送post請(qǐng)求返回400狀態(tài)碼的問(wèn)題
今天小編就為大家分享一篇解決axios發(fā)送post請(qǐng)求返回400狀態(tài)碼的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08Vue項(xiàng)目中如何封裝axios(統(tǒng)一管理http請(qǐng)求)
這篇文章主要給大家介紹了關(guān)于Vue項(xiàng)目中如何封裝axios(統(tǒng)一管理http請(qǐng)求)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05