真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

從零擼一個(gè)pc端vue的ui組件庫(計(jì)數(shù)器組件)

聽到計(jì)數(shù)器這個(gè)名字很多人是不是一瞬間沒有什么印象, 畢竟這個(gè)組件用的比較少,就是那種左邊一個(gè)'-'右邊一個(gè)'+', 控制某些數(shù)量的時(shí)候才會(huì)用到, 比如我之前做的商城小程序只有'下單'頁面的規(guī)格彈出框里面才有他的身影, 如果是涉及到處理商品數(shù)量很頻繁的業(yè)務(wù)場景應(yīng)該會(huì)很常見吧, 但是不要看這個(gè)組件小, 編寫它的時(shí)候坑還不少, 本次我們就來做一個(gè)計(jì)數(shù)器, 目標(biāo)就是盡可能小, 盡可能的省性能.

創(chuàng)新互聯(lián)建站主要從事網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站制作、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)大通,十余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18982081108

1:需求分析

  • 每次+1 -1是常態(tài), 但是如果搞活動(dòng), 每次最少為+-2個(gè)或三個(gè), 就要兼容一下了,( 舉一個(gè)實(shí)際遇到的坑, 我們之前把用戶限制為每次活動(dòng), 每個(gè)用戶只能買2個(gè), 但是沒有做好防備, 導(dǎo)致用戶可能這次只買一個(gè), 而下次他再次購買的時(shí)候會(huì)提示每次只能買兩個(gè), 但顯示他只點(diǎn)擊了買一個(gè), 因?yàn)樗呀?jīng)買過一個(gè), 為了兼容這個(gè)問題, 搞得還要加莫名其妙的補(bǔ)救代碼 )
  • 中間的顯示區(qū)應(yīng)該可輸入的, 用戶想買1000個(gè)不可能讓他+1+1+1..., 某些組件采用的是, 平時(shí)其為div, 點(diǎn)擊之后變?yōu)閕nput, 個(gè)人感覺完全沒必要, 一個(gè)元素就夠了, 何必搞兩個(gè)元素, input狀態(tài)下把他的默認(rèn)樣式去掉就好了.
  • 左右兩邊要有限制, 很多時(shí)候會(huì)有限購一說, 比如我做的商城, 庫存只有10個(gè) 或者單個(gè)用戶最多購買3個(gè), 最少買兩個(gè)等等限制.
  • 小數(shù)位數(shù)的顯示一說... 這個(gè)其實(shí)我還真遇到過, 有一種需求叫做, 只要涉及數(shù)字就必須精確到后兩位, 這種需求會(huì)導(dǎo)致后臺同學(xué)對數(shù)據(jù)庫做一定的限制, 從而我們傳給后臺的數(shù)據(jù)也就存在限制了.

2: 基本結(jié)構(gòu):

先展示一章普通狀態(tài)的圖, 讓我們更直觀的去完成它, 造型比較別致, 是本套組件的一個(gè)特點(diǎn), 哈哈做的與別人一樣會(huì)導(dǎo)致思想的禁錮, 自己寫代碼多嘗試新的東西, 但是工作中一定要中規(guī)中矩, 以公司條款為準(zhǔn)則.

從零擼一個(gè)pc端vue的ui組件庫( 計(jì)數(shù)器組件 )

vue-cc-ui/src/components/InputNumber/index.js

import inputNumber from './main/input-number.vue'
inputNumber.install = function(Vue) {
 Vue.component(inputNumber.name, inputNumber);
};
export default inputNumber

vue-cc-ui/src/components/InputNumber/main/input-number.vue

這里我們選擇吧input與button放在一個(gè)div里面, 且同級別這種方式, 與其他的不太一樣, 因?yàn)檫@樣更直觀, 而且也足夠?qū)崿F(xiàn)我想要的功能.

3: 事件的綁定

// 減少
 
// 增加
// 輸入框的監(jiān)控

