<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] ### 前言 本篇主要介紹模塊中的常見的報錯,希望列舉不正確的以及不完善的大家幫忙提出。 ### npm run dev報錯找不到localhost: 報錯 如下 :原因是因為localhost解析不到對應的ip ~~~ Error: getaddrinfo ENOTFOUND localhost at errnoException (dns.js:50:10) at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:92:26) ~~~ 解決方式 :找到根目錄 /etc/hosts,它是計算機進行域名解析服務的一個本地映射,寫入如下的解析,就可以完美的解決這個問題。 `127.0.0.1 localhost` 提示:如果你需要定制很多host,可以下載一個switchHosts的軟件,可以切換不同測試環境下添加不同的域名解析機制。如果你是shell面板,可以cd 切換到/etc,然后mac利用 vi或者win利用vm修改這個文本文件(需要管理員權限進行修改)。 ### 關于異步獲取數據時渲染報錯 **問題場景**:一般情況下,頁面需要用的數據項是data中會定義一份,然后大部分數據肯定是接口異步獲取的,在組件模板編碼中,一般都習慣于直接基于已有數據正確的情況下去實現,在初始數據為空渲染空對象屬性的屬性下就會報錯(直接空屬性不會報錯哦)。 ~~~ Vue.component("row",{ template:"<li>{{item.account.name}}</li>", props:{ item:{ type:Object, default:[], required:true } }, }) // 父組件中初始狀態 <row :item="item"></row> data:{ item :{} }, created(){ // 模擬異步接口 setTimeout(()=>{ this.dataReady = true; this.item = { account:{ name:8576 }} },2000) } // vue warn 報錯 VM1873 console_runner-ce3034e6bde3912cc25f83cccb7caa2b0f976196f2f2d52303a462c826d54a73.js:1 [Vue warn]: Error in render: "TypeError: Cannot read property 'name' of undefined" found in ---> <Row> ~~~ **解決方案** :這樣的報錯主要是因為數據在渲染時沒有保證其是在數據準備好的情況下,所以需要在組件渲染的做一些必要的準備工作。比如我們可以加下數據加載好的標志位。dataReady:false ~~~ <li is="row" :item="item" v-if="dataReady"></li> // 父組件中 data:{ item:{}, dataReady:true, } created(){ // 模擬異步接口 setTimeout(()=>{ this.dataReady = true; this.item = { account:{ name:8576 }} },2000) } ~~~ - 拓展認知1:如果你的數據是Array類型,也許不會有這樣問題,因為Array類型默認用的[],所以沒有內容不會渲染,內容有的時候才會進行渲染并進行循環,不過為了安全,element等框架還是進行了安全校驗,v-if="data&&data.length>0",數據是對象的,加v-if="item" 以此來保證數據是有的情況。 - 拓展認識2 :即使是數據在正常得到的情況下,如果你的屬性值也可能是空的,那么需要你在可能有屬性報錯或者沒有的情況下,追加屬性存在的判斷,比如:`if(item.account&&item.account.name){//codes here}` - [codepen案例地址:dataRenderError](https://codepen.io/robinson90/pen/dKONLQ) ### watch使用特性:更好的支持異步,可以支持深度監測 **問題場景**:這點主要是講watch以及computed的區別,在watch使用場景中,我們可以針對某屬性的變化,進行一些額外的異步或者同步邏輯或者事件,而計算屬性本身只關注其最后的結果。而且計算屬性時建立在watch基礎上的,在進行計算的時候實際等同于對每個可影響的屬性增加了watch監聽。 那么具體的問題就是指當我們改變對象的非第一層屬性或者值時,雖然值改變了,但是并未觸發其watch方法監聽。如此,我們就需要修改為第三種寫法。 三種基本寫法 : ~~~ watch: { //第一種寫法 適用于普通變量(簡單類型的值的觀測寫法) a: function (val, oldVal) { console.log('new: %s, old: %s', val, oldVal) }, // 第二種寫法:方法名 b: 'someMethod', // 第三種寫法:深度 watcher(能觀測對象c下多重屬性變化)(復雜類型的值的觀測寫法) c: { //當c變化后會回調handler函數 handler: function (val, oldVal) { /* ... */ }, deep: true } } ~~~ **解決方案** :使用deep,并且改變數值的方式要使用this.$set(this.obj,key,value) ~~~ data:{ pserson:'' }, watch:{ person:{ handler(){ console.log(111) }, deep:true, immediate:true } }, created(){ this.tip='變更數據' setTimeout(()=>{ this.name = this.name2='zhang san' this.tip='變化數據完成' // this.$set(this.person,'tip',45); this.person= Object.assign({},this.person,{tip:45}); this.person.account.name=['li定位si']; },2000) } ~~~ - [vueWatchDemo--codepen地址](https://codepen.io/robinson90/pen/JZEepN) - 拓展:Vue 實例將會在實例化時調用 $watch(),遍歷 watch 對象的每一個屬性。不能用箭頭函數,因為箭頭函數會綁定父級的作用域,導致功能失敗。 - 如果希望是第一次data的時候就監聽,需要增加immediate:true (如果你是在created生命周期里就加了執行事件,是根據某監聽屬性來的,那么可以改到這個位置) - 如果是新增屬性,原來對象中沒有的,需要用到前面的知識,用this.$set(),或者Object.assiagn()實現。如果是原來就有這個屬性,直接用賦值方式就可以。 - 不要混淆watch監聽與對數據的改變,直接賦值是任何時候都可以改變值的,只不過沒觸發監聽事件 - watch默認就會返回其最新的val,不需要人為多一行代碼去處理,但是如果你想返回其他值就需要加中間邏輯,并顯性的返回需要的值。 ### 移動端使用rem 一般情況下可能會自己做適配,也可以使用阿里的模塊。amfe-flexible - [amfe-flexible模塊地址](https://npm.taobao.org/package/amfe-flexible) ~~~ //main.js 引入依賴 import 'amfe-flexible' //_base.scss 設計圖寬度除以10,假如設計圖寬度是750px那么,基礎寬度就是75 $baseWidthSize: 75 !default; @function to($px) { @return $px / $baseWidthSize * 1rem; } //組件和頁面使用; to()里面的數值是photoshop里測量的值 <style lang="scss"> @import "../scss/_base.scss"; .box{ width: to(750); height: to(100); } </style> ~~~ ### 移動端使用vw布局 - [手淘vw適配方案](https://www.w3cplus.com/mobile/vw-layout-in-vue.html) ### 使用語言包 i18n 場景 :希望在項目中支持國際化 。 解決方案 :詳細的見文章,描述較為詳細。其中語言包可以根據路由的需要決定是否懶加載。 - [vue-i18n 使用](https://juejin.im/post/5aa7e18ff265da2384404334) ### watch 6位數字 **場景** :我們一般都需要對數字做驗證,在沒有其他外界環境的情況下,一般我們是通過正則進行驗證的,但是現在產品對需求交互進行了細化,要求如下:在沒有數字鍵盤,選擇控件的情況下,還是比較麻煩的。 1 不能輸入非數字,也就是只能輸入數字 2 不能輸入超過6位 **解決方案** :主要通過正則以及Number的相關方法實現。 ~~~ number(newval){ let reg = /^[0-9]+$/ ; let val = parseInt(newval) ; if(reg.test(newval)){ this.number = newval.toString().substring(0,6); }else if(isNaN(val)){ this.number = '' }else{ this.number = val } } ~~~ - [numberWatch](https://codepen.io/robinson90/pen/RJLNYx) ### 兼容問題 在進行項目開發的時候,在ie9或者其他瀏覽器可能會遇到兼容問題,那么需要看下以下的幾種可能,es6不支持 ,promise不支持 ,babel的相關設置不對 。 es6 不支持: ~~~ npm install babel-polyfill --save-dev entry: { 'babel-polyfill': 'babel-polyfill', app: './src/main.js' }, .babelrc 文件的設置 "presets": [ "es2015", "stage-2" ], "plugins": ["transform-runtime"], ~~~ promise不支持 : ~~~ import promise from 'es6-promise'; promise.polyfill(); ~~~ ### 使用eventBus跨頁面傳參錯誤 場景:假設我們沒有使用vuex,而需要在a頁面跳轉到b頁面的時候進行大量的參數傳遞,可以使用eventBus事件進行,于是在a頁面mounted 周期里提交事件,在b頁面mounted周期接收事件。于是發現兩個bug : - 第一次出發并沒有執行接收 - 后續的觸發都會積累之前的 對于第一點是因為生命周期的問題,在進行頁面跳轉的時候,會先進行a頁面的beforeDestroy周期,然后進行b頁面的creadted,,在beforeMount之后才喚醒a頁面的beforeDestroy,destroyed的周期,然后把提交事件放到beforeDestroy周期就可以了。 對于第二點是因為全局的eventBus定義之后,沒有在destroyed周期里銷毀對應的事件,所以針對這種情況需要.$off銷毀對應的事件。那么在銷毀的時候需要拿到其當前頁面的路徑,this.$route.path作為參數傳遞,this.bus.$off(this.$route.path). ### 頁面刷新每次都要執行一個方法或者代碼 場景:如上描述 ,如果這段代碼寫在常規的mounted的周期里不會每次刷新頁面都執行,也有試過去執行某些方法無效。 解決方案 : ~~~ this.$nextTick(function(){ //codes here }) ~~~ 備注:關于this.$nextTick后續會深入研究源碼以及其解決的實際問題。 ### 按需加載組件庫 一般按需加載都是為了節省帶寬,避免網絡資源浪費,提高頁面性能。下面以vant為例: - 安裝: cnpm i vant -S - 安裝babel-plugin-import插件使其按需加載: cnpm i babel-plugin-import -D - 在 .babelrc文件中中添加插件配置 : ~~~ libraryDirectory { "plugins": [ // 這里是原來的代碼部分 // ………… // 這里是要我們配置的代碼 ["import", { "libraryName": "vant", "libraryDirectory": "es", "style": true } ] ] } ~~~ - 在main.js中按需加載你需要的插件: ~~~ // 按需引入vant組件 import { DatetimePicker, Button, List } from 'vant'; ~~~ - 使用組件: ~~~ // 使用vant組件 Vue.use(DatetimePicker) .use(Button) .use(List); ~~~ - 頁面中使用 `<van-button type="primary">按鈕</van-button>` **備注** :出來vant庫外,像antiUi、elementUi等,很多ui庫都支持按需加載,可以去看文檔,上面都會有提到。基本都是通過安裝babel-plugin-import插件來支持按需加載的,使用方式與vant的如出一轍,可以去用一下。 ### 優雅的只在當前頁面中修改ui庫樣式 很多情況下我們引入了組件,需要修改樣式為我們需求的,但是因為如果加scoped的關鍵字,就會找不到對應的庫樣式,一般我們是采用非scoped的樣式去覆蓋,但這樣會造成樣式污染,而且其他人是不知情的。 所以建議可能會有一種是: 在樣式公共目錄下統一的修改組件樣式,然后大家共用,同時與產品、設計約定好這樣的規則 。 **還有一種就是本文推薦的,深度選擇器,我們可以在當前頁面修改庫樣式:** `.van-tabs /deep/ .van-ellipsis { color: blue};` 官方文檔:[deep選擇器](https://vue-loader.vuejs.org/guide/scoped-css.html#deep-selectors) ### 輪播的技術選型 如果你只是想使用輪播的組件,這里推薦Vue-Awesome-Swiper。 - [vue-awesome-swiper](https://npm.taobao.org/package/vue-awesome-swiper) - [swiper文檔說明](http://www.swiper.com.cn/api/index.html) ### 定位分析大文件 在進行項目優化的時候,我們需要針對性的分析出哪些文件大,以及如何優化 。 如果你是vue-cli初始化的項目,會默認安裝webpack-bundle-analyzer插件,該插件可以幫助我們查看項目的體積結構對比和項目中用到的所有依賴。也可以直觀看到各個模塊體積在整個項目中的占比。 ![](https://user-gold-cdn.xitu.io/2018/6/12/163f310014cc9b59?imageslim) npm run build --report // 直接運行,然后在瀏覽器打開http://127.0.0.1:8888/即可查看(先把run dev關掉) ### 開啟gzip壓縮代碼 spa這種單頁應用,首屏由于一次性加載所有資源,所有首屏加載速度很慢。解決這個問題非常有效的手段之一就是前后端開啟gizp(其他還有緩存、路由懶加載等等)。gizp其實就是幫我們減少文件體積,能壓縮到30%左右,即100k的文件gizp后大約只有30k。 vue-cli初始化的項目中,是默認有此配置的,只需要開啟即可。但是需要先安裝插件: `cnpm i compression-webpack-plugin` 然后在config/index.js中開啟即可: ~~~ build: { // 其他代碼 ………… productionGzip: true, // false不開啟gizp,true開啟 // 其他代碼 } ~~~ 現在打包的時候,除了會生成之前的文件,還是生成.gz結束的gzip過后的文件。具體實現就是如果客戶端支持gzip,那么后臺后返回gzip后的文件,如果不支持就返回正常沒有gzip的文件。 **注意**:這里前端進行的打包時的gzip,但是還需要后臺服務器的配置。配置是比較簡單的,配置幾行代碼就可以了,可以讓運維操作下。(待完善具體的配置) ### 瀏覽器前進后退刷新數據的問題 keep-alive 不能完全解決你的問題的話,參考這里的文章實踐:[瀏覽器刷新時的數據與位置](https://juejin.im/post/5b2ce07ce51d45588a7dbf76)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看