<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] ## 前言 本文主要總結了vue實際開發項目當中應該如何解決一些實際的開發問題,可能你認為很簡單,但短時間內也許你并沒解決思路的。 ## 常見技術解答 ### for循環中針對ui樣式的特征性樣式或者事件 - 針對ui有特定的數據字段進行判斷(也叫數據模型方法) 這種書數據的要求比較高,且要求你能夠找到比較好的對應關系,需要針對class進行特征性的組件渲染。當你需要改變時改變數據即可重新渲染達到改變樣式的目的。 ~~~ <li v-for="item of list" :key="item.id" :class="item.status?'color':''" @click="changeColor(item.id)">{{item.name}}</li> return { list:[ {id:1,status:true,name:1111}, {id:2,status:true,name:222}] } methods:{ changeColor(id){ this.list.map((item)=>{ if(item.id==id){ item.status=!item.status; } return item; }) } } ~~~ - 傳入對應的參數以及事件源,可以進行相應的判斷改變class 特點更加靈活,也可以根據需要傳入你需要傳入的item屬性參數進行與class的匹配判斷,不用改變接口返回的數據結構。 ~~~ <li v-for="item of list" :key="item.id" @click="changeColor($event)">{{item.name}}</li> return { list:[ {id:1,name:1111}, {id:2,name:222}] } changeColor(e){ let el=e.target; if(el.classList.contains("color")){ el.classList.remove("color") }else{ el.classList.add("color") } } ~~~ ### 計算屬性方法的使用 問題描述:如果你的計算屬性依賴于data的部分,而你的data對應的字段在data里沒有申明,只是在請求接口時進行申明賦值,那么當接口請求時,雖然數據發生了變化,但是計算屬性的值不會發生更新。 解決方案 :需要你在data里申明你計算屬性依賴的字段,哪怕是空或者null ### 事件執行順序問題 問題描述 :定義了輸入框blur,再按鈕點擊事件問題,其中默認click的話,執行順序是先執行blur再執行click.如果你需要場景在點擊的時候不執行blur的事件 解決方案: 1 常規方案 : 需要吧點擊事件變成@mousedown.prevent ,前者會讓點擊優于blur執行,后者會阻止blur執行 2 el-input并不生效,可以用計時器延遲執行 將失去焦點的事件計時器延遲執行,然后點擊事件里清除定時器,也是可以只執行點擊事件邏輯的 ### 路由參數變化組件不更新 問題描述 :路由參數變化,但是組件沒有對應的更新,主要是因為一般獲取參數寫在了created路由鉤子函數中,路由參數變化的時候,這個生命周期不會重新執行。 解決方案1:watch監聽router ~~~ watch: { // 方法1 '$route' (to, from) { //監聽路由是否變化 if(this.$route.params.articleId){// 判斷條件1 判斷傳遞值的變化 //獲取文章數據 } } //方法2 判斷頁面路徑 '$route'(to, from) { if (to.path == "/page") { /// 判斷條件2 監聽路由名 監聽你從什么路由跳轉過來的 this.message = this.$route.query.msg } } //方法 3 設置路徑變化時的處理函數 '$route': { handler: 'resetData', immediate: true } } ~~~ 解決方案2 :為了實現這樣的效果可以給router-view添加一個不同的key,這樣即使是公用組件,只要url變化了,就一定會重新創建這個組件。 ``` <router-view :key="$route.fullpath"></router-view> ``` 解決方案3 :如果組件被放在<keep-alive>中的話,可以把獲取新數據的方法放在activated鉤子,代替原來在created、mounted鉤子中獲取數據的任務 ### 異步函數中使用this無法指向vue實例對象 問題描述 : 在定時器或者其他異步函數中使用傳統的func導致this指向不到vue實例,主要原因是因為this指向的問題,詳細的可以參考我的《神奇的this》這篇文章。 解決方案 :用箭頭函數或者指定變量賦值為this(其他一些不能用箭頭函數的地方自己也要注意) ### 定時器在組件銷毀后還在執行 問題描述 :一些耗費性能的計時器或者動畫在組件銷毀之后還是執行的,導致性能變低。 解決方案 :在銷毀組件的生命周期中銷毀定時器或者一些動畫的js ~~~ //組件銷毀前執行的鉤子函數,跟其他生命周期鉤子函數的用法相同。 beforeDestroy(){ //我通常是把setInterval()定時器賦值給this實例,然后就可以像下面這么停止。 clearInterval(this.intervalId); }, ~~~ 這里也給出第二種方案,通過$once這個事件偵聽器器在定義完定時器之后的位置來清除定時器。以下是完整代碼: ~~~ const timer = setInterval(() =>{ // 某些定時器操作 }, 500); // 通過$once來監聽定時器,在beforeDestroy鉤子可以被清除。 this.$once('hook:beforeDestroy', () => { clearInterval(timer); }) ~~~ 類似于其他需要在當前頁面使用,離開需要銷毀的組件(例如一些第三方庫的picker組件等等),都可以使用此方式來解決離開后以后在背后運行的問題。 如果不清楚$once、$on、$off的使用,這里送上官網的地址教程,在[程序化的事件偵聽器](https://cn.vuejs.org/v2/guide/components-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)那里。 ### 組件名與引入時大小寫不一致導致報錯 問題描述: ~~~ This can lead to unexpected behavior when compiling on a filesystem with other case-semantic. Use equal casing. Compare these module identifiers: ~~~ 解決方案 :需要嚴格對應組件的大小寫,避免低級錯誤 ### 動態添加的dom沒有樣式 問題描述:作為常識我們知道style中的樣式都會追加scoped,這樣針對模板dom中的樣式就可以生效,但其生效后的最終樣式并不是我們寫的樣式名,而是編碼后的,所以我們在js中拼接上的dom結構樣式并不會生效。 解決思路: 1 當添加的部分樣式不會太多,而且是動態加載的,可以將其設置為非scopred的 2 將添加dom部分用的樣式放到非scoped樣式標簽中 3 將添加的部分,如果有必要,可以另外寫一個頁面拆分的vue組件 拓展 : 項目中引入的其他ui框架的樣式,如果你想覆蓋修改,也是需要不加scoped的,如果你想整個項目覆蓋,就可以在src/styles下定義customer-element.scss 這樣的來重寫覆蓋樣式。 ### vue中直接修改對象數據,頁面視圖不更新 問題描述 :你的數據對象類型,沒有在data中進行定義,就沒有增加對其的監聽綁定,當你直接去使用或者定義數據時,會導致這個數據的vm視圖層不會及時更新. 解決方案:這時候需要你將其定義到data中就會增加對其的監聽。 備注:與此同理,你需要增加監聽的數據或者變化的數據如果需要數據變化時馬上更新,都要定義到data一份。 ### vue中直接修改數組數據,頁面視圖不更新 問題描述 :在常規理解中,視圖與數據是雙向綁定的,但是有時候修改data的數組或者對象值,視圖不會更新 。 ~~~ data() { // data數據 return { arr: [1,2,3], obj:{ a: 1, b: 2 } }; }, // 數據更新 數組視圖不更新 this.arr[0] = 'OBKoro1'; this.arr.length = 1; console.log(arr);// ['OBKoro1']; // 數據更新 對象視圖不更新 this.obj.c = 'OBKoro1'; delete this.obj.a; console.log(obj); // {b:2,c:'OBKoro1'} ~~~ 解決方案 :由于js的限制,Vue 不能檢測以上數組的變動,以及對象的添加/刪除,很多人會因為像上面這樣操作,出現視圖沒有更新的問題。 1 this.$set(你要改變的數組/對象,你要改變的位置/key,你要改成什么value) ~~~ this.$set(this.arr, 0, "OBKoro1"); // 改變數組 this.$set(this.obj, "c", "OBKoro1"); // 改變對象 ~~~ 2 數組原生方法觸發視圖更新: splice()、 push()、pop()、shift()、unshift()、sort()、reverse() 推薦使用splice方法會比較好自定義,因為slice可以在數組的任何位置進行刪除/添加操作 3 替換數組 比方說:你想遍歷這個數組/對象,對每個元素進行處理,然后觸發視圖更新。 ~~~ // 文檔中的栗子: filter遍歷數組,返回一個新數組,用新數組替換舊數組 example1.items = example1.items.filter(function (item) { return item.message.match(/Foo/) }) ~~~ - [codepen地址,可以進行問題重現](https://codepen.io/robinson90/pen/ZRWyYX) ### 需要無腦重復某內容 ~~~ <div v-for="n in 5"> <span>這里會被渲染5次,渲染模板{{n}}</span> </div> ~~~ ### babel-plugin-transform-runtime使用 * 出現問題:這個插件可以兼容并轉化大部分的es6語法,但是部分語法也是不能轉化或者存在具體問題的。 1. 異步加載組件時,會產生 polyfill 代碼冗余 2. 不支持對全局函數與實例方法的 polyfill。不支持全局函數(如:Promise、Set、Map),Set 跟 Map 這兩種數據結構應該大家用的也不多,影響較小。但是 Promise 影響可能就比較大了。不支持實例方法(如:'abc'.include('b')、['1', '2', '3'].find((n) => n 等等),這個限制幾乎廢掉了大部分字符串和一半左右數組的新特性。 而兩個問題的原因均歸因于 babel-plugin-transform-runtime 采用了沙箱機制來編譯我們的代碼(即:不修改宿主環境的內置對象)。由于異步組件最終會被編譯為一個單獨的文件,所以即使多個組件中使用了同一個新特性(例如:Object.keys()),那么在每個編譯后的文件中都會有一份該新特性的 polyfill 拷貝。如果項目較小可以考慮不使用異步加載,但是首屏的壓力會比較大。 * 解決方案:一般情況下 babel-plugin-transform-runtime 能滿足大部分的需求,當不滿足需求時,推薦使用完整的 babel-polyfill。 * 首先,從項目中移除 babel-plugin-transform-runtime,卸載該依賴: `npm un babel-plugin-transform-runtime -D`, * 接著修改 babel 配置文件 ~~~ // .babelrc { //... "plugins": [ // - "transform-runtime" ] //... } ~~~ * 然后,安裝 babel-polyfill 依賴: `npm i babel-polyfill -D` * 最后,在入口文件中導入 ~~~ // src/main.js import 'babel-polyfill' ~~~ ### ES6 import 引用問題 在 ES6 中,模塊系統的導入與導出采用的是引用導出與導入(非簡單數據類型),也就是說,如果在一個模塊中定義了一個對象并導出,在其他模塊中導入使用時,導入的其實是一個變量引用(指針),如果修改了對象中的屬性,會影響到其他模塊的使用。 通常情況下,系統體量不大時,我們可以使用 JSON.parse(JSON.stringify(str)) 簡單粗暴地來生成一個全新的深度拷貝的 數據對象。不過當組件較多、數據對象復用程度較高時,很明顯會產生性能問題,這時我們可以考慮使用 Immutable.js。 鑒于這個原因,進行復雜數據類型的導出時,需要注意多個組件導入同一個數據對象時修改數據后可能產生的問題。 此外,模塊定義變量或函數時即便使用 let 而不是 const,在導入使用時都會變成只讀,不能重新賦值,效果等同于用 const 聲明。 ### 動態懶加載組件 背景:在webpack的新特性中支持組件的懶加載,也就是說我們可以在加載到該路由的時候再把這部分腳本進行加載,同時這個在項目進行打包的時候,對應的文件也會被單獨打包,對于首屏優化以及其他頁面的資源加載優化都是非常好的。這也要求我們在每個頁面組件使用組件的時候盡量按需引入,提升體驗。 問題場景:那么我們需要解決的問題是: 0 webpack是靜態解析路徑的,直接傳入變量并不可行 1 每次都寫一串加載組件的代碼很不方便,是否可以支持寫成一個加載組件的方法 2 是否支持區分生產和開發環境,因為開發環境使用懶加載會導致熱更新,導致更新變慢,所以開發環境使用全量默認加載,生產環境使用懶加載 解決方案如下 : 1 webpack的路徑使用變量拼接,必須預先給出一個相對路徑,然后把具體的組件路徑在傳入 2 用一個箭頭函數,將需要傳入的組件名或者相對路徑傳入 3 用process.env.NODE_ENV確定使用哪種加載方式 代碼如下: 在原來的router/index.js中,定義一個加載組件的_import方法。 ~~~ // router/index.js const _import = require('./_import_' + process.env.NODE_ENV) //使用時 { path: '/', name: 'HelloWorld', component: _import('HelloWorld') }, // router/_import_development.js module.exports = file => require('@/views/' + file + '.vue').default // vue-loader at least v13.0.0+ // router/_import_production.js 如果你加載的vue不是這個路徑 請自定義哦 module.exports = file => () => import('@/views/' + file + '.vue') ~~~ **注意事項:** 1 如果配置完之后,可能會有部分樣式文件或者圖片引入的src路徑之外的,比如說static,報錯找不到對應的文件,這時候需要改為根路徑static的路徑就可以解決這個報錯?你需要裝的模塊:sass-loader,node-sass,stylus,stylus-loader,style-loader,css-loader,url-loader即可。具體的包需要進一步確定。 2 在具體的頁面中,如果你想懶加載組件,也是如此的寫法 ``` import vOther from '@/components/other' //修改后 const vOther = () => import('@/components/other') ``` ### vue中的data必須為函數 **場景** :vue入門的人可能在頁面單獨引入vue的時候,直接使用data為對象類型的,并沒有問題,但是在spa應用中,如果組件中的data為對象類型就會報錯。 **解決方案** :data換為函數,返回對象類型的鍵值對。 拓展 :你可能知道要這樣做,這里稍微科普下原因,主要是因為根組件只會用一次,所以可以用對象,而子組件可能在一個應用中被多次使用,為了避免多個組件使用同一數據互相影響,所以講data約定為了返回函數類型,返回需要的對象,以此保證子組件在數據渲染的時候不會互相影響。 ### 有父子標簽關系的自定義組件渲染失敗 **場景** :在自定義組件的時候,很多時候需要將ul下的li標簽,table下的tr\td標簽進行封裝為自定義組件,但直接使用自定義組件會導致其最終生成的位置不是我們想要的。截圖如下: ~~~ Vue.component("row",{ template:'<tr><td>{{content}}</td></tr>', data(){ return { content:'this is a row' } }, }) ~~~ ![](https://box.kancloud.cn/5c44cd9258f16d1add4c41625b7cc6fd_494x314.png) ![](https://box.kancloud.cn/983d443988a8e4817a1cea1610c58d7e_600x322.png) **解決方案** :原因是因為html會進行標簽解析,tbody下的標簽必須為tr,其他的同理。那么我們可以將其子標簽設置為原來的標簽類型,然后用is="selfComponent" 來解決這個問題。 `<tr is="row"></tr>` - [vueComponents使用](https://codepen.io/robinson90/pen/GGjmyx) 拓展: - 不要將渲染vue的容器元素定位到html或者body上,否則提示:` Do not mount Vue to <html> or <body> - mount to normal elements instead.` - 確保有在vue新建實例的時候將el屬性綁定到一個html模板的標簽上 ### ref使用 **場景** :雖然vue不建議直接操作dom,但是在復雜的場景中,我們需要進行dom的操作,這時候就可以借助ref實現。比如下面我們舉一個簡單的例子,通過ref獲取dom節點,拿到其內容。 **解決方案** : ~~~ <div @click="handleClick" ref="hello">hello world </div> handleClick(){ console.log(this.$refs.hello) } ~~~ - 拓展案例 :實現計數器加和 場景 :假設我們有兩個計數器組件的實例,現在需要用ref的方案得到兩個計數器的加和。 代碼如下: ~~~ <counter ref="one" @change="handleChange"></counter> <counter ref="two" @change="handleChange"></counter> <span>{{total}}</span> Vue.component("counter",{ template:"<div @click='change'>{{number}}</div>", data(){ return { number:0} }, methods:{ change(){ this.number++; this.$emit("change") } } }) //app父組件方法 handleChange(){ this.total=this.$refs.one.number+this.$refs.two.number }, ~~~ - 拓展認知 : this.$refs.name中如果是原生標簽,拿到的是原生標簽的節點,如果是組件,拿到的是組件的引用。 如果你用.name獲取不到,可以嘗試用【name】方式。 - [vueRefDemo使用](https://codepen.io/robinson90/pen/OERmra) ## 參考文檔 - [vue項目實踐中的一些問題](http://mp.weixin.qq.com/s/fgFOvWBC_P78hG154gyXYQ)
                  <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>

                              哎呀哎呀视频在线观看