這里我們有個(gè)問題, 就是本組件采用的是v-model的形式編寫, v-model有一些弊端, 在測試的時(shí)候我發(fā)現(xiàn), 比如說用戶為多個(gè)組件綁定了相同的v-model會(huì)導(dǎo)致無限渲染的bug, 下面會(huì)解讀解決這類bug的相關(guān)代碼.

prpos

props: {
 max: { type: Number }, // 數(shù)字不傳默認(rèn)是undefined
 min: { type: Number },
 step: { // 每次計(jì)算的單位
  type: Number,
  default: 1
 },
 value: { 
 // 綁定的數(shù)值, 這里允許兩種type, 為了方便用戶書寫,具體判斷下面我們自己寫
  type: [String, Number],
  required: true
 },
 precision: { // 顯示小數(shù)點(diǎn)后幾位數(shù)
  type: Number,
  validator(value) {
  if (value < 1 || value === undefined) {
   return 1;
  } else {
   return parseInt(value);
  }
  }
 }
 },

add 方法的實(shí)現(xiàn)

add() {
// 很可能用戶就輸入了一個(gè)string屬性, 
// 1: 比如后臺返回的就是字符串;
// 2: input框輸入的就是字符串類型;
// 3: 用v-model綁定了同樣的值的其他組件賦予了這個(gè)值string類型;
 let num = Number(this.value) + this.step; // 加上固定的長度
// 這里我們抽象出一個(gè)專門負(fù)責(zé)數(shù)值的變化的函數(shù)
 this.emitVal(num);
},

reduce 方法的實(shí)現(xiàn)

reduce() {
  let num = Number(this.value) - this.step;
  this.emitVal(num);
 },

監(jiān)聽input框的輸入事件

inputChange(e) {
// 這里就有可能出現(xiàn)string類型的了
  this.emitVal(Number(e.target.value));
 },

關(guān)鍵性的賦值函數(shù)

emitVal

emitVal(newVal) {
  let { max, min } = this;
  // 不傳參數(shù)的時(shí)候默認(rèn)值就是undefined
  // 對這個(gè)值的限制就是, max之內(nèi), min以上
  if (max !== undefined && newVal > max) newVal = max;
  if (min !== undefined && newVal < min) newVal = min;
  // 這里兼容一下位數(shù)控制
  let value = Number(newVal).toFixed(this.precision);
  // 這個(gè)oldVal下面會(huì)解釋:point_down:
  if (value === this.oldVal) return;
  this.oldVal = ls;
  // 發(fā)出兩個(gè)事件, 一個(gè)負(fù)責(zé)改變value, 一個(gè)負(fù)責(zé)返回給用戶
  // 畢竟用戶不可能監(jiān)聽input事件然后再把值附上去, 太麻煩
  this.$emit("input", value);
  this.$emit("change", value);
  // 這一步很重要
  // 下面會(huì)詳細(xì)說
  this.$refs.input.value = value;
 }

上面遺留的問題,這里解釋一下.

oldVal: 能防止很多多余的改變, 比如說用戶復(fù)制粘貼了一組數(shù)進(jìn)來, 這個(gè)數(shù)大于max, 但是當(dāng)時(shí)顯示的數(shù)值就是max, 所以就不用渲染了, 或者v-model不止綁定了這個(gè)組件, 還綁定了其他各種組件, 導(dǎo)致值超出范圍, 這邊也會(huì)進(jìn)行相應(yīng)的限制, 而這個(gè)oldVal 就是上一個(gè)合法的值, 所以在做完檢測之后, 檢測通過的數(shù)值要賦值給他.

this.$refs.input.value = value; 這一步看似很沒用, 因?yàn)檩斎肟蚶锩娴氖莢alue, value改變input里面的值自然會(huì)改變, 但是實(shí)際測試并不是這樣, 問題也是出現(xiàn)在v-model上, 綁定很多的時(shí)候會(huì)出現(xiàn)值的不改變, 可能是vue的機(jī)制問題, 而且他要放在 this.$emit(....);下面操作, 如果放在上面會(huì)導(dǎo)致多次執(zhí)行, 因?yàn)樗膱?zhí)行會(huì)循環(huán)觸發(fā)input的監(jiān)聽事件, 多次試驗(yàn)之后, 還是放在這里沒有bug.
上面的兩個(gè)問題都是涉及到v-model的問題, 下面還有一個(gè)同類的問題, 我們來看看.

