如题,在el-table中使用el-popover,没法点击确定或取消来关闭el-popover。
怀疑是作用域的问题,但是我把v-model改成row.visible2,@click的时候row.visible2 = false,这样也不行。所以感觉应该是个bug。
在talble外面使用el-popver是没问题的,而且点击popover区域外的地方也可以关闭popover,偏偏不能通过改变visible2 = false来关闭,不知道现在还有没有其他方式暴露出来可以控制hide。
参考代码:http://jsfiddle.net/acx0gnx3/ ,点击删除打开popover。
table 里用 popover 请使用 slot 的方式
@QingWei-Li 呃,我现在这样不是也是slot在el-table-column上的么。能不能举个例子,实在不太理解是哪种slot方式。抱歉抱歉。
我指的是 popover
<el-popover
placement="right"
title="标题"
width="200"
trigger="focus"
content="这是一段内容,这是一段内容,这是一段内容,这是一段内容。">
<el-button slot="reference">focus 激活</el-button>
</el-popover>
@QingWei-Li slot的方式确实可以替代ref解决点击“删除”按钮弹出popover问题。但现在用这种方式还是存在popover内的“确定”和“取消”这两个按钮点击后改成visible2这个值为false没法关闭popover的问题。就是popover没有消失。不知道是不是我哪里用不对。通过v-model来控制显示和消失,我是参考官网文档popover里面的样例做的。
但放在el-table里就不好用了。
这是因为 visible2
在 column 里只是一个拷贝,并非实例上的 visible2,这个是已知问题。在 1.1
里我们计划把自定义模板的方式换成 Vue 的 scoped slot,就能解决这个问题。现在的话只能通过绑定方法的方式。
<el-table-column :context="_self" inline-template label="操作">
<el-popover
placement="right"
title="确定删除?"
width="200"
v-model="visible2"
trigger="click">
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="updateVisible(true)">取消</el-button>
<el-button type="primary" size="mini" @click="updateVisible(false)">确定</el-button>
</div>
<el-button slot="reference">删除</el-button>
</el-popover>
</el-table-column>
然后定义一个 updateVisible 方法
@QingWei-Li 好的,果然还是作用域的问题。我看看怎么先凑合用吧。谢谢。
updateVisible () {
this.visible2 = true;
setTimeout(() => {
this.visible2 = false;
}, 0);
}
用了这种比较tricky的方式可以实现了。
没必要吧,直接写成这样不就好了么
updateVisible(val) { this.visible2 = val }
这样不行。直接改成false好像没生效。表示很奇怪。。。必须得先设置成true,再变成false才会生效。。感觉是得让this重新变化再把值传到column才行?可能和vue更新机制有关系?有点费解。
哦 还是上下文的问题 popover 不能用 v-model ....
好吧略坑,等 1.1 我们加入 scoped slot 的方式吧
el-table-column里面嵌入 el-switch 后 switch开关无效! 看了上面您们讨论的 还是不行啊 switch 不起作用!
DreamFox 你可以用了吗? 你解决了吗?
@DreamFox
@hujianjian187 按照我上面说的那样修改v-model是可以的。。你试试吧。你最好给个jsfiddle之类的,好说清楚
@DreamFox 刚解决了 不是你那么写的
on-color="#13ce66"
off-color="#ff4949" @change="visibile">
</el-table-column>
visibile:function(){
this.value1 = !this.value1;
}
你直接改this.value居然就可以,我得setTimeout才行。反正是上下文的问题。
@DreamFox 我用的change 不是 click
@QingWei-Li
艾特我干啥 😂
现在的利用 inline-template
hack 的自定义模板功能坑有点多,1.1
后会支持 scoped slot 的方式并作为推荐用法。
@QingWei-Li 就是告诉您 这个解决了! 并感谢您思密达!
那我还是要把 inline-template
坑填了
请问,现在我用1.1.2,这个问题如何解决???
@wenner Scoped slot 具体看 Table 文档
@wenner 看文档!
我参考上面的代码....
<el-table-column width="100" align="center" label="操作">
<template scope="scope">
<div class="show-on-row-hover buttons">
<el-button type="primary" size="mini" @click="editItem(scope.row)">
编辑
</el-button>
<el-popover
placement="top"
title="确定删除?"
width="200"
v-model="visible2"
trigger="click">
<p>确定要删除当前记录吗?</p>
<p class="text-danger">将同时删除该机构的所有下级机构!</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="updateVisible(false , scope)">取消</el-button>
<el-button type="primary" size="mini" @click="updateVisible(true )">确定</el-button>
</div>
<el-button slot="reference" size="mini">删除</el-button>
</el-popover>
</div>
</template>
</el-table-column>
这样v-model = visible2 的话,是不显示的
如果 v-model = scope.visible2 , 是可以显示Popover的
如果 v-model = scope._self.visible2 , 还是不显示
因为对 这里面的scope不是很了解 , 所以不知道到底如何设置v-model,以及按钮事件
@wenner 后来你有解决吗?我也遇到了同样的问题,使用inline-template的写法是可以的,用slot却不行,即使拿到了scope,修改其中的变量,弹窗也关不掉。
@iamiota 并不行...而且现在连上面直接用v-model = visible2 一样不显示
不够可以稍微改多一点就可以了
<el-table-column width="100" align="center" label="操作">
<template scope="item">
<el-popover placement="top" title="确定删除?" width="200" v-model="item.row.visible2" trigger="click">
<p>确定要删除当前记录吗?p>
<p class="text-danger">将同时删除该机构的所有下级机构!</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="item.row.visible2 = false">取消</el-button>
<el-button type="primary" size="mini" @click="updateVisible(false , item )">确定</el-button>
</div>
<el-button slot="reference" size="mini">删除 {{item.row.visible2}}</el-button>
</el-popover>
</template>
</el-table-column>
methods:{
updateVisible(v , s){
s.row.visible2 = v;
//Vue.set(s.row , 'visible2', v);
}
} ,
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄' ,
visible2: false //必须有这个, 不然即使用Vue.set,也不起作用
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄',
visible21: false //比如这个,就不行
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄',
visible21: false
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄',
visible21: false
}]
}
}
总提说来基本是能达到预期要求
不过在dom里会有很多的el-popover的节点 , 不知道popover是单例的还是不是...
你可以试试
@wenner 谢啦哥们,把变量放到row上面确实可以 🙏🙏
恩,这个只是能解决这个问题而已...不过最费事的是需要在data中为每条记录提前设置visible2 , 不然就隐藏不掉..一般这样的问题以前用Vue.set就可以解决掉..但是这里面不行...
因为不太熟悉template scope , 也没太看这里实现的代码 , 所以没找到原因....
我猜测是不是在点击solt reference 的按钮时 , 直接给v-model的值设置为true , 而没有v-model对应的属性的话..就有问题了 , 只是猜测
1.当前这样有个问题 , 会改变其他行中的值,比如当前这种,打开一行的popover再关闭,可以看到其他行的button中也有了false的值
2.另外如果给 popover 加 @input 事件 , 可以看到会触发两次 ... 而在普通的v-model的popover只触发一次
3.我又实验了一下 , 将data中所有的visible2都去掉,就是说初始时没有这个属性 , 然后修改updaeVisible方法
updateVisible(v , s){
delete s.row.visible2;
//s.row.visible2 = v;
Vue.set(s.row , 'visible2', v);
}
就是先删除 visible2 , 然后再用 Vue.set , 这样第一个打开的popover就正常了 (就是点确定按钮,就会关闭 , 取消不行,因为没有初始visible2属性)
不过如果打开其他行, 打开时正常的 , 关闭就不正常了, 不管是点 取消 还是 确定 都不行..
反正不知道什么原因...只能不停尝试
期待开发者能给说一下..具体如何实现..给一个完整jsfiddle的例子
http://jsfiddle.net/f8rqagdm/1/
@wenner 没看懂为啥要 delete
和 Vue.set
。
@Leopoldthecoder
delete和Vue.set是想尝试下 不在tableData中初始化visbile2属性 ...一般吧数据取回来应该没有这属性..都要遍历加上去吧...只是试试
而就是现在这样,能发现些问题,并不影响使用
1.当前这样有个问题 , 会改变其他行中的值,比如当前这种,打开一行的popover再关闭,可以看到其他行的button中也有了false的值
上面这只要把data中其他记录的visible都给去掉, 然后给button中text = 删除{{scope.row.visible}}
2.另外如果给 popover 加 @input 事件 , 可以看到会触发两次 ... 而在普通的v-model的popover只触发一次
这个在普通的v-model时候,只触发一次
这并不影响使用...只是想知道为什么发生这些情况..
@Leopoldthecoder 在你的demo上加上了fixed后popover就不出来了
http://jsfiddle.net/f8rqagdm/6/
问题解决,感谢!
关于循环中使用popover出现的问题,不建议使用【为data数据的每个item加visible属性】的方式。
尤其当data在vuex中管理的时候,点击reference slot打开popover时对visible的修改并不符合vuex所要求的action->commit->mutation->state的数据修改原则,并会报错。
使用ref更简单易懂。如下:
<el-table-column width="100" align="center" label="操作">
<template scope="item">
<el-popover placement="top" title="确定删除?" width="200" :ref="'popover-' + scope.row.id" trigger="click">
<p>确定要删除当前记录吗?</p>
<p class="text-danger">将同时删除该机构的所有下级机构!</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="pCancel(scope.row.id)">取消</el-button>
<el-button type="primary" size="mini" @click="pSubmit(scope.row)">确定</el-button>
</div>
<el-button slot="reference" size="mini">删除</el-button>
</el-popover>
</template>
</el-table-column>
不一定是id(scope.row.id),只要能具备唯一性就好。
methods: {
pSubmit(row) {
new Promise().then(_ => {
/***submit处理后***/
this.pClose(row.id)
})
},
pCancel(id) {
this.pClose(id)
},
pClose(id) {
this.$refs[`popover-` + id].doClose()
}
}
使用了el-popover组件的doClose方法。
el-popover组件还提供了一些其他方法,也可以去看看,能解决一些疑难杂症。
楼上的处理个人觉得还是繁琐了点。我的处理方法:
此方法其实在官方的表格文档中已有示例,但只有 hover 的方式,click 的方法需要做个 hack:
<template>
<div ref="page">
...
<template scope="scope">
<el-popover trigger="click" placement="left-start">
<p>确定要删除 <span class="sf-red">{{ scope.row.name }}</span> 吗?</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click.native.prevent="$refs.page.click()">取消</el-button>
<el-button size="mini" type="primary" @click.native.prevent="handleOperationButtonClick(scope.row)">确定</el-button>
</div>
<el-button slot="reference" type="text" size="small">删除</el-button>
</el-popover>
</template>
...
</div>
</template>
@transtone thank u, it works!
感觉这个问题还是没解决,像popover这种东西的隐藏,最好是不用hack,非要用hack才能解决的话,说明这块还是有问题,最好就是popover能提供show和close方法,这样子在popover上加个ref就能解决table上popover无法隐藏的问题
@istobran 或许这样比较完美吧
[email protected]
<el-table-column width="100" align="center" label="操作">
<template slot-scope="scope">
<el-popover width="160" :ref="`popover-${scope.$index}`">
<p>确定删除该项吗?</p>
<div style="text-align: right; margin: 0">
<el-button type="text" size="mini" @click="scope._self.$refs[`popover-${scope.$index}`].doClose()">
取消
</el-button>
<el-button type="danger" size="mini" >确定</el-button>
</div>
<el-button type="text" slot="reference">删除</el-button>
</el-popover>
</template>
</el-table-column>
@weifeiyue thx,方法不错。
@weifeiyue 还好我翻到了最后面,感谢!
heah
@weifeiyue
[email protected]
doClose方法无效,请问还有别的方法吗
@weifeiyue
[email protected]
Cannot read property 'doClose' of undefined
"element-ui": "^2.4.5", have removed 'doClose' and 'doShow' these two methods, but this bug still exist .
@QingWei-Li
<div ref="closepopover">
<el-table-column label="操作">
<template slot-scope="item">
<el-popover
placement="right"
title="确定删除?"
width="200"
v-model="item.row.visible"
trigger="click">
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="updateVisible()">取消</el-button>
<el-button type="primary" size="mini" @click="updateVisible()">确定</el-button>
</div>
<el-button slot="reference">删除</el-button>
</el-popover>
</template >
</el-table-column>
//完美解决
updateVisible(){
this.$refs.closepopover.click();
}
在 popover 里面点击区域加入 input type='textarea' 在 input 的高度变化时,popover 带出来的框框不会随着框框撑高而进行位置变化,不懂有什么方法可以对她进行手动触发么
https://juejin.im/post/5b7e6fb4f265da4369366a2a 这个帖子试了可行, 给每个column设置ref
@istobran 或许这样比较完美吧
[email protected]<el-table-column width="100" align="center" label="操作"> <template slot-scope="scope"> <el-popover width="160" :ref="`popover-${scope.$index}`"> <p>确定删除该项吗?</p> <div style="text-align: right; margin: 0"> <el-button type="text" size="mini" @click="scope._self.$refs[`popover-${scope.$index}`].doClose()"> 取消 </el-button> <el-button type="danger" size="mini" >确定</el-button> </div> <el-button type="text" slot="reference">删除</el-button> </el-popover> </template> </el-table-column>
nb,幸亏看到了这里。哈哈,谢谢大佬。
Most helpful comment
@istobran 或许这样比较完美吧
[email protected]