自定義指令
<div v-demo="{ color: 'white', text: 'hello!' }"></div>
Vue.directive('demo', function (el, binding) {
console.log(binding.value.color) // => "white"
console.log(binding.value.text) // => "hello!"
});
項目中自定義滾動指令(main.js)
Vue.directive('scroll',{
bind:function(el,binding){
window.addEventListener('scroll',() => {
let fnc = binding.value; // 該項目中綁定到函數(shù)
fnc(el);
})
}
})
組件中使用
<div class="..." v-scroll="showTop">
...
<div @click="gotop" class="go-top" :class="goTop?'active':''"></div>
...
</div>
methods: {
gotop: function() {
let speed = 10;
let timer = setInterval(function(){
if (document.body.scrollTop > 0){
document.body.scrollTop = document.body.scrollTop - speed > 0 ? document.body.scrollTop - speed : 0;
speed += 20;
} else {
clearInterval(timer);
}
}, 16)
},
showTop: function() {
if(document.body.scrollTop > 200){
this.goTop = true
} else {
this.goTop = false
}
},
}
Modules
使用單一狀態(tài)樹忽妒,導(dǎo)致應(yīng)用的所有狀態(tài)集中到一個很大的對象笛谦。但是,當(dāng)應(yīng)用變得很大時当凡,store 對象會變得臃腫不堪挤茄。為了解決以上問題如叼,Vuex 允許我們將 store 分割到模塊(module)。每個模塊擁有自己的 state穷劈、mutation笼恰、action、getters歇终。
cinema-modules
import * as types from '../types'
const state = {...};
const actions = {...};
const getters = {...};
const mutations = {...};
export default {
state,
actions,
getters,
mutations
}
index.js
import Vue from 'vue'
import Vuex from 'vuex'
import cinema from './modules/cinema'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
cinema
},
})
export default store;
跨域問題
有時候社证,本地使用webpack開啟一個node的dev端口,項目中使用vuejs去訪問別人家的api评凝,
比如豆瓣或者其他的api追葡,不使用jsonp肯定就會報跨域的問題。
解決方法:使用http-proxy-middleware插件
在vue-cli生成的build/dev-server.js中添加
app.use('/api',proxyMiddleware({
target:'http://www.example.org',
changeOrigin:true
}))
路由
響應(yīng)路由參數(shù)的變化
當(dāng)使用路由參數(shù)時奕短,例如從 /user/foo 導(dǎo)航到 user/bar宜肉,原來的組件實例會被復(fù)用。因為兩個路由都渲染同個組件篡诽,比起銷毀再創(chuàng)建崖飘,復(fù)用則顯得更加高效榴捡。 不過杈女,這也意味著組件的生命周期鉤子不會再被調(diào)用。
復(fù)用組件時吊圾,想對路由參數(shù)的變化作出響應(yīng)的話达椰,你可以簡單地 watch(監(jiān)測變化) $route 對象。
const User = {
template: '...',
watch: {
'$route' (to, from) {
// 對路由變化作出響應(yīng)...
}
}
}
路由常用API
表達式 | 返回類型 | 意義 |
---|---|---|
$route.name | String | 當(dāng)前路由的名稱 |
$route.path | String | 對應(yīng)當(dāng)前路由的路徑项乒,總是解析為絕對路徑 |
$route.params | Object | 一個 key/value 對象啰劲,包含了 動態(tài)片段 和 全匹配片段 |
$route.query | Object | 一個 key/value 對象,表示 URL 查詢參數(shù)檀何。/foo?user=1蝇裤,$route.query.user == 1 |
axios
目前主流的 Vue 項目,都選擇 axios 來完成 ajax 請求频鉴,而大型項目都會使用 Vuex 來管理數(shù)據(jù)
cnpm install axios -S
安裝其他插件的時候栓辜,可以直接在 main.js 中引入并 Vue.use(),但是 axios 并不能 use类垦,只能每個需要發(fā)送請求的組件中即時引入
為了解決這個問題爬迟,有兩種開發(fā)思路土匀,一是在引入 axios 之后辐脖,修改原型鏈狭莱,二是結(jié)合 Vuex僵娃,封裝一個 aciton。
方案一:改寫原型鏈
首先在 main.js 中引入 axios
import axios from 'axios'
這時候如果在其它的組件中腋妙,是無法使用 axios 命令的默怨。但如果將 axios 改寫為 Vue 的原型屬性,就能解決這個問題
Vue.prototype.$http = axios
在 main.js 中添加了這兩行代碼之后辉阶,就能直接在組件的 methods 中使用 $http 命令
methods: {
getMovies() {
this.$http.get('url')
.then(res => {
console.log(res.data)
})
.catch(err => {
console.log(err)
})
}
}
小結(jié)
- 每個組件只能包含一個根節(jié)點
- actions彌補了mutations不能異步操作的缺陷