對value進(jìn)行的監(jiān)控

因?yàn)関alue的變化, 不一定全是 通過+-輸入這三種方式, 還有第三方通過v-model的方式, 還有用戶手動(dòng)亂填的方式.

watch: {
 value: {
  handler() {
  // 為了解決, 多組件共同v-model采用的這個(gè)方法, 也算是另辟蹊徑了
  let { value, time } = this;
  clearTimeout(time);
  // 畢竟把它放入宏任務(wù)Macrotasks可以躲過很多無限循環(huán).
  time = setTimeout(() => {
   if (value !== undefined) this.emitVal(value);
  });
  },
  // 這個(gè)是開啟進(jìn)頁面的瞬間就出發(fā)一次的意思, 很有用, 但是數(shù)據(jù)稍大會(huì)消耗性能, 慎用
  // watch還有一個(gè)deep屬性, 更是吃性能吃的厲害, 可以深度監(jiān)控里面的數(shù)據(jù)
  immediate: true
 }
 }

上面的問題都是基于v-model的, 所以很早就有人剔除雙向綁定的壞處, 封裝越多的組件感覺就越明顯.

4: 關(guān)于樣式的判定

在計(jì)算屬性里面我們隊(duì)當(dāng)前值進(jìn)行了監(jiān)控, 返回的是置灰的顏色, 這個(gè)讓用戶自定的意義不大, 所以直接寫了.

computed: {
 valueMin() {
  if (this.value === this.min) return "#bbbbbb";
  return "";
 },
 valueMax() {
  if (this.value === this.max) return "#bbbbbb";
  return "";
 }
 },

dom, 點(diǎn)擊到了最大值的話就會(huì)置灰, 我們上面已經(jīng)阻止了繼續(xù)點(diǎn)擊的渲染

做點(diǎn)有意思的事

slot是個(gè)自由度很高的標(biāo)簽

把左右按鈕都包上, 讓用戶可以自己定義顯示的標(biāo)簽是什么樣子的

vue-cc-ui/src/style/inputNumber.scss @import './common/var.scss'; @import './common/extend.scss'; @import './common/mixin.scss'; @import './config/index.scss'; @include b(input-number) { // 友好的小手 cursor: pointer; // 有個(gè)放大動(dòng)畫, 看過我文章的同學(xué)都知道, 操作類的組件, 我喜歡有一個(gè)懸停放大效果. transition:all .1s; align-items: center; display: inline-flex; background-color: white; &:hover { // 放大被其他組件擋住就劃不來了 z-index: 6; transform: scale(1.2); } // 招牌陰影 @include commonShadow($--color-black); @include e(add) { @include flexCenter(); padding: 4px 6px; } @include e(reduce) { @include flexCenter(); padding: 4px 6px; } @include e(input) { // 去掉輸入框的默認(rèn)樣式 border: none; outline:none; display: block; text-align: center; width:60px; height: 20px; } }

效果展示

從零擼一個(gè)pc端vue的ui組件庫( 計(jì)數(shù)器組件 )

從零擼一個(gè)pc端vue的ui組件庫( 計(jì)數(shù)器組件 )

end

總的來說是這些組件中比較簡單的一個(gè)了, 有些坑能夠讓我更好的學(xué)習(xí)vue以及前端的思想, 總的來說挺有趣的.

大家繼續(xù)一起學(xué)習(xí),一起進(jìn)步, 早日實(shí)現(xiàn)自我價(jià)值!!

下一集準(zhǔn)備聊聊 tab切換組件的相關(guān)知識;

github: 鏈接描述


本文標(biāo)題:從零擼一個(gè)pc端vue的ui組件庫(計(jì)數(shù)器組件)
文章地址:http://weahome.cn/article/jhicjc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部