vue 填空(一个文字一个方格)
- 当前题目的数据
data() { return { questionName: "举头望__,低头思___头思_", blankNameList: [], blankList: [], //绑定每一个格子的model,用于处理用户输入的答案 } },
- 根据标题,处理好格子数,以及每一个方格所在位置,绑定到model,用于页面渲染
/** * 处理数据 */ arrayCount(data){ let newdata = [] let index = 1; let i = 0; for(let k in data){ let {type,content} = data[i]; let {type:type2} = data[i+1]||{} i++; //类型相同且内容相同 if(type===type2 && content === "_"){ index++; }else{ newdata.push({ ...data[k], hasCol:index }) index = 1; } } return newdata; }, arrObj(nameList){ let arrd = []; nameList.forEach((item, i) => { if (item === '_') { arrd.push({ type: 'input', content: "_", }) } else { arrd.push({ type: 'txt', content: item, }) } }) return arrd }, /* 处理填空题标题 */ handleBlankTile(questionName) { const nameList = questionName.split(''); let arrd = this.arrObj(nameList); console.log(arrd) let arrList = this.arrayCount(arrd); let idx = 1; let blankList = []; arrList.forEach((item)=>{ if (item.type === "input") { let data = []; for (let i = 0; i < item.hasCol; i++) { data.push({index: idx++}) blankList.push("") } item.content = data } }) this.blankNameList = arrList; this.blankList = blankList; },
得到的数据格式( blankNameList, blankList )
- 根据以上处理好的数据来渲染html代码
<div class="title bank-title"> <template v-for="(subItem, subIdx) in blankNameList"> <template v-if="subItem.type === 'input'" id="id_inpt"> <input v-for="(itemIpt, iptIdx) in subItem.content" type="text" :class="['unit-cell-input', 'inputVal']" ref="ids_ipt" v-model="blankList[itemIpt.index - 1]" @input="inputChange($event, itemIpt.index)" @click="changeIdx" @keyup.delete="KeyDelete" /> </template> <span v-else>{{subItem.content}}</span> </template> </div>
- 判断用户是要输入还是删除,分以下几种情况
a.单文字输入直接将焦点转移到下一个输入框 b.删除将焦点转移到上一个输入框 c.多文字输入填充
1.拿到用户当前输入框所有文字集合数组 2.定位是从第几个框开始输入, 3.输入的文字字数和当前框到最后一个框的输入框数量的关系,是否超出等 4.将焦点放到最后一个文字所在的输入框 5.将文字赋值到blankList,更新视图 (不然有bug) 6.储存用户输入的答案
/* 填空题输入效果——输入框自动失焦以及转移到下个焦点 */ inputChange(e, iptI) { this.$nextTick(() => { const els = this.$refs.ids_ipt; switch (e.inputType) { case 'insertText': case 'insertFromPaste': const str = els[iptI - 1].value const strList = str.split('') const strL = strList.length const elsL = els.length // alert(strL) if (strL > 1) { strList.map((item, i) => { if (i < elsL - iptI + 1) { els[iptI - 1 + i].value = item this.$set(this.blankList, iptI - 1 + i, item) } if (i === strL - 1) { // 字数等于或大于空格数时焦点到最后一个空格 if (strL > elsL - iptI || strL === elsL - iptI) { els[elsL - 1].focus() } else { els[iptI + i].focus() } } }) } else { if (str !== els.length) { if (iptI === this.blankList.length) { els[iptI-1].focus() } else { els[iptI].focus() } } } break case 'deleteContentBackward': if (iptI > 1) { els[iptI - 2].focus() } break } // this.getUserKey(this.currentIdx - 1) //保存用户答案 }) }, /** * 根据ref获取相对应下标焦点,将焦点移动最后面 */ changeIdx () { let findIndex = this.blankList.findIndex(item => !item) if (findIndex === -1) { findIndex = this.blankList.length - 1; } this.$nextTick(function(){ this.$refs.ids_ipt[findIndex].focus() let t = this.$refs.ids_ipt[findIndex].value; this.$refs.ids_ipt[findIndex].selectionStart = this.$refs.ids_ipt[findIndex].selectionEnd = t.length; }) },
/**
* 监听删除事件
*/
KeyDelete (){
let findIndex = this.blankList.findIndex(item => !item)
if (findIndex === -1) {
findIndex = this.blankList.length - 1;
}
this.$nextTick(function(){
if (findIndex>0) {
this.$refs.ids_ipt[findIndex-1].focus()
let t = this.$refs.ids_ipt[findIndex-1].value;
this.$refs.ids_ipt[findIndex-1].selectionStart = this.$refs.ids_ipt[findIndex-1].selectionEnd = t.length;
} else {
this.$refs.ids_ipt[findIndex].focus()
let t = this.$refs.ids_ipt[findIndex].value;
this.$refs.ids_ipt[findIndex].selectionStart = this.$refs.ids_ipt[findIndex].selectionEnd = t.length;
}
})
}, -
.bank-title { margin-bottom: 40px; display: flex; flex-wrap: wrap; input { width: 15px; height: 21px; display: inline-block; text-align: center; border: 1px solid transparent; } .unit-cell-input { width: 21px; height: 21px; background: #dedee2; margin: 0 4px; font-weight: bold; color: transparent; text-shadow: 0 0 0 #5050de; &:focus { border: 1px solid #5656df; } } }
-
-
参考: https://blog.csdn.net/alisa_lisa/article/details/111823217