vuejs2 - VueJS 2/Bootstrap 4 - 防止从 bootstrap 4 的数据切换事件中关注元素
问题描述
使用 VueJS2 和 Bootstrap 4,我创建了一个自定义指令来与 Bootstrap 4 单选按钮组发生的更改进行交互。出现的问题是,当您更新引导程序 4 的数据时,元素组件会获得焦点,如果页面很小,这很好。但是如果页面很长并且可以滚动,这就会成为一种负担。
以下代码是根据以下示例复制和修改的:
https://getbootstrap.com/docs/4.0/components/buttons/#checkbox-and-radio-buttons
<div class="btn-group btn-group-sm" data-toggle="buttons" v-radio="oType">
<label class="btn btn-outline-dark active">
<input type="radio" name="oType" value="0" /> Pressure
</label>
<label class="btn btn-outline-dark">
<input type="radio" name="oType" value="1" /> Vacuum
</label>
</div>
我创建了以下 vue 自定义指令(radio.js):
注意:问题不在于绑定,问题仅在于插入/更新的钩子,它们与复制的代码完全相同。
export default {
inserted: function (el, binding, vnode) {
var btns = $(el).find('.btn');
var radioGrpName = $(btns[0]).find('input')[0].name;
$("input[name='" + radioGrpName + "'][value='" + binding.value + "']").closest('.btn').button('toggle');
},
bind: function (el, binding, vnode) {
var btns = $(el).find('.btn');
btns.each(function () {
$(this).on('click', function () {
var v = $(this).find('input').get(0).value;
(function set(obj, str, val) {
str = str.split('.');
while (str.length > 1) {
obj = obj[str.shift()];
}
return obj[str.shift()] = val;
})(vnode.context, binding.expression, v);
})
})
},
update: function (el, binding, vnode, oldnode) {
var btns = $(el).find('.btn');
var radioGrpName = $(btns[0]).find('input')[0].name;
$("input[name='" + radioGrpName + "'][value='" + binding.value + "']").closest('.btn').button('toggle');
}
}
问题是,如果我在页面下方的某处有 bootstrap 4 单选按钮组,并且我让用户设置了某种输入数据来自动更改单选按钮的数据,这会触发按钮('toggle')从指令(使用插入或更新钩子),专注于元素,在 html 页面中进行大跳跃。用户必须向上滚动才能继续他们离开的地方。
上面的单选按钮与更改的数据交互的方式是通过计算属性:
computedProperty: {
oType: {
get: function () {
return this.oType;
},
set: function (value) {
this.oType = value
}
}
}
那么如何防止焦点发生在元素上呢?
解决方案
于是我将问题追溯到bootstrap.js,在触发data-toggle的过程中,导致了问题的发生。所以在 radio.js 中,我切换了这一行:
$("input[name='" + radioGrpName + "'][value='" + binding.value + "']").closest('.btn').button('toggle');
并模仿外观和感觉:
$(el).children('.btn').removeClass('active');
$("input[name='" + radioGrpName + "'][value='" + binding.value + "']").closest('.btn').addClass('active');
$("input[name='" + radioGrpName + "'][value='" + binding.value + "']").prop('checked', true);