在項目時用到了一些插件,比如這次用了下拉菜單插件。
這個插件需要實例化,而下拉框的數據是通過ajax來獲取的,然后在用 v-for 渲染數據,再次遇到了一個問題。
就是等插件實例化完畢,數據卻還沒渲染完畢,所以這就出現一個bug。出現bug解決掉。
第一種解決方法: settimeout
setTimeout(function() { //實例初始化 },100)
但是這種方法有一個缺點,就是不確定 數據 什么時候渲染完畢。
第一種情況: 假設10毫秒渲染完畢,但是setTimeout需要等100毫秒,浪費了90毫秒。
第二種情況:假設數據需要 200 毫秒執行完畢,但是 100毫秒就執行了 實例初始化,BUG又出現了。
總而言之這種方法不是我們想要的,看第二種方法。
第二種解決方法: watch + vm.nextTick
這兩種方法是 vue 的屬性和方法。
watch: 監聽某一個data數據發生變化就執行方法。
例:
vm = new Vue({ el:'.app', data: { a: '1', }, watch: { a: function() { console.log('a的數據發生變化'+this.a); } } }) vm.a = '2';
data 里面的a屬性發生了變化變成成了2,就觸發了watch的a方法。console.log(a的數據發生變化2);
nextTich: 在下次 DOM 更新循環結束之后執行延遲回調。在修改數據之后立即使用這個方法,獲取更新后的 DOM。
例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div @click="ceshi()">{{ a }}</div> </body> <script type="text/javascript"> vm = new Vue({ el:'.app', data: { a: '1', }, methods:{ ceshi(){ a = 2; /*DOM還沒更新*/ this.$nextTick(function(){ /*DOM更新了*/ }) } } }) </script> </html>
$nextTick 里面DOM更新是指頁面上的數據是最新的數據。而不是data的a數據更新了。
知道這兩種屬性之后。我們開始解決一下BUG吧。
先貼完整代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <setion> <option value="1" v-for="(item,key) in arr" :key="key">{{ item }}</option> </setion> </body> <script type="text/javascript"> vm = new Vue({ el:'.app', data: { arr: [], }, wathc:{ arr: function() { this.$nextTick(function(){ /*現在數據已經渲染完畢*/ }) } }, mounted:function() { var that = this; axios.get('url',{ params:{ link: '', } }).then(function(res){ that.arr = res; }) } }) </script> </html>
好,這就是我們解決的完整代碼。 解釋一下什么意思。
在 axios 請求數據是 this.arr被賦值了,watch監聽到了 arr 數據發生變化執行arr方法。到了this.$nextTick 它需要等DOM 渲染完畢才執行(也就是等arr在DOM渲染完畢)。
這個方法完美解決需求,既不浪費時間又不會出現數據還沒渲染完畢就執行實例初始化。這只是一個插件的實例化,通過這個例子可以應用很多的需求。