开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情
需求:显示填空题,数据为string格式,一道填空题内包含多个小题、多个填空,小括号表示代填空格,需将小括号转化为输入框,并能够记录输入答案用';'分割。项目使用的vue2.0.如何实现呢?
为了实现这个需求,我用了vue中的render函数。
什么是render函数呢?
在vue脚手架的main.js中就用到了render函数。
使用render函数可以用js构建dom。当使用render函数描述虚拟DOM时,vue提供一个函数,这个函数是就构建虚拟DOM所需要的工具。官网上给他起了个名字叫createElement。还有约定的简写叫h。
render函数的语法:
render: (h,context)=>{return h(‘el’,{‘css’},vnodeArr)}
render函数的具体用法这里不做赘述,下面对实现思路进行阐述。
方法一
- 正则匹配小括号
let reg = new RegExp("([\s]*)|[(][\s]*[)]|([\s]*[)]|[(][\s]*)", "g");
- 将填空题里的小括号转化为_
let fillText=text.replace(reg,'_')
- 将转化后的字符串遍历每个字符,当遇到_时添加input并添加change监听事件
return h("span", {}, fillText
.map((d) => {
if (d == "_") {
return h("input", {
//相当于给input上的属性
attrs: {
value: value[id++],
autofocus: true,
class: "text",
name: that.value.questionId,
id: id,
},
//input框的监听事件
on: {
change: that.change,
},
});
}else {
return h("span", {
domProps: {
innerHTML: d,
}
}, []);
}
}));
此种方法基本可以实现要求,但存在一个致命的问题,就是若原有字符串里含有标签将无法正常显示,比如包含表格。 发现此问题后,整个字符串就不能被分割,只能以整体的形式存在,以innerHTML的形式对整个字符串进行显示。
方法二
- 正则匹配小括号
- 将填空题的小括号转化为input标签的字符串
let fillText = that.text.replace(reg, function () {
// id += 1;
let inputDom
// let inputDom = `<input autofocus="true" class="text" style="text-align: center" value="${value[id]}" id="${id++}">`
if (value[id]) {
inputDom = `<input autofocus="true" class="text" style="text-align: center" value="${value[id]}" id="${id++}">`
} else {
inputDom = `<input autofocus="true" class="text" style="text-align: center" value="" id="${id++}">`
}
return inputDom
});
- 添加虚拟dom,用innerHTML(取代v-html)添加内容,onchange监听输入变化
return h("span", {
domProps: {
innerHTML: fillText,
onchange: that.change
}
}, [])
此种方法,不管填空题里包含什么样的标签都可以正常显示。
以前从没用过render函数,这是第一次使用,若有其它实现思路,请评论区告诉我,谢谢。