偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

困擾99%前端程序員的Vue問(wèn)題,全在這了

新聞 前端
最近要求使用vue進(jìn)行前后端分離開(kāi)發(fā)微信公眾號(hào),不斷摸索踩坑之后,總結(jié)出如下幾點(diǎn)vue項(xiàng)目開(kāi)發(fā)中常見(jiàn)的問(wèn)題及解決辦法。

[[348925]]

 1.前言

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

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

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

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

  1. <router-link :to="{path: 'detail', query: {id: 1}}">前往detail頁(yè)面</router-link> 

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

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

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

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

  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沒(méi)有定義 
  9. <router-link :to="{name: 'Detail', params: { id: 1, token: '123456' }}">前往Detail頁(yè)面</router-link> 
  10.  
  11. // 在詳情頁(yè)接收 
  12. created () { 
  13.     // 以下都可以正常獲取到 
  14.     // 但是頁(yè)面刷新后,id依然可以獲取,而token此時(shí)就不存在了 
  15.     const id = this.$route.params.id; 
  16.     const token = this.$route.params.token; 

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

 

 

 

 

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

 

 

 

 

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

 

 

 

 

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

 

 

 

 

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

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

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

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

4.UI庫(kù)的按需加載

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

  • 安裝: cnpm i vant -S
  • 安裝 babel-plugin-import 插件使其按需加載: cnpm i babel-plugin-import -D
  • 在 .babelrc文件中中添加插件配置 :
  1. libraryDirectory { 
  2.      
  3.     "plugins": [ 
  4.         // 這里是原來(lái)的代碼部分 
  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); 
  • 最后在在頁(yè)面中使用:
  1. <van-button type="primary">按鈕</van-button> 

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

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

首先我們vue文件的樣式都是寫(xiě)在 <style lang="less" scoped></style> 標(biāo)簽中的,加scoped是為了使得樣式只在當(dāng)前頁(yè)面有效。那么問(wèn)題來(lái)了,看圖:  

 

 

 

 

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

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

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

 

 

 

 

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

6.定時(shí)器問(wèn)題

我在a頁(yè)面寫(xiě)一個(gè)定時(shí),讓他每秒鐘打印一個(gè)1,然后跳轉(zhuǎn)到b頁(yè)面,此時(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)不好的地方,引用尤大的話來(lái)說(shuō)就是:

  1. timer 

解決方案2

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

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

方案2要感謝@zzx18023在評(píng)論區(qū)提供出的解決方案。類似于其他需要在當(dāng)前頁(yè)面使用,離開(kāi)需要銷毀的組件(例如一些第三方庫(kù)的picker組件等等),都可以使用此方式來(lái)解決離開(kāi)后以后在背后運(yùn)行的問(wèn)題。綜合來(lái)說(shuō),我們更推薦使用 方案2,使得代碼可讀性更強(qiáng),一目了然 。如果不清楚once、on、$off的使用,這里送上官網(wǎng)的地址教程,在程序化的事件偵聽(tī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)入問(wèn)題

我們?cè)谧鍪謾C(jī)端時(shí),適配是必須要處理的一個(gè)問(wèn)題。例如,我們處理適配的方案就是通過(guò)寫(xiě)一個(gè)rem.js,原理很簡(jiǎn)單,就是根據(jù)網(wǎng)頁(yè)尺寸計(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); 

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

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

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

  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中注冊(cè)組件 
  6. components: { 
  7.     swiper, 
  8.     swiperSlide 
  9.  
  10. // template中使用輪播 
  11. // ref是當(dāng)前輪播 
  12. // callback是回調(diào) 
  13. // 更多參數(shù)用法,請(qǐng)參考文檔 
  14. <swiper :options="swiperOption" ref="mySwiper" @someSwiperEvent="callback"
  15.     <!-- slides --> 
  16.     <swiper-slide><div class="item">1</div></swiper-slide> 
  17.     <swiper-slide><div class="item">2</div></swiper-slide> 
  18.     <swiper-slide><div class="item">3</div></swiper-slide> 
  19.            
  20.     <!-- Optional controls --> 
  21.     <div class="swiper-pagination"  slot="pagination"></div> 
  22.     <div class="swiper-button-prev" slot="button-prev"></div> 
  23.     <div class="swiper-button-next" slot="button-next"></div> 
  24.     <div class="swiper-scrollbar"   slot="scrollbar"></div> 
  25. </swiper> 
  26. // 參數(shù)要寫(xiě)在data中 
  27. data() { 
  28.     return { 
  29.         // swiper輪播的參數(shù) 
  30.         swiperOption: { 
  31.             // 滾動(dòng)條 
  32.             scrollbar: { 
  33.                 el: '.swiper-scrollbar'
  34.             }, 
  35.             // 上一張,下一張 
  36.             navigation: { 
  37.                 nextEl: '.swiper-button-next'
  38.                 prevEl: '.swiper-button-prev'
  39.             }, 
  40.             // 其他參數(shù)………… 
  41.         } 
  42.     } 
  43. }, 

swiper需要配置哪些功能需求,自己根據(jù)文檔進(jìn)行增加或者刪減。附上文檔:npm文檔,swiper3.0/4.0文檔,更多用法,請(qǐng)參考文檔說(shuō)明。

9.打包后生成很大的.map文件的問(wèn)題

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

 

 

 

 

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

開(kāi)發(fā)移動(dòng)端項(xiàng)目,點(diǎn)擊事件會(huì)有300ms延遲的問(wèn)題。至于為什么會(huì)有這個(gè)問(wèn)題,請(qǐng)自行百度即可。這里只說(shuō)下常見(jiàn)的解決思路,不管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ě)選項(xiàng)的順序

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

    • 副作用 (觸發(fā)組件外的影響)
      • el
    • 全局感知 (要求組件以外的知識(shí))
      • 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 
    • 事件 (通過(guò)響應(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

 

 

責(zé)任編輯:張燕妮 來(lái)源: 知乎
相關(guān)推薦

2022-08-01 09:43:19

程序員Googlefacebook

2020-08-05 07:53:53

程序員網(wǎng)站技術(shù)

2018-11-01 15:20:17

前端程序員編程語(yǔ)言

2025-03-31 03:00:05

2019-12-03 10:04:18

程序員招聘開(kāi)發(fā)

2021-10-18 21:41:10

Go程序員 Defer

2023-11-13 08:34:01

Java編程習(xí)慣

2018-08-02 17:00:15

Vue.js學(xué)習(xí)iOS開(kāi)發(fā)

2013-08-20 09:33:59

程序員

2017-11-13 20:27:09

程序員月薪技術(shù)

2022-07-15 08:20:54

Java基礎(chǔ)知識(shí)

2012-06-08 09:57:25

2015-11-04 10:30:06

前端文藝范程序員

2016-09-25 22:13:11

程序員代碼編碼

2012-02-23 15:02:46

程序員

2022-11-10 10:29:07

KPI軟件開(kāi)發(fā)

2011-06-08 10:24:58

程序員

2021-11-01 07:11:03

程序員職場(chǎng)公司

2018-07-17 09:08:55

程序員技能區(qū)塊鏈

2022-08-08 15:45:44

JavaPromise前端
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)