当某个地方需要右键弹出信息,已供快速选择时,例如一些用到惯用语的地方。
输入框部分代码:
<el-row style="margin-top:50px">
<el-col :span="24">
<el-form-item label="意见"
prop="note1">
<div v-click-outside>
<div @contextmenu.prevent="rightShow">
<el-input type="textarea" :autosize="{ minRows: 4}" v-model="ruleForm.note1" @input="forceInput()" placeholder="请输入整改验收意见" ></el-input>
<ul id="menu" ref="msgRightMenu" v-show="isPersoncontextMenus">
<li @click.stop="selectPhrase(item)"
v-for="item in sceneList"
:key="item.id">{{ item.content}}</li>
</ul>
</div>
</div>
</el-form-item>
</el-col>
</el-row>
showRightMenu: false,
isPersoncontextMenus:false,
sceneList:[]
// 位置在 export default {} 里,点击输入框外的地方会关闭弹窗
directives: {
clickOutside: {//自定义指令:clickOutside
bind (el, bindings, vnode) {//自定义指令生命周期:bind ;参数:el, bindings, vnode
let handler = (e) => {
if (el.contains(e.target)) {
if (!vnode.context.isPersoncontextMenus) {
vnode.context.focus()
}
} else {
if (vnode.context.isPersoncontextMenus) {
vnode.context.blur()
}
}
}
el.handler = handler
document.addEventListener('click', handler)
},
unbind (el) {//自定义指令生命周期:unbind
document.removeEventListener('click', el.handler)
}
}
},
// methods
rightShow() {
let menu = this.$refs.msgRightMenu
this.isPersoncontextMenus = true
this.$post('/test/getList', {}, res => {
if (res.success === true) {
this.sceneList = res.data;
} else {
this.isCommiting = false
this.isPersoncontextMenus = false
}
})
var evt = event || window.event;
var clientWidth = document.documentElement.clientWidth || document.body.clientWidth ;
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
var clientHeight = document.documentElement.clientHeight || document.body.clientHeight ;
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop ;
//给left和top分别赋值为鼠标的位置;
menu.style.left = evt.pageX+"px";
menu.style.top = evt.pageY+"px";
//如果鼠标右边放不下菜单,就把left的值的改了
if(evt.pageX+100>clientWidth+scrollLeft){//菜单应该在鼠标左边;
var left1 = evt.pageX-100;
menu.style.left = left1+"px";
}
//如果鼠标下边放不下菜单,就把top的值的改了
if(evt.pageY+100>clientHeight+scrollTop){
var top1 = (evt.pageY-100);
menu.style.top = top1+"px";
}
menu.style.display = "block";
},
// 选择要用的常用语
selectPhrase(item) {
// if (item.content === '暂无惯用语') return
this.ruleForm.note1 = item.content
this.isPersoncontextMenus = false
},
// showNo(){
// console.log('showNo')
// console.log('showNossssssssssssssss')
// let menu = this.$refs.msgRightMenu
// menu.style.display = "none";
// },
focus () {
this.isPersoncontextMenus = true
let menu = this.$refs.msgRightMenu
menu.style.display = "block";
},
blur () {
this.isPersoncontextMenus = false
let menu = this.$refs.msgRightMenu
menu.style.display = "none";
},
如果加完右键功能,发现该输入框或者的内容无法修改,也无法输入。
出现该问题的原因是:vue页面进行数据渲染时,层次嵌套或者多重数据绑定导致该组件信息框数据不能被Vue实时监听到,以此出现了数据发生改变但页面上更新或删除对应信息框的数据毫无反应的现象,此时需要强制更新,重新渲染。
可以在输入框添加@input=“forceInput()”,然后在methods中添加方法:
forceInput() {
this.$forceUpdate();
},
forceUpdate用来强制渲染,避免data中对象层次太深,Vue框架不自动渲染的情况。