最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

Vue使用Sortable步骤详解

来源:懂视网 责编:小采 时间:2020-11-27 19:51:04
文档

Vue使用Sortable步骤详解

Vue使用Sortable步骤详解:这次给大家带来Vue使用Sortable步骤详解,Vue使用Sortable的注意事项有哪些,下面就是实战案例,一起来看一下。之前开发一个后台管理系统,里面用到了Vue和Element-UI这个组件库,遇到一个挺有意思的问题,和大家分享一下。场景是这样,在一个列表展示页上,
推荐度:
导读Vue使用Sortable步骤详解:这次给大家带来Vue使用Sortable步骤详解,Vue使用Sortable的注意事项有哪些,下面就是实战案例,一起来看一下。之前开发一个后台管理系统,里面用到了Vue和Element-UI这个组件库,遇到一个挺有意思的问题,和大家分享一下。场景是这样,在一个列表展示页上,

渲染出来后的DOM节点是

[$A,$B,$C,$D]

那么Virtual Dom对应的结构就是

[{elm:$A,data:'A'},
{elm:$B,data:'B'},
{elm:$C,data:'C'},
{elm:$D,data:'D'}]

假设拖拽排序之后,真实的DOM变为

[$B,$A,$C,$D]

此时我们只操作了真实DOM,改编了它的位置,而Virtual Dom的结构并没有改变,依然是

[{elm:$A,data:'A'},
{elm:$B,data:'B'},
{elm:$C,data:'C'},
{elm:$D,data:'D'}]

此时我们把列表元素也按照真实DOM排序后变成

[‘B','A','C','D']

这时候根据Diff算法,计算出的Patch为,VNode前两项是同类型的节点,所以直接更新,即把$A节点更新成$B,把$B节点更新成$A,真实DOM又变回了

[$A,$B,$C,$D]

所以就出现了拖拽之后又被Patch算法更新了一次的问题,操作路径可以简单理解为

拖拽移动真实DOM -> 操作数据数组 -> Patch算法再更新真实DOM

根本原因

根本原因是Virtual DOM和真实DOM之间出现了不一致。

所以在Vue2.0以前,因为没有引入Virtual DOM,这个问题是不存在的。

在使用Vue框架的时候要尽量避免直接操作DOM

解决方案

1、通过设置key唯一标志每一个VNode,这也是Vue推荐的使用v-for指令的方式。因为在判断两个VNode是否为同类型时会调用sameVnode方法,优先判断key是否相同

function sameVnode (a, b) {
 return (
 a.key === b.key &&
 a.tag === b.tag &&
 a.isComment === b.isComment &&
 isDef(a.data) === isDef(b.data) &&
 sameInputType(a, b)
 )
}

2、因为根本原因是真实DOM和VNode不一致,所以可以通过把拖拽移动真实DOM的操作还原,即在回调函数里,把[$B,$A,$C,$D]还原成[$A,$B,$C,$D],让DOM的操作交还给Vue

拖拽移动真实DOM ->还原移动操作 -> 操作数据数组 -> Patch算法再更新真实DOM

代码如下

var app = new Vue({
 el: '#app', 
 mounted:function(){
 var $ul = this.$el.querySelector('#ul')
 var that = this
 new Sortable($ul, {
 onUpdate:function(event){
 var newIndex = event.newIndex,
 oldIndex = event.oldIndex
 $li = $ul.children[newIndex],
 $oldLi = $ul.children[oldIndex]
 // 先删除移动的节点
 $ul.removeChild($li) 
 // 再插入移动的节点到原有节点,还原了移动的操作
 if(newIndex > oldIndex) {
 $ul.insertBefore($li,$oldLi)
 } else {
 $ul.insertBefore($li,$oldLi.nextSibling)
 }
 // 更新items数组
 var item = that.items.splice(oldIndex,1)
 that.items.splice(newIndex,0,item[0])
 // 下一个tick就会走patch更新
 }
 })
 },
 data:function() {
 return {
 message: 'Hello Vue!',
 items:[{
 key:'1',
 name:'1'
 },{
 key:'2',
 name:'2'
 },{
 key:'3',
 name:'3'
 },{
 key:'4',
 name:'4'
 }]
 }
 },
 watch:{
 items:function(){
 console.log(this.items.map(item => item.name))
 }
 }
 })

3.暴力解决!不走patch更新,通过v-if设置,直接重新渲染一遍。当然不建议这么做,只是提供这种思路~

 mounted:function(){
 var $ul = this.$el.querySelector('#ul')
 var that = this
 var updateFunc = function(event){
 var newIndex = event.newIndex,
 oldIndex = event.oldIndex
 var item = that.items.splice(oldIndex,1)
 that.items.splice(newIndex,0,item[0])
 // 暴力重新渲染!
 that.reRender = false
 // 借助nextTick和v-if重新渲染
 that.$nextTick(function(){
 that.reRender = true
 that.$nextTick(function(){
 // 重新渲染之后,重新进行Sortable绑定
 new Sortable(that.$el.querySelector('#ul'), {
 onUpdate:updateFunc
 })
 })
 })
 }
 new Sortable($ul, {
 onUpdate:updateFunc
 })
 },

相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!

推荐阅读:

vue-cli怎样做出跨域请求

Angular5对组件标签添加样式class步骤说明

JS怎样实现运算符重载

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文档

Vue使用Sortable步骤详解

Vue使用Sortable步骤详解:这次给大家带来Vue使用Sortable步骤详解,Vue使用Sortable的注意事项有哪些,下面就是实战案例,一起来看一下。之前开发一个后台管理系统,里面用到了Vue和Element-UI这个组件库,遇到一个挺有意思的问题,和大家分享一下。场景是这样,在一个列表展示页上,
推荐度:
标签: VUE 使用vue sortable
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top