基于element-ui組件手動(dòng)實(shí)現(xiàn)單選和上傳功能
前言
在用戶使用過(guò)程中提出一鍵導(dǎo)入的功能,需求如下:點(diǎn)擊導(dǎo)入按鈕顯示提示框,然后是單選框以及上傳按鈕。pc端常使用element-ui組件,但是這個(gè)項(xiàng)目是vue1的老項(xiàng)目,并且沒(méi)有element-ui組件。所以需要自己動(dòng)手實(shí)現(xiàn)單選功能和上傳功能。
radio 屬性及方法
name: 用于定義同一類型的 radio 同一 name 的 radio 只能選中一個(gè)(單選實(shí)現(xiàn))
- id: 用于和 label 標(biāo)簽關(guān)聯(lián)起來(lái) 實(shí)現(xiàn)點(diǎn)擊 label 標(biāo)簽內(nèi)的元素也能選中 radio
- value:?jiǎn)芜x按鈕的值,選中某個(gè)單選按鈕相當(dāng)于拿到 value 值 tip:用于識(shí)別組中的哪個(gè)單選按鈕被選中。
- checked 用于設(shè)置默認(rèn)選中的 radio
- v-model 創(chuàng)建雙向數(shù)據(jù)綁定。 會(huì)忽略所有表單元素的 value、checked、selected 特性的初始值而總是將 Vue 實(shí)例的數(shù)據(jù)作為數(shù)據(jù)來(lái)源。
// html
<div v-for="day in weekSelectList"
:key="day.id"
class="select__day">
<input type="radio"
name="week"
:id="day.label"
:value="day.value"
v-model="selectedDay">
<label :for="day.label">{{day.label}}({{day.value}})</label>
</div>
// 暫定的數(shù)據(jù)
data(){
return {
weekSelectList: [
{ label: '周一', value: '2018-12', id: 1 },
{ label: '周二', value: '2018-13', id: 2 },
{ label: '周三', value: '2018-14', id: 3 },
{ label: '周四', value: '2018-15', id: 4 },
{ label: '周五', value: '2018-16', id: 5 }
]
},
selectedDay: '2018-12',
}
通過(guò) v-model 綁定 selectedDay,匹配到相同的值會(huì)將該 radio 選中,當(dāng)改變 radio 的選擇,selectedDay 也會(huì)動(dòng)態(tài)的變更成選中的 radio 的 value
上傳文件
屬性
accept 屬性接受一個(gè)(多個(gè)值時(shí))逗號(hào)分隔的字符串 如:accept="image/png, image/jpeg"
- id
- name
- 注意:accept 屬性并不會(huì)驗(yàn)證選中文件的類型只是在用戶瀏覽時(shí)只顯示指定文件類型
缺點(diǎn)
- 在未上傳文件時(shí),顯示"未選擇文件",用戶界面不友好,不可配置
- 同一個(gè)文件名即使內(nèi)容改變了,重新上傳也不會(huì)觸發(fā) change 事件
- 用戶如果在上傳過(guò)程中點(diǎn)擊了“取消”,已經(jīng)上傳的文件會(huì)被移除
解決方式
<div class="upload__button"
:class="{'upload__button--uploaded':isUploaded}"
@click="onUploadClick">點(diǎn)擊上傳</div>
<input type="file"
class="upload__file"
v-el:upload
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
@change="onFileChange" />
methods:{
onUploadClick() {
if (!this.isUploaded) {
this.$els.upload.click()
}
},
onFileChange(e) {
const file = e.target.files[0]
if (file === undefined) {
return
}
this.fileName = file.name
const result = /[xls|xlsx]$/.test(this.fileName)
if (result) {
this.isUploaded = true
this.showAlert('上傳成功')
this.$els.upload.value = null
} else {
this.showAlert('文件格式錯(cuò)誤,請(qǐng)確認(rèn)后重試。')
}
},
}
當(dāng)點(diǎn)擊上傳按鈕觸發(fā) onUploadClick 事件后,獲取到 upload 綁定的 DOM (由于是老的項(xiàng)目使用的是$els,vue2 使用 ref)手動(dòng)觸發(fā) click 事件并且可以在change事件中默認(rèn)接收一個(gè)文件信息對(duì)象其中target.files[0]包含文件的更多信息,如下圖:
判斷文件類型
可以看到 change 事件的返回值包含著文件屬性,這里我們需要判斷是文件名是否為 excel,使用正則的 test 方法。
重置change事件
在最后 this.$refs.uploadFile.value = null; 移除文件,可以保證上傳同樣的文件時(shí),也會(huì)觸發(fā) change 事件
優(yōu)化樣式
至此關(guān)于表單方面的功能都已經(jīng)實(shí)現(xiàn)了,由于原始的radio樣式比較丑,而且不能更改。下面我們就想辦法將它做的漂亮些。
// template
<label v-for="(item,index) in radioList"
:key="item.value"
:for="item.linkLabel"
:accesskey="index">
<span class="content__input">
<span class="radio__replace"
:class="{'radio__replace--checked':selectedRadio===item.value,'radio__replace--disable':item.isDisabled}">
</span>
<input v-model="selectedRadio"
type="radio"
class="radio__button"
name="radio"
:id="item.linkLabel"
:tabindex="index"
:value="item.value"
:disabled="item.isDisabled"
@focus="item.isFocus = true"
@blur="item.isFocus = false" />
</span>
<span class="content__text">{{item.label}}</span>
</label>
// data
data() {
return {
radioList: [
{
linkLabel: 'label1',
value: '1',
isDisabled: false,
isFocus: false,
label: '標(biāo)簽1'
},
{
linkLabel: 'label2',
value: '2',
isDisabled: false,
isFocus: false,
label: '標(biāo)簽2'
},
{
linkLabel: 'label3',
value: '3',
isDisabled: true,
isFocus: false,
label: '標(biāo)簽3'
}
],
selectedRadio: '1'
}
- 這里使用遍歷的方式在data中定義多個(gè)radio,在前面我們講到過(guò)radio的基本用法,使用label的for屬性和input的for屬性實(shí)現(xiàn)關(guān)聯(lián)起來(lái)。(這里我將input放在label內(nèi),這樣點(diǎn)擊整個(gè)label都會(huì)選中,沒(méi)有l(wèi)abel和radio元素之間的間隙)。
- name相同的radio會(huì)實(shí)現(xiàn)單選效果,tabindex代表使用"Tab"鍵的遍歷順序 ,value是選中時(shí)v-model綁定的selectedRadio也就會(huì)跟著變更
- 實(shí)現(xiàn)個(gè)性化樣式的關(guān)鍵在于結(jié)構(gòu)就是用一個(gè)類名content__input標(biāo)簽將類名radio__replace和radio包起來(lái)。設(shè)置定位層級(jí)(相當(dāng)于radio被覆蓋了,然而只要點(diǎn)擊到labelradio就會(huì)被選中)
- 通過(guò)selectedRadio選中的值和當(dāng)前radio值做對(duì)比,以及isDisabled這些Boolean值來(lái)動(dòng)態(tài)綁定class實(shí)現(xiàn)我們自定義的radio樣式切換
效果如下:
其實(shí)radio__replace類名對(duì)應(yīng)的標(biāo)簽就是我們自定義的radio,其中的白色原點(diǎn)是通過(guò)偽類生成的css代碼放在最后,感興趣可以看下
偽類樣式修改
如果想通過(guò)類名來(lái)改變白色原點(diǎn)的樣式,可以通過(guò)權(quán)重來(lái)改變。如下通過(guò)isShow來(lái)給外層添加test類名 而起始的時(shí)候設(shè)置的權(quán)重為兩層,之后添加一層可以起到修改樣式的效果。(ps:偽類不能通過(guò)預(yù)先設(shè)定好的類名來(lái)修改樣式)
例子代碼如下:
<div :class="{test:isShow}"
@click="onRedClick">
<div class="text__item"></div>
</div>
.text__item {
&:after {
content: '';
width: 30px;
height: 30px;
background-color: #f00;
position: absolute;
bottom: 20px;
}
}
.test {
.text__item {
&:after {
background-color: #ff0;
}
}
}
// css
.radio {
&__replace {
border: 1px solid #dcdfe6;
border-radius: 100%;
width: 14px;
height: 14px;
background-color: #fff;
position: relative;
cursor: pointer;
display: inline-block;
box-sizing: border-box;
z-index: 999;
transition: 0.15s ease-in;
&--checked {
border-color: #409eff;
background-color: #409eff;
}
&--disable {
cursor: not-allowed;
}
&:after {
width: 4px;
height: 4px;
border-radius: 100%;
background-color: #fff;
content: '';
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
}
&__button {
opacity: 0;
outline: none;
position: absolute;
z-index: -1;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: 0;
}
}
總結(jié)
- 介紹了radio基本屬性,使用案例并優(yōu)化了radio的樣式
- 原始上傳文件元素的缺點(diǎn)以及改善方法
以上所述是小編給大家介紹的基于element-ui組件手動(dòng)實(shí)現(xiàn)單選和上傳功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
JS+Canvas實(shí)現(xiàn)動(dòng)態(tài)時(shí)鐘效果
這篇文章主要為大家詳細(xì)介紹了JS+Canvas實(shí)現(xiàn)動(dòng)態(tài)時(shí)鐘效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
GreyBox技術(shù)總結(jié)(轉(zhuǎn))
GreyBox是一個(gè)遮罩層的組件也稱模式窗口或模態(tài)窗口(所謂模態(tài)窗口,就是指除非采取有效的關(guān)閉手段,用戶的鼠標(biāo)焦點(diǎn)或者輸入光標(biāo)將一直停留在其上的窗口),它運(yùn)行以后可以產(chǎn)生不錯(cuò)的界面。2010-11-11
Bootstrap基本布局實(shí)現(xiàn)方法詳解
這篇文章主要為大家詳細(xì)介紹了Bootstrap基本布局實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
electron-builder 的基本使用及electron打包步驟
electron-builder 作為一個(gè)用于 Electron 應(yīng)用程序打包的工具,需要下載并使用 Electron 運(yùn)行時(shí)來(lái)創(chuàng)建可執(zhí)行文件,這篇文章主要介紹了electron-builder 的基本使用,需要的朋友可以參考下2023-12-12

