|
@@ -21,7 +21,7 @@
|
|
|
</view>
|
|
</view>
|
|
|
<view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}">
|
|
<view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}">
|
|
|
<text class="checklist-text" :style="item.styleIconText">{{item[map.text].includes('##') ? item[map.text].slice(0,-2) : item[map.text]}}</text>
|
|
<text class="checklist-text" :style="item.styleIconText">{{item[map.text].includes('##') ? item[map.text].slice(0,-2) : item[map.text]}}</text>
|
|
|
- <input v-show="(item[map.text].includes('##')) && item.selected" type="text" placeholder="请输入" class="multiple-Input" v-model="item.inputValue" @change="inputChange('',$event)">
|
|
|
|
|
|
|
+ <input v-show="(item[map.text].includes('##')) && item.selected" type="text" placeholder="请输入" class="multiple-Input" v-model="item.inputValue" @input="inputChange('',$event)" @change="inputChange('',$event)">
|
|
|
<view v-if="mode === 'list' && icon === 'right'" class="checkobx__list" :style="item.styleBackgroud"></view>
|
|
<view v-if="mode === 'list' && icon === 'right'" class="checkobx__list" :style="item.styleBackgroud"></view>
|
|
|
</view>
|
|
</view>
|
|
|
</label>
|
|
</label>
|
|
@@ -38,7 +38,7 @@
|
|
|
</view>
|
|
</view>
|
|
|
<view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}">
|
|
<view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}">
|
|
|
<text class="checklist-text" :style="item.styleIconText">{{item[map.text].includes('##') ? item[map.text].slice(0,-2) : item[map.text]}}</text>
|
|
<text class="checklist-text" :style="item.styleIconText">{{item[map.text].includes('##') ? item[map.text].slice(0,-2) : item[map.text]}}</text>
|
|
|
- <input v-show="(item[map.text].includes('##')) && item.selected" type="text" placeholder="请输入" class="multiple-Input" v-model="item.inputValue" @change="inputChange('',$event)">
|
|
|
|
|
|
|
+ <input v-show="(item[map.text].includes('##')) && item.selected" type="text" placeholder="请输入" class="multiple-Input" v-model="item.inputValue" @input="inputChange('',$event)" @change="inputChange('',$event)">
|
|
|
<view v-if="mode === 'list' && icon === 'right'" :style="item.styleRightIcon" class="checkobx__list"></view>
|
|
<view v-if="mode === 'list' && icon === 'right'" :style="item.styleRightIcon" class="checkobx__list"></view>
|
|
|
</view>
|
|
</view>
|
|
|
</label>
|
|
</label>
|
|
@@ -162,6 +162,10 @@
|
|
|
},
|
|
},
|
|
|
value(newVal) {
|
|
value(newVal) {
|
|
|
let that = this;
|
|
let that = this;
|
|
|
|
|
+ // 打字时(inputChange)自己往外 emit 这个值,只是为了让父组件的 item.answer 跟着同步,
|
|
|
|
|
+ // 这里的 dataList 本来就已经是最新的了,不需要也不应该借着这次赋值再重建一遍
|
|
|
|
|
+ // (重建会整个替换 dataList,正在输入的框可能因此丢失焦点/光标,见 inputChange 里的说明)
|
|
|
|
|
+ if (that._skipModelRebuild) { that._skipModelRebuild = false; return }
|
|
|
that.dataList = that.getDataList(newVal)
|
|
that.dataList = that.getDataList(newVal)
|
|
|
// fix by mehaotian is_reset 在 uni-forms 中定义
|
|
// fix by mehaotian is_reset 在 uni-forms 中定义
|
|
|
// if(!this.is_reset){
|
|
// if(!this.is_reset){
|
|
@@ -170,6 +174,7 @@
|
|
|
// }
|
|
// }
|
|
|
},
|
|
},
|
|
|
modelValue(newVal) {
|
|
modelValue(newVal) {
|
|
|
|
|
+ if (this._skipModelRebuild) { this._skipModelRebuild = false; return }
|
|
|
this.dataList = this.getDataList(newVal);
|
|
this.dataList = this.getDataList(newVal);
|
|
|
// if(!this.is_reset){
|
|
// if(!this.is_reset){
|
|
|
// this.is_reset = false
|
|
// this.is_reset = false
|
|
@@ -193,7 +198,10 @@
|
|
|
},
|
|
},
|
|
|
isTop: 0,
|
|
isTop: 0,
|
|
|
nowRecordList:[],//记录当前选择
|
|
nowRecordList:[],//记录当前选择
|
|
|
- saveList:[]
|
|
|
|
|
|
|
+ saveList:[],
|
|
|
|
|
+ // inputChange 往外 emit modelValue 只是为了同步父组件的 item.answer,配合 value/modelValue
|
|
|
|
|
+ // watcher 用来跳过那一次没必要、还可能打断正在输入的重建
|
|
|
|
|
+ _skipModelRebuild: false
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
|
computed: {
|
|
computed: {
|
|
@@ -314,6 +322,9 @@
|
|
|
this.dataList = this.getDataList(detail.value)
|
|
this.dataList = this.getDataList(detail.value)
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
+ // 修复:填空框原来只绑定了 @change(失焦/回车才触发),如果用户打完字直接点提交、
|
|
|
|
|
+ // 输入框没有失焦,这次编辑就完全没被记录下来,提交内容里这一项还是打字之前的旧值(甚至是空的)。
|
|
|
|
|
+ // 现在同时绑定 @input,每敲一个字都会同步一次,不再依赖"有没有失焦"这个时机。
|
|
|
inputChange(type,e){
|
|
inputChange(type,e){
|
|
|
console.log('datalistInput,',e)
|
|
console.log('datalistInput,',e)
|
|
|
let detail = {
|
|
let detail = {
|
|
@@ -352,9 +363,16 @@
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
console.log('selectedValue92929',detail)
|
|
console.log('selectedValue92929',detail)
|
|
|
- // this.$emit('input', detail.value);
|
|
|
|
|
- // // // TOTO 兼容 vue3
|
|
|
|
|
- // this.$emit('update:modelValue', detail.value);
|
|
|
|
|
|
|
+ // 修复:原来这两行是注释掉的,导致父组件 v-model 绑定的 item.answer 只有勾选/取消勾选时才会
|
|
|
|
|
+ // 同步,打字编辑永远不会同步——如果用户对同一题的操作顺序是"先勾选、再打字"(而不是"打完字
|
|
|
|
|
+ // 又去点别的勾选框"),item.answer 就会一直停留在打字之前的旧快照上,表单提交前的完整性校验
|
|
|
|
|
+ // (读的正是 item.answer)会一直误判成"没填",即使实际要提交的内容早就是对的。
|
|
|
|
|
+ // 这里把 emit 打开,让 item.answer 跟着每次打字同步;同时给 _skipModelRebuild 打标记,
|
|
|
|
|
+ // 配合 value/modelValue watcher 跳过因为这次 emit 引发的重建(dataList 现在已经是最新的,
|
|
|
|
|
+ // 不需要再重建一遍,重建反而可能打断正在输入的框)。
|
|
|
|
|
+ this._skipModelRebuild = true
|
|
|
|
|
+ this.$emit('input', detail.value);
|
|
|
|
|
+ this.$emit('update:modelValue', detail.value);
|
|
|
this.$emit('change', {
|
|
this.$emit('change', {
|
|
|
detail
|
|
detail
|
|
|
})
|
|
})
|
|
@@ -364,8 +382,10 @@
|
|
|
// this.dataList = this.getDataList(detail.value, true)
|
|
// this.dataList = this.getDataList(detail.value, true)
|
|
|
// }
|
|
// }
|
|
|
} else {
|
|
} else {
|
|
|
-
|
|
|
|
|
- this.dataList = this.getDataList(detail.value)
|
|
|
|
|
|
|
+ // 单选场景下 detail.value 是数组(上面统一按 push 方式构建的),但 getDataList 单选分支
|
|
|
|
|
+ // 是按"传入的是一个值"来解析的(取首字符当选项标识),直接把数组传进去每个 typeof 判断都对不上,
|
|
|
|
|
+ // 会导致 item.selected 全部算不出来、勾选状态和填空框跟着一起消失,这里取数组里唯一的一项传进去
|
|
|
|
|
+ this.dataList = this.getDataList(detail.value.length ? detail.value[0] : '')
|
|
|
}
|
|
}
|
|
|
// console.log('selectedValue6656565',this.dataList)
|
|
// console.log('selectedValue6656565',this.dataList)
|
|
|
},
|
|
},
|
|
@@ -514,12 +534,14 @@
|
|
|
// console.log('otherObj77777',otherObj)
|
|
// console.log('otherObj77777',otherObj)
|
|
|
item.inputValue = otherObj.end
|
|
item.inputValue = otherObj.end
|
|
|
// console.log('otherObj77777',item)
|
|
// console.log('otherObj77777',item)
|
|
|
- // 多选下 item.selected 上面按 value 数组已经正确算过了,这里不再需要、也不能再用 item.value = otherObj.end
|
|
|
|
|
- // 去覆盖 —— item.value 是这个 checkbox 原生 value 属性绑定的标识,多选场景下改成填写的文本内容,
|
|
|
|
|
- // 会导致下一次勾选变化时对不上号,选中状态跟着丢
|
|
|
|
|
|
|
+ // 之前这里不管单选多选,只要匹配上就会把 item.value 整个改成填写的文本内容——item.value 是
|
|
|
|
|
+ // checkbox 原生 value 属性绑定的标识(比如"E"),选中状态靠它和 item_number 对比来判断。
|
|
|
|
|
+ // 改了之后下一次编辑/切换再用 item.value 去拼自描述串或者做选中判断就全错位了(单选场景之前
|
|
|
|
|
+ // 只排除了多选,单选这条尾巴一直留着,导致单选"其他"填空打完字失焦后连带选中状态一起丢)。
|
|
|
|
|
+ // item.selected 上面 sliceInput === item.item_number 那步已经算对了,这里不再需要,
|
|
|
|
|
+ // 文本内容已经通过 item.inputValue 记录,不需要也不能再动 item.value。
|
|
|
if(!this.multiple && otherObj.start === item.value){
|
|
if(!this.multiple && otherObj.start === item.value){
|
|
|
item.selected = true;
|
|
item.selected = true;
|
|
|
- item.value = otherObj.end;
|
|
|
|
|
}
|
|
}
|
|
|
// showOtherInputVal 反推不出来时,用重建前缓存的内容(按下标)兜底,避免多选下切换勾选把已填文本冲掉
|
|
// showOtherInputVal 反推不出来时,用重建前缓存的内容(按下标)兜底,避免多选下切换勾选把已填文本冲掉
|
|
|
if (this.multiple && !item.inputValue && prevInputMap[index]) {
|
|
if (this.multiple && !item.inputValue && prevInputMap[index]) {
|