您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關怎樣抽象一個Vue公共組件的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
先上 Demo 與 源碼。(demo最好在瀏覽器里以手機模式瀏覽)
在講具體實現前,我想先分享下自己認為的理想的公用組件是什么樣的:
1. 黑盒性,即除了你自己以外,其他的開發者在快速閱讀使用文檔之后可以立刻上手,而不用關心你的內部實現;
2. 獨立性,即做好解耦,不與父組件有過多關聯;
3 自定義性,適當地暴露一些輸入接口或者方法給外部用于自定義,同時也要設置好這些屬性在外部未輸入時的默認值。
下面我們先以黑盒的方式看看 demo 中數字鍵盤組件是如何調用的(已省略非關鍵部分代碼)。
App.vue
<template> ...... <keyboard @submit-event='handleSubmit' @change-event='handleChange'></keyboard> </template> <script> import keyboard from 'Keyboard.vue'; export default { data() { return { value: '' }; }, methods: { handleChange(value, currentValue) { console.log(value, currentValue); this.value = value; }, handleSubmit() { console.log('submit: ' + this.value); } } } </script>
如上,最基本的調用就完成了。效果如下:
接著,點擊 1-6 與“確定”。如果如下:
可以看到數字鍵盤已經如我們預期工作了,接下來分析下該數字鍵盤組件所有的輸入項。
@change-event:該事件為自定義事件,父組件通過 v-on 注冊監聽,子組件內部通過 $emit 進行觸發(更多自定義事件相關內容請參考:Vue官方教程)。
每一次點擊數字按鍵以及退格鍵均會觸發該事件,其傳遞兩個參數:value,累積點擊的字符組合;currentValue,當前點擊的字符。父組件通過 handleChange 方法接收該事件的回調內容。
@submit-event:當點擊“確定”鍵即會觸發該事件,其不傳遞參數,只是告訴父組件“我的確定按鈕被點擊了,你要做什么操作自己看著辦吧,之前點擊的數字已經通過 change-event 傳給你了”。父組件通過 handleSubmit 方法接收回調。
如果只寫這兩個方法未免也太沒誠意了,我還根據一些場景編寫了以下幾個自定義屬性。
max:最大輸入長度,超過的部分將不會觸發 change-event 事件,默認無限制。
<keyboard max='6'></keyboard>
sp-key:自定義的特殊字符,如身份證輸入時的“X”,會添加到左下角空白格,默認無。
<keyboard sp-key='X'></keyboard>
random:是否打亂數字順序,一些有關銀行賬戶或密碼的輸入經常會見到這種場景,默認 false。
<keyboard random='true'></keyboard>
從上面的幾個自定義屬性與事件,我們大概知道了父組件是如何向子組件傳值以及監聽子組件的變化,但父組件該如何直接調用子組件內部的函數呢?我們看下面這個場景。
數字鍵盤上的鍵盤圖標,點擊之后會將數字鍵盤收起隱藏。組件內部擁有一個方法 keyboardToggle(true|false) 來控制鍵盤的彈起和收回,那么如果在組件外部也想調用這個方法呢?比如當父組件中的 input 獲取到焦點時。
可以通過 Vue 中的 ref 屬性來獲取到鍵盤的組件引用,從而調用其內部的方法,如下:
$refs.[refName].keyboardToggle(true|false)
<template> <input type='text' @focus='handleShowKeyboard($event)' /> <keyboard ref='kbref'></keyboard> </template> <script> import keyboard from 'Keyboard'; export default { //... methods: { handleShowKeyboard(e) { e && e.preventDefault(); this.$refs.kbref.keyboardToggle(true); } } } </script>
以上面這種形式便可以在父組件上下文中調用子組件內的方法。
$refs.[refName].handleInit()
數字鍵盤組件內部的初始化方法,用于重新渲染組件。若 random 屬性為 true,則數字鍵會刷新隨機排列。
$refs.[refName].handleClear()
清除之前輸入的字符組合,并觸發 change-event 且返回空字符串。
上面分享了這個組件所有對外的屬性與事件,可以發現我們并未看過該組件內部的一行代碼,但已經可以完整的使用它了,下面來聊聊內部實現。
首先來看看布局,我將鍵盤分為左右兩部分,右邊部分不用多說,左邊的部分是將一個鍵位數組通過 v-for 循環生成。
那么是如何讓 0 和 9 之間空出一格呢,下面看下初始化鍵盤組件的方法。
keyboard.vue
handleInit()
<template> <div> <div class='kb-left'> <div class='kb-item' v-for='item in keyArr'>{{item}}</div> <div class='kb-item kb-toggle'></div> //鍵盤圖標 </div> <div class='kb-right'> //... </div> </div> </template> <script> export default { data() { return { baseArr: [] } }, computed: { keyArr() { this.handleInit(); return this.baseArr; } }, methods: { handleInit() { this.baseArr = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']; this.baseArr.splice(this.baseArr.length - 1, 0, ''); } } } </script>
即在鍵位數組倒數第二位插入一個空字符,然后循環生成按鍵。下面看下自定義參數是如何生效的。
sp-key
<script> export default { props: ['spKey'], data() { return { baseArr: [] } }, //.... methods: { handleInit() { let spKey = this.spKey; this.baseArr = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']; this.baseArr.splice(this.baseArr.length - 1, 0, spKey); } } } </script>
在組件內部通過 props 屬性接收父組件傳遞的 spKey,之后就可在組件內的屬性和方法中通過 this.spKey 進行訪問。首先判斷 spKey 值是否有效,并代替空字符插入鍵位數組倒數第二項。
random
<script> export default { props: ['spKey', 'random'], data() { return { baseArr: [] } }, //.... methods: { handleInit() { let spKey = this.spKey; this.baseArr = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']; if (this.random && this.random != 'false') { this.baseArr.sort(function() { return Math.random() - Math.random(); }); } this.baseArr.splice(this.baseArr.length - 1, 0, spKey); } } } </script>
將鍵位打亂順序其實也很簡單,只要通過數組的 sort 方法。sort 方法可以接收一個函數作為參數,若函數返回正數則交換前后兩項的位置,若函數返回負數則不作交換。所以將兩個隨機數相減的結果返回,即可將鍵位數組隨機排序。
下面看看在組件內部是如何觸發 change-event 的。
handleInput()
<template> <div> <div class='kb-left'> <div @click='handleInput(item)' class='kb-item' v-for='item in keyArr'>{{item}}</div> <div class='kb-item kb-toggle'></div> //鍵盤圖標 </div> //... </div> </template> <script> export default { data() { return { inputStr: '' } }, //... methods: { handleInput(value) { this.inputStr += value; this.$emit('change-event', this.inputStr, value); } } } </script>
增加了 max 屬性后修改方法如下:
handleInput(value) { let max = Number(this.max); if (!isNaN(max) && this.inputStr.length+1 > max) { return; } this.inputStr += value; this.$emit('change-event', this.inputStr, value); }
最后看看退格刪除是如何實現的。
handleDelete()
handleDelete() { let str = this.inputStr; if (!str.length) return; this.inputStr = str.substring(0, str.length - 1); this.$emit('change-event', this.inputStr); }
感謝各位的閱讀!關于“怎樣抽象一個Vue公共組件”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。