日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
困擾99%前端程序員的Vue問題,全在這了

 1.前言

最近要求使用vue進(jìn)行前后端分離開發(fā)微信公眾號,不斷摸索踩坑之后,總結(jié)出如下幾點(diǎn)vue項(xiàng)目開發(fā)中常見的問題及解決辦法。如果你是vue大佬,請忽略小弟的愚見

  • 列表進(jìn)入詳情頁的傳參問題。
  • 本地開發(fā)環(huán)境請求服務(wù)器接口跨域的問題
  • axios封裝和api接口的統(tǒng)一管理
  • UI庫的按需加載
  • 如何優(yōu)雅的只在當(dāng)前頁面中覆蓋ui庫中組件的樣式
  • 定時(shí)器問題
  • rem文件的導(dǎo)入問題
  • Vue-Awesome-Swiper基本能解決你所有的輪播需求
  • 打包后生成很大的.map文件的問題
  • fastClick的300ms延遲解決方案
  • 組件中寫選項(xiàng)的順序

2.列表進(jìn)入詳情頁傳參問題

例如商品列表頁面前往商品詳情頁面,需要傳一個(gè)商品id;

 
 
 
 
  1. 前往detail頁面 

c頁面的路徑為 http://localhost:8080/#/detail?id=1 ,可以看到傳了一個(gè)參數(shù) id=1 ,并且就算刷新頁面id也還會存在。此時(shí)在c頁面可以通過id來獲取對應(yīng)的詳情數(shù)據(jù),獲取id的方式是 this.$route.query.id vue傳參方式有:query、params+動態(tài)路由傳參。

vue傳參方式有:query、params+動態(tài)路由傳參。說下兩者的區(qū)別:

  • query通過 path 切換路由,params通過 name 切換路由
 
 
 
 
  1. // query通過path切換路由 
  2. 前往Detail頁面 
  3. // params通過name切換路由 
  4. 前往Detail頁面 
  • query通過 this.$route.query 來接收參數(shù),params通過 this.$route.params 來接收參數(shù)。
 
 
 
 
  1. // query通過this.$route.query接收參數(shù) 
  2. created () { 
  3.     const id = this.$route.query.id; 
  4.  
  5. // params通過this.$route.params來接收參數(shù) 
  6. created () { 
  7.     const id = this.$route.params.id; 
  • query傳參的url展現(xiàn)方式: /detail?id=1&user=123&identity=1&更多參數(shù) params+動態(tài)路由的url方式: /detail/123
  • params動態(tài)路由傳參,一定要在路由中定義參數(shù),然后在路由跳轉(zhuǎn)的時(shí)候必須要加上參數(shù),否則就是空白頁面
 
 
 
 
  1.     path: '/detail/:id', 
  2.     name: 'Detail', 
  3.     component: Detail 
  4. }, 

注意,params傳參時(shí),如果沒有在路由中定義參數(shù),也是可以傳過去的,同時(shí)也能接收到,但是一旦刷新頁面,這個(gè)參數(shù)就不存在了。這對于需要依賴參數(shù)進(jìn)行某些操作的行為是行不通的,因?yàn)槟憧偛豢赡芤笥脩舨荒芩⑿马撁姘?。例如?/p>

 
 
 
 
  1. // 定義的路由中,只定義一個(gè)id參數(shù) 
  2.     path: 'detail/:id', 
  3.     name: 'Detail', 
  4.     components: Detail 
  5.  
  6. // template中的路由傳參, 
  7. // 傳了一個(gè)id參數(shù)和一個(gè)token參數(shù) 
  8. // id是在路由中已經(jīng)定義的參數(shù),而token沒有定義 
  9. 前往Detail頁面 
  10.  
  11. // 在詳情頁接收 
  12. created () { 
  13.     // 以下都可以正常獲取到 
  14.     // 但是頁面刷新后,id依然可以獲取,而token此時(shí)就不存在了 
  15.     const id = this.$route.params.id; 
  16.     const token = this.$route.params.token; 

3.本地開發(fā)環(huán)境請求服務(wù)器接口跨域的問題

上面的這個(gè)報(bào)錯(cuò)大家都不會陌生,報(bào)錯(cuò)是說沒有訪問權(quán)限(跨域問題)。本地開發(fā)項(xiàng)目請求服務(wù)器接口的時(shí)候,因?yàn)榭蛻舳说耐床呗?,?dǎo)致了跨域的問題。下面先演示一個(gè)沒有配置允許本地跨域的的情況:

可以看到,此時(shí)我們點(diǎn)擊獲取數(shù)據(jù),瀏覽器提示我們跨域了。所以我們訪問不到數(shù)據(jù)。那么接下來我們演示設(shè)置允許跨域后的數(shù)據(jù)獲取情況:

我們在1出設(shè)置了允許本地跨域,在2處,要注意我們訪問接口時(shí),寫的是 /api ,此處的 /api 指代的就是我們要請求的接口域名。如果我們不想每次接口都帶上 /api ,可以更改axios的默認(rèn)配置 axios.defaults.baseURL = '/api'; 這樣,我們請求接口就可以直接 this.$axios.get('app.php?m=App&c=Index&a=index') ,很簡單有木有。此時(shí)如果你在 network 中查看 xhr 請求,你會發(fā)現(xiàn)顯示的是 localhost:8080/api 的請求地址。這樣沒什么大驚小怪的,代理而已:

好了,最后附上proxyTable的代碼:

 
 
 
 
  1. proxyTable: { 
  2.       // 用‘/api’開頭,代理所有請求到目標(biāo)服務(wù)器 
  3.       '/api': { 
  4.         target: 'http://jsonplaceholder.typicode.com', // 接口域名 
  5.         changeOrigin: true, // 是否啟用跨域 
  6.         pathRewrite: { // 
  7.           '^/api': '' 
  8.         } 
  9.       } 

注意:配置好后一定要關(guān)閉原來的server,重新 npm run dev 啟動項(xiàng)目。不然無效。

axios的封裝,主要是用來幫我們進(jìn)行請求的攔截和響應(yīng)的攔截。在請求的攔截中我們可以攜帶userToken,post請求頭、qs對post提交數(shù)據(jù)的序列化等。在響應(yīng)的攔截中,我們可以進(jìn)行根據(jù)狀態(tài)碼來進(jìn)行錯(cuò)誤的統(tǒng)一處理等等。axios接口的統(tǒng)一管理,是做項(xiàng)目時(shí)必須的流程。這樣可以方便我們管理我們的接口,在接口更新時(shí)我們不必再返回到我們的業(yè)務(wù)代碼中去修改接口。

4.UI庫的按需加載

為什么要使用按需加載的方式而不是一次性全部引入,原因就不多說了。這里以vant的按需加載為例,演示vue中ui庫怎樣進(jìn)行按需加載:

  • 安裝: cnpm i vant -S
  • 安裝 babel-plugin-import 插件使其按需加載: cnpm i babel-plugin-import -D
  • 在 .babelrc文件中中添加插件配置 :
 
 
 
 
  1. libraryDirectory { 
  2.      
  3.     "plugins": [ 
  4.         // 這里是原來的代碼部分 
  5.         // ………… 
  6.  
  7.         // 這里是要我們配置的代碼 
  8.         ["import", 
  9.             { 
  10.                 "libraryName": "vant", 
  11.                 "libraryDirectory": "es", 
  12.                 "style": true 
  13.             } 
  14.         ] 
  15.     ] 
  • 在main.js中按需加載你需要的插件:
 
 
 
 
  1. // 按需引入vant組件 
  2. import { 
  3.     DatetimePicker, 
  4.     Button, 
  5.     List 
  6. } from 'vant'; 
  • 使用組件:
 
 
 
 
  1. // 使用vant組件 
  2. Vue.use(DatetimePicker) 
  3.     .use(Button) 
  4.     .use(List); 
  • 最后在在頁面中使用:
 
 
 
 
  1. 按鈕 

ps:出來 vant 庫外,像 antiUi 、 elementUi 等,很多ui庫都支持按需加載,可以去看文檔,上面都會有提到?;径际峭ㄟ^安裝babel-plugin-import插件來支持按需加載的,使用方式與vant的如出一轍,可以去用一下。

5.如何優(yōu)雅的只在當(dāng)前頁面中覆蓋ui庫中組件的樣式

首先我們vue文件的樣式都是寫在  標(biāo)簽中的,加scoped是為了使得樣式只在當(dāng)前頁面有效。那么問題來了,看圖:

我們正常寫的所有樣式,都會被加上[data-v-23d425f8]這個(gè)屬性(如1所示),但是第三方組件內(nèi)部的標(biāo)簽并沒有編譯為附帶[data-v-23d425f8]這個(gè)屬性。所以,我們想修改組件的樣式,就沒轍了。怎么辦呢,有些小伙伴給第三方組件寫個(gè)class,然后在一個(gè)公共的css文件中或者在當(dāng)前頁面再寫一個(gè)沒有socped屬性的style標(biāo)簽,然后直接在里面修改第三方組件的樣式。這樣不失為一個(gè)方法,但是存在全局污染和命名沖突的問題。約定特定的命名方式,可以避免命名沖突。但是還是不夠優(yōu)雅。作為一名優(yōu)( 強(qiáng) )秀(  )的(  )前(  )端(  ),怎么能允許這種情況出現(xiàn)呢?好了,下面說下優(yōu)雅的解決方式:通過深度選擇器解決。例如修改上圖中組件里的van-ellipsis類的樣式,可以這樣做:

 
 
 
 
  1. .van-tabs /deep/ .van-ellipsis { color: blue}; 

編譯后的結(jié)果就是:

這樣就不會給 van-ellipsis 也添加 [data-v-23d425f8] 屬性了。至此你可以愉快的修改第三方組件的樣式了。當(dāng)然了這里的深度選擇器 /deep/ 是因?yàn)槲矣玫?nbsp;less 語言,如果你沒有使用 less/sass 等,可以用 >>> 符號。更多的關(guān)于深度選擇器的內(nèi)容,在文章后面有介紹。

6.定時(shí)器問題

我在a頁面寫一個(gè)定時(shí),讓他每秒鐘打印一個(gè)1,然后跳轉(zhuǎn)到b頁面,此時(shí)可以看到,定時(shí)器依然在執(zhí)行。這樣是非常消耗性能的。如下圖所示:

解決方法1

首先我在data函數(shù)里面進(jìn)行定義定時(shí)器名稱:

 
 
 
 
  1. data() { 
  2.     return { 
  3.         timer: null  // 定時(shí)器名稱 
  4.     } 
  5. }, 

然后這樣使用定時(shí)器:

 
 
 
 
  1. this.timer = (() => { 
  2.     // 某些操作 
  3. }, 1000) 

最后在beforeDestroy()生命周期內(nèi)清除定時(shí)器:

 
 
 
 
  1. beforeDestroy() { 
  2.     clearInterval(this.timer); 
  3.     this.timer = null; 

方案1有兩點(diǎn)不好的地方,引用尤大的話來說就是:

 
 
 
 
  1. timer 

解決方案2

該方法是通過$once這個(gè)事件偵聽器器在定義完定時(shí)器之后的位置來清除定時(shí)器。以下是完整代碼:

 
 
 
 
  1. const timer = setInterval(() =>{ 
  2.     // 某些定時(shí)器操作 
  3. }, 500); 
  4. // 通過$once來監(jiān)聽定時(shí)器,在beforeDestroy鉤子可以被清除。 
  5. this.$once('hook:beforeDestroy', () => { 
  6.     clearInterval(timer); 
  7. }) 

方案2要感謝@zzx18023在評論區(qū)提供出的解決方案。類似于其他需要在當(dāng)前頁面使用,離開需要銷毀的組件(例如一些第三方庫的picker組件等等),都可以使用此方式來解決離開后以后在背后運(yùn)行的問題。綜合來說,我們更推薦使用 方案2,使得代碼可讀性更強(qiáng),一目了然 。如果不清楚once、on、$off的使用,這里送上官網(wǎng)的地址教程,在程序化的事件偵聽器那里: https:// cn.vuejs.org/v2/guide/c omponents-edge-cases.html#%E7%A8%8B%E5%BA%8F%E5%8C%96%E7%9A%84%E4%BA%8B%E4%BB%B6%E4%BE%A6%E5%90%AC%E5%99%A8 。

7.rem文件的導(dǎo)入問題

我們在做手機(jī)端時(shí),適配是必須要處理的一個(gè)問題。例如,我們處理適配的方案就是通過寫一個(gè)rem.js,原理很簡單,就是根據(jù)網(wǎng)頁尺寸計(jì)算html的font-size大小,基本上小伙伴們都知道,這里直接附上代碼,不多做介紹。

 
 
 
 
  1. (function(c, d) { 
  2.   var e = document.documentElement || document.body, 
  3.     a = "orientationchange" in window ? "orientationchange" : "resize", 
  4.     b = function() { 
  5.       var f = e.clientWidth; 
  6.       e.style.fontSize = f >= 750 ? "100px" : 100 * (f / 750) + "px"; 
  7.     }; 
  8.   b(); 
  9.   c.addEventListener(a, b, false); 
  10. })(window); 

這里說下怎么引入的問題,很簡單。在main.js中,直接 import './config/rem' 導(dǎo)入即可。import的路徑根據(jù)你的文件路徑去填寫。

8.Vue-Awesome-Swiper基本能解決你所有的輪播需求

在我們使用的很多ui庫(vant、antiUi、elementUi等)中,都有輪播組件,對于普通的輪播效果足夠了。但是,某些時(shí)候,我們的輪播效果可能比較炫,這時(shí)候ui庫中的輪播可能就有些力不從心了。當(dāng)然,如果技術(shù)和時(shí)間上都還可以的話,可以自己造個(gè)比較炫的輪子.這里我說一下 vue-awesome-swiper 這個(gè)輪播組件,真的非常強(qiáng)大,基本可以滿足我們的輪播需求。swiper相信很多人都用過,很好用,也很方便我們二次開發(fā),定制我們需要的輪播效果。vue-awesome-swiper組件實(shí)質(zhì)上基于swiper的,或者說就是能在vue中跑的 swiper 。下面說下怎么使用:

 
 
 
 
  1. cnpm install vue-awesome-swiper --save 

 
 
 
 
  1. // 引入組件 
  2. import 'swiper/dist/css/swiper.css' 
  3. import { swiper, swiperSlide } from 'vue-awesome-swiper' 
  4.  
  5. // 在components中注冊組件 
  6. components: { 
  7.     swiper, 
  8.     swiperSlide 
  9.  
  10. // template中使用輪播 
  11. // ref是當(dāng)前輪播 
  12. // callback是回調(diào) 
  13. // 更多參數(shù)用法,請參考文檔 
  14.  
  15.      
  16.     1
 
  •     2
  •  
  •     3
  •  
  •            
  •      
  •     
  •  
  •     
  •  
  •     
  •  
  •     
  •  
  •  
  • // 參數(shù)要寫在data中 
  • data() { 
  •     return { 
  •         // swiper輪播的參數(shù) 
  •         swiperOption: { 
  •             // 滾動條 
  •             scrollbar: { 
  •                 el: '.swiper-scrollbar', 
  •             }, 
  •             // 上一張,下一張 
  •             navigation: { 
  •                 nextEl: '.swiper-button-next', 
  •                 prevEl: '.swiper-button-prev', 
  •             }, 
  •             // 其他參數(shù)………… 
  •         } 
  •     } 
  • }, 
  • swiper需要配置哪些功能需求,自己根據(jù)文檔進(jìn)行增加或者刪減。附上文檔:npm文檔,swiper3.0/4.0文檔,更多用法,請參考文檔說明。

    9.打包后生成很大的.map文件的問題

    項(xiàng)目打包后,代碼都是經(jīng)過壓縮加密的,如果運(yùn)行時(shí)報(bào)錯(cuò),輸出的錯(cuò)誤信息無法準(zhǔn)確得知是哪里的代碼報(bào)錯(cuò)。 而生成的.map后綴的文件,就可以像未加密的代碼一樣,準(zhǔn)確的輸出是哪一行哪一列有錯(cuò)可以通過設(shè)置來不生成該類文件。但是我們在生成環(huán)境是不需要.map文件的,所以可以在打包時(shí)不生成這些文件:在 config/index.js 文件中,設(shè)置 productionSourceMap: false, 就可以不生成 .map 文件

    10.fastClick的300ms延遲解決方案

    開發(fā)移動端項(xiàng)目,點(diǎn)擊事件會有300ms延遲的問題。至于為什么會有這個(gè)問題,請自行百度即可。這里只說下常見的解決思路,不管vue項(xiàng)目還是jq項(xiàng)目,都可以使用 fastClick 解決。安裝 fastClick :

     
     
     
     
    1. cnpm install fastclick -S 

    在main.js中引入fastClick和初始化:

     
     
     
     
    1. import FastClick from 'fastclick'; // 引入插件 
    2. FastClick.attach(document.body); // 使用 fastclick 

    11.組件中寫選項(xiàng)的順序

    為什么選項(xiàng)要有統(tǒng)一的書寫順序呢?很簡單,就是要將選擇和認(rèn)知成本最小化。

      • 副作用 (觸發(fā)組件外的影響)
        • el
      • 全局感知 (要求組件以外的知識)
        • name
        • parent
      • 組件類型 (更改組件的類型)
        • functional
      • 模板修改器 (改變模板的編譯方式)
     
     
     
     
    1. delimiters 
    2. comments 
    • 模板依賴 (模板內(nèi)使用的資源)
     
     
     
     
    1. components 
    2. directives 
    3. filters 
      • 組合 (向選項(xiàng)里合并屬性)
     
     
     
     
    1. extends 
    2. mixins 
      • 接口 (組件的接口)
        • inheritAttrs
        • model
        • props / propsData
      • 本地狀態(tài) (本地的響應(yīng)式屬性)
     
     
     
     
    1. data 
    2. computed 
      • 事件 (通過響應(yīng)式事件觸發(fā)的回調(diào))
     
     
     
     
    1. beforeCreate 
    2. created 
    3. beforeMount 
    4. mounted 
    5. beforeUpdate 
    6. updated 
    7. activated 
    8. deactivated 
    9. beforeDestroy 
    10. destroyed 
    11. watch 
    • 非響應(yīng)式的屬性 (不依賴響應(yīng)系統(tǒng)的實(shí)例屬性)
      • methods
    • 渲染 (組件輸出的聲明式描述)
      • template / render
      • renderError

    文章名稱:困擾99%前端程序員的Vue問題,全在這了
    標(biāo)題路徑:http://www.dlmjj.cn/article/dppcodh.html