公司年初開始從jquery轉型到vue開發,思想上從jquery的操做DOM到vue的操做數據,剛開始還不太習慣,但用了一段時間發現確實比較方便。在剛開始用vue的時候,也踩了一些坑,如今分享出來,供剛入門上手開發vue的朋友參考,都是一些剛接觸vue開發遇到的比較常見的問題,vue老手可越過。css
vue中的props是單向綁定的,父組件的屬性變化時會傳遞給子組件,子組件內部不該改變props的值,不然控制檯會給出警告。
但若是props的類型爲數組或者對象時,在子組件內部改變props的值控制檯不會警告。由於數組或對象是地址引用,vue不會檢測到props發生改變。因此有的狀況須要在子組件內部改變父組件的值,能夠將屬性定義爲數組或者對象類型傳入。
但官方不建議在子組件內改變父組件的值,由於這違反了vue中props單向綁定的思想。vue
由1能夠引伸出,地址引用類型的數據,例如對象obj ={a:1},若是想要修改obj中的a屬性,經過obj.a = 2這樣賦值,頁面不會更新,需使用vue.set方法更改纔會起做用, Vue.set(this,obj,a,2)
;
一樣,若是要給obj增長一個新屬性,若是該屬性未在data中聲明,頁面也不會刷新。也就是vue文檔中聲明的「Vue 不能檢測到對象屬性的添加或刪除」,一樣須要使用vue.set方法進行賦值纔好使。node
對象或數組的簡單賦值,修改新值也會改變原值。這時咱們須要獲取原值的深拷貝對象。
對於對象,能夠經過newObj = JSON.parse(JSON.stringfy(obj))
實現。
對於數組,能夠經過 newArr = […arr]
或者newArr = arr.slice(0)
來實現。jquery
vue中每個組件均可以自定各自的css樣式,若是但願組件內的樣式只對當前組件起做用,能夠在style標籤中增長scoped便可。
該寫法會讓vue在渲染組件的時候給每一個元素都增長一個data-v-/版本號/的屬性,能夠保證只針對有一樣data-v-data-v-/版本號/的元素應用該樣式。webpack
vue中的v-for循環最好加上key屬性,不然在高版本(2.2.0+)的vue中控制檯會報錯。
key屬性須要惟一,理想的 key 值是每項都有惟一 id,全局不需惟一,但在一個循環中須要惟一。ios
圖片引用問題。直接把本地圖片地址放在src裏沒問題。但若是把地址提取出來寫在data裏或者經過method動態給src賦值則引用不到。
由於放在template模板裏會被webpack打包因此能夠,而放在data或者動態賦值,圖片路徑只是一個字符串webpack不會處理因此引用不到。
解決辦法:經過import或者required引入。import src from ‘../../img.png’
或者data:{img:require(‘../../img.png’)}
nginx
在子組件使用父組件傳入的值時,最好複製出一份props
的值,經過data
或者computed
進行賦值。data
賦值與computed
賦值的區別:data
賦值:data:{return {aaa: this.aaa}
若是是在data
中進行賦值,當父組件的aaa
值發生改變時,不會在從新賦給子組件中的aaa
。computed
賦值:若是想讓子組件跟着父組件修改,須要將賦值操做寫在computed
中。computed:{aaa(){return this.aaa}
web
後端傳過來的數組是一個數組對象,頁面中綁定對象中某一具體的屬性,當該值變化時調用某個函數,天然想到就是watch
方法。但如何watch
數組對象中某一個具體的屬性,顯然不可能一個個屬性寫watch
。
解決辦法:
1.watch
整個對象,設置deep
爲true
,當該對象發生改變時,調用處理函數。
2.將頁面中綁定的屬性寫在computed
函數中,watch
這個computed
中的函數,當對象值改變時會進入computed
函數中,進而進入watch
函數中,再調用處理函數。vue-cli
給元素動態增長class
時,能夠在模板中經過:class={‘hasClass’: ifHasClass}
來實現,當ifHasClass
爲true
時,該元素會自動加上hasClass
的樣式。
動態綁定的class
能夠與正常寫的一塊兒使用<a class=‘aaa’ :class={‘bbb’:isBbb}></a>
,但若是在一個元素中使用了兩個class
則會報錯<a class="aaa" class="bbb"></a>
。json
若是咱們在頁面A中使用了一個定時器,當從頁面A跳轉到頁面B時,若是不手動清除這個定時器,那麼它仍舊會執行,這不是咱們所指望的。
一般能想到的常規解決辦法就是,在data
屬性中定義一個timer
,在代碼中啓動定時器,而後在組件銷燬的時候清除定時器。具體代碼以下:
data(){ return{ timer:null } }, methods:{ onStartTimer(){ this.timer = setInterval( () => { // 執行一些操做 }, 1000) } }, beforeDestroy() { clearInterval(this.timer); this.timer = null; }
可是這裏有兩個潛在的問題:
timer
,若是能夠的話最好只有生命週期鉤子能夠訪問到它。這並不算嚴重的問題,可是它能夠被視爲雜物。Vue
官方文檔給出的解決方案是,在定義timer的時候使用$once
指令監聽beforeDestroy
這個鉤子函數。具體代碼爲:
methods:{ onStartTimer(){ const timer = setInterval( () => { // 執行一些操做 }, 1000) this.$once('hook:beforeDestroy', () => { clearInterval(timer); }) } },
這樣就解決了上面所列的兩個問題。相似的這種在離開頁面時須要銷燬的組件均可以採用此方法。
在本地開發請求後端服務器接口的時候,都不可避免的會遇到跨域的問題。解決方法能夠經過加一個node
中間層或者nginx
作反向代理。可是若是是用vue-cli
搭建的項目,vue-cli
在config
中自帶了一個proxyTable
屬性,能夠配置這個屬性解決跨域的問題。
// config/index.js module.exports = { // ... dev: { proxyTable: { '/api': { // 遇到/api的接口都會走此代理,所以在調用接口時,須要在url中增長/api標識 target: 'http://jsonplaceholder.typicode.com', // 真實的地址 changeOrigin: true, // 是否啓用跨域 pathRewrite: { '^/api': '' // 將接口中的/api替換成'' } } } } }
以上代碼會將 /api/posts/1
請求代理到 http://jsonplaceholder.typicode.com/posts/1
。
若是不想在每個接口中都手動增長/api
標識,能夠更改axios
的默認配置axios.defaults.baseURL = '/api'
,這樣,axios
會自動幫咱們在url
上加上/api
的前綴。
須要特別注意的是,更改完配置後須要重啓server纔會生效。