在用戶使用過程當中提出一鍵導入的功能,需求以下:點擊導入按鈕顯示提示框,而後是單選框以及上傳按鈕。pc端常使用element-ui組件,可是這個項目是vue1的老項目,而且沒有element-ui組件。因此須要本身動手實現單選功能和上傳功能。 css
// 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>
複製代碼
// 暫定的數據
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',
}
複製代碼
經過 v-model 綁定 selectedDay,匹配到相同的值會將該 radio 選中,當改變 radio 的選擇,selectedDay 也會動態的變動成選中的 radio 的 valuehtml
<div class="upload__button"
:class="{'upload__button--uploaded':isUploaded}"
@click="onUploadClick">點擊上傳</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('文件格式錯誤,請確認後重試。')
}
},
}
複製代碼
當點擊上傳按鈕觸發 onUploadClick 事件後,獲取到 upload 綁定的 DOM (因爲是老的項目使用的是$els,vue2 使用 ref
)手動觸發 click 事件
而且能夠在change事件中默認接收一個文件信息對象其中target.files[0]
包含文件的更多信息,以下圖:vue
能夠看到 change 事件的返回值包含着文件屬性,這裏咱們須要判斷是文件名是否爲 excel,使用正則的 test 方法。element-ui
在最後 this.$refs.uploadFile.value = null; 移除文件,能夠保證上傳一樣的文件時,也會觸發 change 事件bash
至此關於表單方面的功能都已經實現了,因爲原始的radio樣式比較醜,並且不能更改。下面咱們就想辦法將它作的漂亮些。app
// 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: '標籤1'
},
{
linkLabel: 'label2',
value: '2',
isDisabled: false,
isFocus: false,
label: '標籤2'
},
{
linkLabel: 'label3',
value: '3',
isDisabled: true,
isFocus: false,
label: '標籤3'
}
],
selectedRadio: '1'
}
複製代碼
關聯起來
。(這裏我將input放在label內,這樣點擊整個label都會選中,沒有label和radio元素之間的間隙
)。name
相同的radio會實現單選效果
,tabindex
表明使用"Tab"鍵的遍歷順序
,value是選中時v-model綁定的selectedRadio也就會跟着變動關鍵在於結構
就是用一個類名content__input
標籤將類名radio__replace
和radio包起來。設置定位層級(至關於radio被覆蓋了,然而只要點擊到labelradio就會被選中)selectedRadio
選中的值和當前radio值作對比,以及isDisabled這些Boolean值
來動態綁定class
實現咱們自定義的radio樣式切換效果以下:優化
其實radio__replace
類名對應的標籤就是咱們自定義的radio,其中的白色原點是經過僞類生成的css代碼放在最後,感興趣能夠看下ui
若是想經過類名來改變白色原點的樣式,能夠經過權重來改變。以下經過isShow來給外層添加test類名
而起始的時候設置的權重爲兩層,以後添加一層能夠起到修改樣式的效果。(ps:僞類不能經過預先設定好的類名來修改樣式)例子代碼以下:this
<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;
}
}
複製代碼
基本屬性
,使用案例並優化了radio的樣式
缺點
以及改善方法