vue項目踩坑


  由於上一個小項目寫的很次,這一次打算好好地寫一個博客系統,最近剛剛結束了管理員的管理端的編寫。其中遇到了很多小坑。

  其實只能說自己vue用的不是特別熟練吧。很多問題都有些想當然了,實現起來發現了很多的問題。簡單的記錄幾個我自己認為值得記錄的吧。

一、一個很坑的問題,vue在對其中一個目標進行改變的時候,實際上會對模板內部的方法和變量等都進行重新渲染,這樣就會導致一個問題。如下

<template>
  <div class="hello">
    <ul>
      <li v-for="item in datas">
        <div :style="{fontSize:changsize()}">{{item}}</div>
      </li>
    </ul>
    <input type="text" v-model="tests">
    {{tests}}
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      datas:['one','two','three','one','two','three','one','two','three'],
      fz:'',
      tests:'',
    }
  },
  watch:{
    datas(val){
      console.log(111);
      return;
    }
  },
  methods:{
    changsize(){
      return (parseInt(Math.random()*15)+10)+'px';
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

  代碼如上,如果我在input內部輸入內容,這樣就會改變了data內部的tests,進而整個模板都進行一次重新渲染。這樣就導致我輸入一個數據這個字體的大小就全部改變一次。這樣就違背了我的初衷,僅僅是想在模板加載的時候賦值一次就可以了!!!以后輸入內容的時候不需要改變了。開始還以為能有類似鈎子函數的東西來禁止一下。最后發現有點問題。

在網上解決問題的時候找到這樣一句話:

每個vue實例都有一個根元素id的屬性el,Vue對象通過它來找到要渲染的部分。之后使用createDocumentFragment()方法創建一個documentFragment,遍歷根元素的所有子元素,依次劫持並插入文檔片段,將根元素掏空。然后執行Vue的編譯:遍歷documentFragment中的節點,對其中的v-for,v-text等屬性進行相應的處理。最后,把編譯完成后的documentFragment還給根元素。

這樣也就是說其實它實際上是對整體都進行了處理,如果要改變的話可能需要重寫一些方法......

那就換一個思路好了,在自己寫的代碼層面上想辦法。

1.當時想的第一個辦法是每一次在生成datas(在我得項目里這個數據是從數據庫取出來的),就直接生成一個隨機的字體大小存儲在數據庫中。這樣加載的時候就可以直接設置了。但是也有壞處。改變了自己的初始設計想法。。。。

2.今天仔細想了一下,想出了一個辦法。使用一個變量用來存儲模板刷新的時候所生成的字體大小,這樣在使用的時候用這個自己定義的數組變量和相應的item的index來進行分辨到底設置哪個字體的大小。代碼如下

<template>
  <div class="hello">
    <ul>
      <li v-for="(item,index) in datas">
        {{changsize(index)}}
        <div :style="{fontSize:font_size[index]}">{{item}}</div>
      </li>
    </ul>
    <input type="text" v-model="tests">
    {{tests}}
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      datas:['one','two','three','one','two','three','one','two','three'],
      fz:'',
      tests:'',
      font_size:[],
    }
  },
  watch:{
    datas(val){
      console.log(111);
      return;
    }
  },
  methods:{
    changsize(index){
      if(this.font_size.length!=this.datas.length){this.font_size[index]=(parseInt(Math.random()*15)+10)+'px';  
      }else{
        return;
      }
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

 3.對於上面的方法純屬是屬於通過自己的邏輯來進行判斷。在methods運行的時候還需要使用if來判斷一下。那么根據上一個方法有個優化的方法,我們可以聲明一個數組變量,然后不斷地push進新的數據進行存儲,在賦值的時候依舊使用  數組[index]  這樣的形式來賦值,這樣就可以了。

<template>
  <div class="hello">
    <ul>
      <li v-for="(item,index) in datas">
        {{changsize()}}
        <div :style="{fontSize:font_size[index]}">{{item}}</div>
      </li>
    </ul>
    <input type="text" v-model="tests">
    {{tests}}
  </div>
</template>
<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      datas:['one','two','three','one','two','three','one','two','three'],
      fz:'',
      tests:'',
      // font_size:[],
    }
  },
  computed:{
    font_size(){
      return [];
    }
  },
  methods:{
    changsize(){
      this.font_size.push((parseInt(Math.random()*15)+10)+'px');
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

這樣就比較完美的解決了這個問題。當然,我們也可以將存儲數據的變量放到data內部,例如我在data內部注釋的那行代碼一樣,但是這樣會有一個缺點,瀏覽器會報錯

[Vue warn]: You may have an infinite update loop in a component render function.

這個問題的原因就是如果我們在v-for內部使用方法來改變data內的數據的時候,很有可能會導致無線循環,按照我這種寫法當然不會觸發,但是畢竟還是有可能的,所以我們還是把變量聲明到computed好了。畢竟有個紅色的報錯提醒看着也是很煩的。

-------------------------------------------------2018-05-03 23:56:14--------------------------------------------------------


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM