sortable.js——Vue 数据更新问题
从一个 bug 说起
在一个需求中,我需要实现一个拖拽的功能,其中我使用了 sortable.js
去实现,但我发现我拖拽之后的数据并没有渲染在页面上。
简而言之,举个例子,原先的数组是 [1,2,3,4],拖拽之后,变成了 [4,1,2,3],但在视图上并没有显现,这不经让我疑惑不解,开始了以下问题的探索,在此记录一下
Vue 的数组更新问题
看到以上问题,你肯定会认为我处理数组的方式不对,毕竟官方文档明确指出了数组的几个坑
以下参考 Vue 文档 由于 JavaScript 的限制,Vue 不能检测以下数组的变动: 1.当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue 2.当你修改数组的长度时,例如:vm.items.length = newLength
但是实际上,我避开了这个坑,实际的实现是通过 splice
实现的,这样实际上是不会有问题的。
-
const tempItem = me.tabs.splice(e.oldIndex,
1)[0]
-
me.tabs.splice(e.newIndex,
0, tempItem)
题外话
实际上,我们在 Vue
的数组书使用 splice
、 push
等方法, Vue
都已经做了一层封装,所以它们才能出发视图更新,如果有想更加深入了解,可以阅读[源码]:https://ustbhuangyi.github.io/vue-analysis/reactive/questions.html#%E6%95%B0%E7%BB%84。
Vue 强制刷新——$forceUpdate()
对于这一点,尤大大表示,一般而言,我们都不需要用到的,如果需要用到的话,99.9%的情况,是自身的问题。
而 $forceUpdate()
的功能,就是迫使实例重新渲染,但尴尬的是,我使用了之后并没有效果,我觉得是我用错了,O__O "…
类似的代码如下:
-
// 在控制变量改变的时候进行 强制渲染更新
- let childrenRefs = this.refs.elTabs.children
-
this.$nextTick(()
=>
{
-
childrenRefs.forEach(child => child.$forceUpdate())
-
})
参考:http://www.imooc.com/wenda/detail/439493
最后的解决方法
其实对于最后的解决方法,来源于 segmentfault
,我还是心存疑问的,废话少说,我们来看代码
先用一个数据深拷贝数据,这里使用了 slice
方法,然后置空,最后在 $nextTick
中赋值深拷贝出来的数组值。最后可以了。
我猜测有两个,数组的长度不变,只是数组的长度变化, Vue
检测不到,对于这个猜想,很容易就被自己推翻了,毕竟试了一下,并不会这样的。
那就可能是 sortable.js
的问题了
-
// 代码参考:https://segmentfault.com/q/1010000009672767
-
mounted :
function
()
{
-
var that =
this;
-
var sortable1 =
new
Sortable(document.querySelector('#topicNumBox'),
{
-
sort:
true,
-
animation:
300,
-
onEnd:
function
(evt)
{
//拖拽结束发生该事件
-
that.questionData.splice(evt.newIndex,
0, that.questionData.splice(evt.oldIndex,
1)[0]);
-
var newArray = that.questionData.slice(0);
-
that.questionData =
[];
-
that.$nextTick(function
()
{
-
that.questionData = newArray;
-
});
-
},
-
});
-
}
结论
虽然问题解决了,但是最终的根源并没有找到O__O "…
但也提供一两种很强势的刷新数据的方法,以后需要用到的时候可以试下(愿你不会用到)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Flutter Dojo设计之道——利用Github打造完善的开源项目
- 最强 Redis 客户端 lettuce 已支持 Redis6客户端
- 还在手动整理数据库文档?试试这个工具
- Elasticsearch 常见的 8 种错误及最佳实践
- Spark流式状态管理
- Scala中的IO操作及ArrayBuffer线程安全问题
- 设计模式之单例模式
- Roslyn 理解 msbuild 的清理过程
- gorm聚合查询group结合join和count
- 潘石屹用Python解决100个问题 | 集合
- Catalina 默认使用zsh了,你可习惯
- LeetCode 354 Russian Doll Envelopes (动态规划)
- 设计模式之原型模式
- 设计模式之工厂方法模式
- Python 随机数生成