vue中遇到的坑


 如何解決在vue中替換圖片、一個使用base64,而我們使用zepto之后,src找不到資源,因為已經打包了,難道強行寫base64。

1. 引入文件時語法很重要!

import "FooterMenu" from '@components/Menu';
import FooterMenu from '@components/Menu';

即在頁面組件中引入一個FooterMenu組件, 我們引入時應該引入的一個變量作為標簽,而不能再FooterMenu上添加引號!!  在這里浪費了很多時間。

 

2. 在一個單頁面組件中不需要style,但必須要script。

即在.vue文件中,我們可以沒有style,但是必須要有script來利用 exports default 來導出模塊,否則就會出錯。

 

補充: 

    <transition name="fade">
      <div class="pay-model" v-show="ifpay">
        <div class="pay-style">
          <div  v-if="payArr[payArr.length - 3] == 1">
            <input type="radio"  name="settleChoose" checked = "checked"  data-value='4' id="wechat" value="微信支付" v-model="style">  
            <label for="wechat" >微信支付</label>
          </div>
          <div v-if="payArr[payArr.length - 2] == 1">
            <input type="radio" name="settleChoose"  id="alipay" data-value='2' value="支付寶支付" v-model='style'>  
            <label for="alipay"  >支付寶支付</label>
          </div>
          <div  v-if="payArr[payArr.length - 1] == 1">
            <input type="radio" name="settleChoose" id="tohome" data-value='1' value="貨到付款" v-model='style'>  
            <label for="tohome">貨到付款</label>
          </div>
        </div>
      </div>
    </transition>

在這里,如果style的值為初始值 "", 即為空,那么我們及時使用這里的checked = "checked"也無法自動選中,解決方法:如果我們希望在打開模態框之后的微信支付是默認的,那么我們就可以將 style 的初始值設置為 “微信支付”, 這樣就沒有什么問題了。

 

 

補充:

      <div v-if="payArr[payArr.length - 2] == 1">
                <label class="pay-lable" >
                <input type="radio" v-bind:checked = 'curPayMethod == 2' name="choosePay" value="2">  
                支付寶支付</label>
              </div>
              <div  v-if="payArr[payArr.length - 3] == 1">
                <label class="pay-lable" >
                <input type="radio" v-bind:checked = 'curPayMethod == 4' name="choosePay" value="4">  
                微信支付</label>
              </div>
              <div  v-if="payArr[payArr.length - 1] == 1">
                <label class="pay-lable">
                <input type="radio" v-bind:checked = 'curPayMethod == 1' name="choosePay" value="1">  
                修改為貨到付款</label>
              </div>

 

label的for對應於input的id,如果說不能正常使用,其實我們也可以直接將input寫進label里去,這樣會更加方便,不再需要使用 for 和 id 了。

 

 

 

 

 

3. 當我們在路由中配置了不同的router-link對應於不同的組件的時候,會發現npm run dev之后什么都沒有,比如我的路由如下:

export default new Router({
  routes: [
    {
      path: '/Mall',
      component: Mall
    },
    {
      path: '/personal-center',
      component: personalCenter
    }, 
    {
      path: '/order',
      component: AlipayHint
    },
    {
      path: '/commodity',
      component: Commodity
    }
  ]
});

運行之后,是空白頁,這是因為路由中並沒有配置一進來是“/”的路由,所以什么都沒有顯示,這時就需要重定向了。如下所示:

routes: [
    {
      path: '/Mall',
      component: Mall
    },
    {
      path: '/personal-center',
      component: personalCenter
    }, 
    {
      path: '/order',
      component: AlipayHint
    },
    {
      path: '/commodity',
      component: Commodity
    },
    {
      path: "/",
      redirect: "/commodity"
    }
  ]

即我們需要重定向的時path中的值,而不是component中的值。

 

 

4. 在v-for下的列表中,如何向方法傳遞參數?  

(1) 我們可以在一個list中綁定 v-for="item,index in items", 這樣,我們就可以獲取到相應的item和index(從0開始),另外,如果我們希望向list中的某個v-on:click = "handler" 傳遞參數,可以直接傳遞,比如: v-on:click="handler(index)", 這樣就可以向methods下的handler傳遞參數了。

(2) 我們還可以傳遞$event直接給hanlder,然后通過e.currentTarget獲取到這個元素。 

 

 

5. 如何使用vuex、使用store中的數據、替換store中的數據?

  vuex大家都不陌生,比如我在一個store的state中存儲了items為一個空數組,然后在組件中循環數組中的每一個元素並展示出來,然后再通過axios獲取到數據之后更新store,這樣數組中就有元素了。

  最開始我使用的思路如下所示:

