这篇文章给大家分享的是有关怎样抽象一个Vue公共组件的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
先上 Demo 与 源码。(demo最好在浏览器里以手机模式浏览)
在讲具体实现前,我想先分享下自己认为的理想的公用组件是什么样的:
1. 黑盒性,即除了你自己以外,其他的开发者在快速阅读使用文档之后可以立刻上手,而不用关心你的内部实现;
2. 独立性,即做好解耦,不与父组件有过多关联;
3 自定义性,适当地暴露一些输入接口或者方法给外部用于自定义,同时也要设置好这些属性在外部未输入时的默认值。
下面我们先以黑盒的方式看看 demo 中数字键盘组件是如何调用的(已省略非关键部分代码)。
App.vue
<template> ...... <keyboard@submit-event='handleSubmit'@change-event='handleChange'></keyboard> </template> <script> importkeyboardfrom'Keyboard.vue'; exportdefault{ 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 事件,默认无限制。
<keyboardmax='6'></keyboard>
sp-key:自定义的特殊字符,如身份证输入时的“X”,会添加到左下角空白格,默认无。
<keyboardsp-key='X'></keyboard>
random:是否打乱数字顺序,一些有关银行账户或密码的输入经常会见到这种场景,默认 false。
<keyboardrandom='true'></keyboard>
从上面的几个自定义属性与事件,我们大概知道了父组件是如何向子组件传值以及监听子组件的变化,但父组件该如何直接调用子组件内部的函数呢?我们看下面这个场景。
数字键盘上的键盘图标,点击之后会将数字键盘收起隐藏。组件内部拥有一个方法 keyboardToggle(true|false) 来控制键盘的弹起和收回,那么如果在组件外部也想调用这个方法呢?比如当父组件中的 input 获取到焦点时。
可以通过 Vue 中的 ref 属性来获取到键盘的组件引用,从而调用其内部的方法,如下:
$refs.[refName].keyboardToggle(true|false)
<template> <inputtype='text'@focus='handleShowKeyboard($event)'/> <keyboardref='kbref'></keyboard> </template> <script> importkeyboardfrom'Keyboard'; exportdefault{ //... 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> <divclass='kb-left'> <divclass='kb-item'v-for='iteminkeyArr'>{{item}}</div> <divclass='kb-itemkb-toggle'></div>//键盘图标 </div> <divclass='kb-right'> //... </div> </div> </template> <script> exportdefault{ data(){ return{ baseArr:[] } }, computed:{ keyArr(){ this.handleInit(); returnthis.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> exportdefault{ props:['spKey'], data(){ return{ baseArr:[] } }, //.... methods:{ handleInit(){ letspKey=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> exportdefault{ props:['spKey','random'], data(){ return{ baseArr:[] } }, //.... methods:{ handleInit(){ letspKey=this.spKey; this.baseArr=['1','2','3','4','5','6','7','8','9','0']; if(this.random&&this.random!='false'){ this.baseArr.sort(function(){ returnMath.random()-Math.random(); }); } this.baseArr.splice(this.baseArr.length-1,0,spKey); } } } </script>
将键位打乱顺序其实也很简单,只要通过数组的 sort 方法。sort 方法可以接收一个函数作为参数,若函数返回正数则交换前后两项的位置,若函数返回负数则不作交换。所以将两个随机数相减的结果返回,即可将键位数组随机排序。
下面看看在组件内部是如何触发 change-event 的。
handleInput()
<template> <div> <divclass='kb-left'> <div@click='handleInput(item)'class='kb-item'v-for='iteminkeyArr'>{{item}}</div> <divclass='kb-itemkb-toggle'></div>//键盘图标 </div> //... </div> </template> <script> exportdefault{ data(){ return{ inputStr:'' } }, //... methods:{ handleInput(value){ this.inputStr+=value; this.$emit('change-event',this.inputStr,value); } } } </script>
增加了 max 属性后修改方法如下:
handleInput(value){ letmax=Number(this.max); if(!isNaN(max)&&this.inputStr.length+1>max){ return; } this.inputStr+=value; this.$emit('change-event',this.inputStr,value); }
最后看看退格删除是如何实现的。
handleDelete()
handleDelete(){ letstr=this.inputStr; if(!str.length)return; this.inputStr=str.substring(0,str.length-1); this.$emit('change-event',this.inputStr); }
感谢各位的阅读!关于“怎样抽象一个Vue公共组件”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!
相关文章
本站已关闭游客评论,请登录或者注册后再评论吧~