当前位置: 首页 > Web前端 > HTML5

第10集:从头实现一套PC端Vue的ui组件库(计数器组件)

时间:2023-04-05 21:05:57 HTML5

Episode10:Realizationfromscratch(countercomponent)本集定位:很多人听到namecounter都没什么印象。毕竟这个元件用的少,就是左边的'-'右边的'+',只有在控制一定数量的时候才会用到。比如我之前做的商城小程序,只有在‘下单’页面的规格弹框才有。如果涉及到处理频繁项的场景应该是很常见的,但是别看这个组件体积小。写的时候还是有很多坑。这次我们将制作一个计数器。目标是尽可能小,尽可能节省性能。1:需求分析每次+1-1是正常的,但是如果搞活动,每次至少+-2或3,需要兼容,(给个实际坑,我们之前限制用户每次活动,每个A用户只能买2个,但是他没有做好防范,所以用户这次可能只买1个,下次再买的时候会提示每次只能买2个,但是说??明他只点了买一个,因为他已经买了一个,为了兼容这个问题,还得加个莫名其妙的补救码)中间的展示区应该是输入,用户要买1000个,就是他不可能+1+1+1...,用到一些组件,一般是div,点击后变成input。个人感觉完全没必要,一个元素就够了,何苦要两个元素,去掉他输入状态下的默认样式就好了。关于双方肯定是有限制的,很多时候会出现限购的情况。比如我建的商城,库存只有10个或者单个用户最多可以购买3个,最少2个等等限制。小数位的显示...这个其实我遇到过一个需求,只要涉及到数字,就必须精确到最后两位。这个需求会导致后台同学对数据库进行一定的限制,所以我们传给后台的数据是有限制的。.2:基本结构:先展示一章正常状态的图,让我们更直观的完成,造型更独特,这是这套组件的一个特点,哈哈照着做会导致思维的禁锢,自己写代码去尝试新的东西,但是工作中一定要乖乖听话,遵守公司的规定。vue-cc-ui/src/components/InputNumber/index.jsimportinputNumberfrom'./main/input-number.vue'inputNumber.install=function(Vue){Vue.组件(inputNumber.name,inputNumber);};exportdefaultinputNumbervue-cc-ui/src/components/InputNumber/main/input-number.vue这里我们选择把input和button放在一个div里面,而且是同一个level,这种方式和其他的不一样,因为这样比较直观,而且实现我想要的功能。3:事件绑定//减少//增加//监听输入框这里我们遇到一个问题,就是这个组件是以v-model的形式写的,而v-model有一些缺点,在测试过程中,我发现,比如用户将同一个v-model绑定到多个组件,会导致无限渲染的bug。下面将解释解决此类bug的相关代码。prposprops:{max:{type:Number},//如果不传数字,默认为undefinedmin:{type:Number},step:{//每次计算的单位类型:Number,默认:1},value:{//绑定值,这里允许两个类型,为了方便用户书写,我们将具体的判断写在下面type:[String,Number],required:true},precision:{//显示小数点后的位数type:Number,validator(value){if(value<1||value===undefined){return1;}else{返回parseInt(值);}}}},add方法的实现add(){//很有可能用户输入的是字符串属性,//1:比如后台返回的是字符串;//2:输入框input为字符串类型;//3:其他与v-model绑定相同值的组件赋予该值字符串类型;让num=Number(this.value)+this.step;//添加固定长度//这里抽象出一个函数,负责改变值this.emitVal(num);},reduce方法reduce()的实现{letnum=Number(this.value)-这一步;this.emitVal(num);},监听输入框的输入事件inputChange(e){//这里可能有一个字符串类型this.emitVal(Number(e.target.value));},key赋值函数emitValemitVal(newVal){let{max,min}=this;//不传参数时,默认值为undefined//这个值限制在max以内,min以上if(max!==undefined&&newVal>max)newVal=max;如果(min!==undefined&&newVal{if(value!==undefined)this.emitVal(value);});},//这个是start表示在页面的瞬间launch一次,很好用,但是数据有点消耗性能,慎用//watch还有一个deep属性,就是更强大,可以即时深度监控数据:true}}上面的问题都是基于v-model的,所以有人很早就消除了双向绑定的弊端,封装的组件越多,会更明显。4:关于风格的判断,我们在计算属性中监测了球队的当前值。返回的颜色是灰色的,用户自定义没有意义,所以直接写了。计算:{valueMin(){if(this.value===this.min)re转“#bbbbbb”;返回””;},valueMax(){if(this.value===this.max)返回“#bbbbbb”;返回””;}},dom,如果你点击最大值,它会设置为灰色,我们已经阻止了继续点击的渲染dosomethinginterestingslot是一个自由度很高的标签左右按钮被包裹起来,这样用户就可以定义标签显示的样子

vue-cc-ui/src/style/inputNumber.scss@import'./common/var.scss';@import'./common/extend.scss';@import'./common/mixin.scss';@import'./config/index.scss';@includeb(input-number){//friendly小手形光标:pointer;//有放大动画。看过我文章的同学都知道,我喜欢操作组件有悬停缩放效果。过渡:所有.1s;对齐项目:居中;显示:内联-flex;背景色:白色;&:hover{//如果缩放被其他组件遮挡,则不会绘制z-index:6;转换米:规模(1.2);}//签名阴影@includecommonShadow($--color-black);@includee(add){@includeflexCenter();填充:4px6px;}@includee(reduce){@includeflexCenter();填充:4px6px;}@includee(input){//去掉输入框边框的默认样式:none;大纲:无;显示:块;文本对齐:居中;宽度:60px;高度:20px;}}效果展示端一般是这些组件中比较简单的一个。一些坑让我更好的学习vue和前端思想。总的来说还是挺有意思的。让我们一起继续学习,一起进步,早日实现自我价值!!下一集要讲的是tab切换组件的相关知识;github:链接说明个人博客:链接说明