const state = {
  totalPrice:  0,
  items: [],
 //.... 其他的state }

 

  然后通過axois獲取items,獲取到之后更新:

  .then(function (response) {
    if (response.data.code == 130) {
      items = response.data.data;
      console.log(items);
      store.commit('update', items);
    }

  其中的update已經在mutation中定義了,因為我們知道vue中的state只能通過commit這一種方式來替換而不能通過其他方式,如下:

mutations: {
update (state, items) {
state.items = items;
}
}

 

   最后,我們需要把items掛載到組件下:

  data: function () {
      return {
        name: "CommodityKinds",
     items: this.$store.state.items } },

 

  說明:因為我已經將store注冊到根組件下了,所以我們可以在組件中使用 this.$store.state來訪問到state對象。 

  但是,這樣是有問題的 --- 我們會發現,進入有items數據的頁面后, 數據並沒有被渲染出來,而是等到我們切換頁面,再切換回來的時候才能渲染出來。

  而問題就出現在了最后一步!  

  我們應該將store中的數據放在computed下而不是放在data下!!!!

  具體解決方法如下:

  import {mapState} from 'vuex'

  然后:

    computed: mapState({
      items: state => state.items
    })

  這樣,當store中的數據改變時, 就會直接改變了,更多例子可以看vuex官方文檔,講的很好。 

總結: 一般而言,我們需要將store下的state放在computed中,將組件自身的state,不需要像vuex這樣動態的、傳遞的放在 data 下即可。

 

 

 

6. 在vue中,我們可以使用v-on:click.once對click處理函數只綁定一次,這樣就類似於jquery中的one綁定了。  

 

 

7. 在jquery中,如果我們希望第一個元素最開始添加一個active類名,我們可以使用class綁定,其中是一個對象,對象中的屬性是類的名稱,值是布爾值,如果為true,則顯示,否則不顯示。 

<template>
  <div class="commodity-kind">
    <div class="kind" v-bind:class="{active: index == 0}" v-on:click="getContent(item.id, $event)" v-for="item,index in items">
      <span>{{item.name}}</span>
    </div>
  </div>
</template>

 

  這樣,一進去就是這樣的狀態了。

 

 

 

8. 當需要axios請求時,如果我們在不同的組件中都需要請求,並且都有相同的請求頭,特別是最近的項目我需要使用vue-cli的express代理Tomcat服務器進行測試開發時,就要添加/api才能正常訪問,但是在每一個請求前添加這個是非常麻煩的,並且在 npm run build 時,又要把這些/api去掉,這是相當麻煩的,所以我們可以單獨建立一個js文件,我命名為 request.js 文件,內容如下:

import axios from 'axios'
axios.defaults.baseURL = "/api";
axios.defaults.headers.common['BBG-Key'] = "ab9ef20253-49d4-b229-3cc2383480a6";


export default axios

 

其中,/api是在開發過程需要代理服務器所必須的, 所以這里設置為baseURL,那么在實際請求中,就會自動添加/api, 並且在實際生產中,我們只要注釋掉它就可以了。 

而BBG-Key是為了安全使用的,所以為了避免每次在請求時都添加一個請求頭,我們在這里直接設置為 common(公共) 的請求頭。這樣,在實際的每一個請求中就不需要都添加這個請求頭了。 

最后導出這個 axios,在其他的模塊中引用。

import axios from '../assets/js/request'
  axios.get('/bbg/shop/get_classify', {
    params: {
      sid:  13729792
    } 
  })
  .then(function (response) {
    if (response.data.code == 130) {
      items = response.data.data;
 //............

 

這樣,就會較之前省去很多的工作量。 good!

 

9. vue中在css下寫的,即一般使用的時作為背景圖的,在assets下的圖片經過打包之后使用的時base64的編碼方式,所以,如果在js中操作css,使用路徑的方式是行不通的,我的方式是使用base64, 但是有更好的方法嗎?如下所示:

 handleDefault (id,e) {
        $(".default").html("設為默認").css({
          'color': 'black',
          'background': 'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAC+SURBVFhH7Y5BCgIxDEXHs7h15wV0XWjajeD9D6IVP8wfJlAITovwH2QTEt5bxFGY2W3kQNun1vqaOcjw8R5mDHL2eMczBjlbSinP7tGBsLu1nLFeacsHH2E9DHa3livWKwrswG4FRmC3AiOwW4ER2K3ACOxWYAR2KzACuxUYgd0KjMBuBUZgtwIjsFuBEdj9n4FmVvgI62GwO6V0wXoLH80c5OzxjmcMcny8h5GDjC6nnPN95HycX7X4JcvyBq2MUQCYxq1GAAAAAElFTkSuQmCC) no-repeat',
          'background-size': '0.4rem'
        });

         $(e.currentTarget).html("默認地址").css({
          'color': '#51B1B0',
          'background': 'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAnCAYAAAB9qAq4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAG3SURBVFhH7Zc9S8NgFIXrFwiuiuDu4uoPcFFwEJsUhP6COjk7+hscO7h0a5Hc+6bOdnMRHMTByV1wEB0caxJPX0xzY9MkvSLmgQekOSfvoWlFaxUaHPV6C/vd7lqZHvj+Km6fj71OZ8U1PNTQYXrCsdlwjTmRbjRrz4bDeUxI55B5SypriRnpSCVN60wPmJKkacy6VNIWc5I45J1LBW0xJ4nLxFJB2+12ewmT4lQDM1oNTJXpBkeFv878xHX4KwMdY+5wTESDeVfKhaoPdAzf4wiLlBupOtAxdIvbj5iTct9VG+gQXePWFik3bqGBiE48qG7oClGLlJPMPbDJvIFohJQJDR6rQcQi5dLMPTD4sL8iaklkyPNwyTKemWSxzyDzC+IWe42I8ZIl1s1o8S8JeW+oWFyf+/jRInYzWHxgYPC431ETkTpZLWVgaN3wM6oxpOw0ljYwcuw/MjEzpeUO/PLD9elYeD2XsxhYqn93oMNMUkHbncFgEZPiNAy1pIK2mJOkFby1UkFbzJGRCrrSBabIBM9/WS7qiBk/0+hfbkrlWYvjsxP8Xfco3ah0iU5xZMV/o1b7BPkQ+pZZ2s/xAAAAAElFTkSuQmCC) no-repeat',
          'background-size': '0.4rem'
         });

 

 

 

10. class綁定的是一個對象,一般情況下,這個對象直接定義在html中是比較好處理的,如下:

   <!-- 這里使用class綁定來決定默認 -->
            <span class="no-default" v-bind:class="{default: item.id == defaultAddress.id}" v-on:click="handleDefault(item.id, $event)" >
              {{ (item.id == defaultAddress.id) ? "默認地址" : "設為默認" }}
            </span>

注意: class中的class名稱不能用引號括起來。 

 

 

 

 

11. 在menu中,每當點擊一個選項時,替換其背景圖片,如何做到實時的變化。 

最開始,我的實現思路是: 先通過import的方式引入,然后在 v-for 中引用data下的每一個項目的src, 然后當點擊選項的時候, 用switch函數來根據點擊的index來進行替換圖片,但是這樣的替換存在一個問題: 每當點擊之后,第一次並沒變化,而是再點擊一次,才會發生改變。

原因: 在vue中,data下的值和DOM中不是實時更新的,所以一般實時更新就要使用store。 即在store中import 圖片資源,然后在改變的時候通過mutations進行改變。 這樣的變化就是實時的了。 

問題: 雖然使用 mutations 可以實時改變,但問題是,我們完全是沒有必要的,因為這個改變只需要在一個組件中,使用store未免太小題大做了。

注意:這里使用的是vue的data,並且需要改變的時引入的文件(需要打包的),對於下面這樣只需要修改顏色的不需要使用這樣的方式, 只需要使用 zepto 來改變css即可,這樣一定是實時的。

 

 

 

12. 使用actions時,需要commit Mutations,但是actions 不支持多參數傳遞,也就是說第一個參數是Mutation,第二個參數是我們需要傳遞的值,如果傳入多個,那么第三個及以后將自動忽略,為了解決這個問題,我們可以將多個值封裝到一個對象,然后傳遞這個對象就可以了,這就類似於Payload啊啊啊。

       if (response.data.code == 626) {
              for (let i = 0; i < response.data.data.length; i++) {
                console.log(response.data.data[i], index);
                var obj = {
                  index: index,
                  item: response.data.data[i]
                };
                commit(UPDATE_ALL_CONTENT, obj);

              }
              index++;
              resolve();
            }

 

OK! 這就是payload。 哈哈哈哈 理解就好。

 

 

13. 在vue中,我們傳入的事件一定是$event,但是獲取時, e.currentTarget 和 e.target 獲取的不一樣的,區別在於 前者是當前的元素,即冒泡的最后一個綁定事件的元素,而后者是 最原始的元素。 

關鍵: 后者可以實現事件代理。

 

 

 

 

14. 有時候啊, 一個很小的錯誤都會導致全局的失敗! 比如,不知道為什么就報下面這種錯誤! 

 

 

然后內容就顯示不出來,但是通過network可以獲知數據都請求到了,所以遇到這種問題我的解決方法還是尋找於此有關的代碼,然后逐個注釋代碼,如果注釋之后不再出錯,就說明問題出在了這里,通過尋找,問題在這:

<template>
  <div class="item"}>

 

即之前添加屬性時, } 沒有去掉。  

 

雖然有問題了,但是解決問題的方法和思路正確就好。

 

 

 

 

15. 為什么document.body.scrollTop = 0 不生效,而 document.querySelector("body").scrollTop = 0; 是可以的呢?

 

 

 

 

 16. 下面的這個錯誤而很明顯!  就是在創建鈎子函數created中出現了未定義的變量:

Error in created hook!

 

 

17. localStorage無法輸出

為什么只有localStorage可以輸出,而其他的不能呢? 就是訪問不到屬性!


免責聲明!

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



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