每個vue應用都是通過構造函數Vue創(chuàng)建的一個Vue的根實例啟動的,在實例化Vue時霉颠,需要傳入一個選項對像荆虱,它可以包括是數據诉位,模板,掛載元素岳瞭,方法,生命周期函數等選項
const vm=new Vue({ })
el
提供一個在頁面上已經存在的DOM元素作為實例的掛載目標姚炕,可以是CSS選擇器凄硼,ID選擇器等,也可以是一個HTMLElement實例
new Vue({
el:"#app"
})
如果我們聲明了一個vue實例,但是沒有傳入el屬性尼斧,那么該實例會處于未掛載的狀態(tài),沒有關聯(lián)的DOM屬性烛恤,可以使用$mount來實現手動掛載
const vm=new Vue({
data:{
say:"hellow world"
}
}).$mount("app");
console.log(vm.$data.say)
data
類型: object | function
限制:在組件中對象必須是function格式
對象的格式必須是純粹的對象(含有零或多個key/value的鍵值對)碟贾,可以理解為data應該只能是數據杀餐,不推薦其它形似
不要對data屬性使用箭頭函數蔬崩,在data中this的指向應該是Vue實例
new Vue({
el:"#app",
data:{
name:"tom"
}
})
實例創(chuàng)建之后,可以通過vm.$data訪問原始數據對象,在實例內部可以直接通過this.data[屬性]來獲取指定的屬性
<p>{{this.test}}</p>
<p>{{test}}</p>
<p>{{this.$data.test}}</p>
new Vue({
...
data(){
return {
test:"測試"
}
}
})
props
類型: Array | Object
props可以是數組或對象溅潜,用來接收來自父組件的數據嫁怀,props可以是簡單的數組,或者是用對象作為替代,對象允許接收高級選項岗钩,如類型檢測周蹭,自定義校驗和設置默認值
//簡單語法
Vue.compoment("props-demo",{
props:['size','myMessage']
})
//對象語法
//在對象語法中可以進行類型檢測,設置默認值或者自定義校驗規(guī)則
//類型檢測可以是Js中的簡單數據類型和復雜數據類型显拳,如果從父組件中獲取的值的類型不符合的話棚愤,命令依然會執(zhí)行宛畦,但是在控制臺中會報錯
Vue.component("props-demo",{
props:{
props_a:{
type:'Number',
//type 類型可以是String Number Boolearn Function Fbject Array Symbol 'null'表示允許傳入任意值
//也可以組合傳入 [String,Number] 那伐,表示是多種類型
default:10,
//設置的默認值日熬,如果在父組件中沒有獲取值的話會展示默認值
//如果我們設置類型為Object/Array,default的值必須是一個函數怕敬,default(){ return{ } }
required:true,
//表示必傳
validator: function (value) {
//設置自定義校驗規(guī)則揣炕,value為獲取的父組件的數據,如果不符合校驗條件也會在控制臺報錯
return value > 10
}
}
}
})
在模板中如果要動態(tài)的綁定父組件的數據到子組件中虽填,需要使用v-bind丁恭,在使用動態(tài)綁定后,如果父組件的數據發(fā)生變化斋日,該變化也會傳導給子組件
<child :get-parent-msg="parentMsg"></child>
如果不使用動態(tài)綁定牲览,那么我們最終獲取到的數據只是在標簽中寫入的字符串
<child get-parent-msg="parentMsg"></child>
<!--最后我們在子組件中獲取到的只是字符串parentMsg,并不是父組件中data的parentMsg變量的值-->
由于html的特性是不區(qū)分大小寫的恶守,所以當使用的不是字符串模板時第献,使用駝峰命名法的prop需要轉換為相對應的短橫線相隔開的命名格式
<child :get-parent-msg="parentMsg"></child>
Vue.component("child",{
props:["getParentMsg"]
})
注意,每一次父組件數據更新時兔港,子組件的所有props都會更新為最新值庸毫,如果我們在子組件直接修改props的值,控制臺會報錯
雖然明確給組件定義props是傳參的推薦方式衫樊,但實際組件可以接收任意傳入的特性飒赃,這些特性都會被添加到組件根元素上,例如在使用Botstrap時科侈,我們需要在某一個組件上添加一個data-3d-data-picker特性载佳,這時可以直接把屬性添加到組件上,不需要事先定義prop
<組件 data-3d-date-picker='true'><組件>
添加的屬性data-3d-data-picker會自動被添加到組件的根元素上
computed
我們在模板內可以運用表達式臀栈,但是如果在模板內放入太多的邏輯代碼會讓后期的維護變得十分困難蔫慧,vue為我們提供了computed來處理復雜邏輯,例如:
<p>{{msg.split('').reverse().join("")}}</p>
<!--對于這樣的邏輯挂脑,我們可以將其放置到computed中來進行處理-->
computed:{
reverse:function () {
return this.msg.split("").reverse().join("");
}
}
//computed的變量會掛載到實例本身藕漱,可以直接使用
<p>{{reverse}}</p>
在上面的例子中,reverse的值依賴于msg崭闲,使用計算屬性肋联,在msg的值發(fā)生變化時,reverse的值也會相應的發(fā)生變化
對于在computed中設置監(jiān)測數據變化方法刁俭,如果我們使用methods同樣可以實現
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// a computed getter
reversedMessage: function () {
// `this` points to the vm instance
return this.message.split('').reverse().join('')
}
}
})
//轉化為method方式
var vm=neww Vue({
el:'#example',
data:{
message:"hello"
},
methods:{
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
})
//然后在頁面中調用reversedMessage()方法即可
{{reversedMessage()}}
兩者的區(qū)別在于computed是會基于他們的依賴進行緩存橄仍,只有在它的依賴發(fā)生改變時才會重新求值
這意味著如果數據沒有發(fā)生變化,即使多次訪問計算機也只會返回之前的計算結果牍戚,而不必再次執(zhí)行函數操作
而如果使用methods侮繁,只要重新渲染methods就會執(zhí)行該函數
計算屬性默認只有getter,但是我們也可以提供一個setter
var vm = new Vue({
el: ".test",
data: {
a: 1
},
methods:{
click(){
this.b=2;
}
},
computed: {
b:{
get: function () {
return this.a+1;
},
set: function (newValue) { //參數是必須的
this.a = newValue-1;
}
}
}
})
//計算屬性中默認是只有get的如孝,我們在平時使用的時候大部分都是通過改變a的值來改變b的值
//在設置了set之后宪哩,如果我們改變b的值,那么a的值也會相應的改變
//值得改變的順序是首先調用set改變a的值第晰,在a的值發(fā)生改變后會調用get锁孟,b的值同時發(fā)生改變
methods
大部分時候我們定義在元素上的方法都是定義在methods中的
methods將被混入到Vue實例中,可以直接通過vm實例訪問這些方法茁瘦,或者在指令表達式中使用
方法中的this自動綁定為vue的實例品抽,也就是我們需要注意一點,在使用methods時不要通過箭頭函數來定義methods函數甜熔,因為箭頭函數會自動綁定父級作用域的上下文
在methods中定義的事件圆恤,可以通過v-on來定義一個方法來接收
<div @click="get($event)"></div>
new Vue({
methods:{
get(event){
}
}
})
在通過v-on定義的方法來接收事件時可以傳入參數,$event是vue封裝的事件運動狀態(tài)
在這段代碼中在div標簽get($event)中$event是我們傳入的實參腔稀,methods中傳入的event是形參
如果我們在div標簽中沒有傳入參數盆昙,那么在methods中傳入的是實參
在使用v-on進行事件綁定還可以有以下幾種寫法
<!-- 行內語法 -->
<button v-on:click="counter+=1"></button>
<!-- 對象語法 (2.4.0+) -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
<!-- 阻止默認行為,沒有表達式 -->
<form @submit.prevent></form>
<input type="text" :value=value @input="value=$event.target.value">
它實際是一下寫法的簡寫形式(這里是對vue中利用v-model分析時寫的)
<body>
<div id="box">
<!--<input type="text" :value=value @input="$event.target.value">-->
<input type="text" @input='change($event)'>
{{value}}
</div>
<script>
new Vue({
data: {
value: ''
},
methods:{
change(e){
this.value=e.target.value
}
}
}).$mount("#box")
</script>
</body>
vue.js為v-on提供了事件修飾符烧颖,可以通過.表示的指令來調用修飾符
<!--阻止事件冒泡-->
<a @click.stop="click"></a>
<!--阻止默認事件-->
<form @submit.prevent="click"></form>
<!--添加事件偵聽器時使用事件捕獲模式-->
<a @click.capture="click"></a>
<!--只當事件在元素本身觸發(fā)時觸發(fā)回調弱左,例如在子元素觸發(fā)是不響應的-->
<a @click.self="click"></a>
<!--點擊事件只會觸發(fā)一次-->
<a @click.once="click"></a>
<!--2.3.0版本提供了.passive選項,用來優(yōu)化scroll等事件的滾動流暢度炕淮,提升移動端的流暢度-->
<div @scroll.passive="onScroll"></div>
<!--注意不要及那個passive和prevent同時使用拆火,prevent將會被忽略-->
<!--使用修飾符時注意 1.修飾符是可以串聯(lián)的-->
<a @click.stop.prevent="click"></a>
<!--2.順序很重要 @click.prevent.self會阻止所有的點擊,而@click.self.prevent只會阻止該元素的點擊-->
vue.js提供了鍵值修飾符涂圆,在監(jiān)聽鍵盤事件時们镜,我們經常需要監(jiān)測常見鍵值
<!--只有在按下keyCode鍵碼為13的鍵時才會觸發(fā)submit事件-->
<input @keyup.13="submit">
<!--veu為常見的按鍵提供了別名-->
.enter .tab .delete (捕獲 “刪除” 和 “退格” 鍵) .esc .space .up .down .left .right
<!--可以通過全局config.keyCode對象自定義鍵值修飾符別名,例如定義keyCode為112的按鍵定義別名為.f1-->
Vue.config.keyCode.f1=112
<!--可以用如下修飾符開啟鍵盤事件監(jiān)聽-->
.ctrl .alt .shift .meta
<!--Alt + C-->
<input @keyup.alt.67="clear">
<!--2.5.0新增加了.exact修飾符,允許我們控制精確的按鍵-->
<!-- 即使 Alt 或 Shift 被一同按下時也會觸發(fā) -->
<button @click.ctrl="onClick">A</button>
<!-- 有且只有 Ctrl 被按下的時候才觸發(fā) -->
<button @click.ctrl.exact="onCtrlClick">A</button>
vue.js提供了鼠標按鈕修飾符
.left .right .middle
在一個組件被銷毀時所有掛載在該組件上的方法都會被銷毀
watch
vue中提供watch對象润歉,可以用來監(jiān)視實例屬性的變化模狭,鍵是需要觀察的表達式,值是對應回調函數/方法名/包含選項的對象踩衩,
new Vue({
data: {
a: 1
},
methods:{
click(){
this.a=2
}
},
watch: {
a: function (val, oldVal) {
console.log('new: %s, old: %s', val, oldVal)
}
}
//watch用來監(jiān)視變量a的變化嚼鹉,在a發(fā)生變化后執(zhí)行我們定義的函數
//函數中傳入的兩個參數val代表a改變后的值贩汉,oldVal代表a改變之前的值
}).$mount(".test")
//也可以通過調用一個在methods中已經定義方法的方法名來執(zhí)行改動后的操作
new Vue({
data: {
a: 1,
b:{
num:10
}
},
methods: {
click() {
this.a = 2
},
someMethod(n, o) {
console.log(n);
},
},
watch: {
a: "someMethod",
//對于復雜類型的數據,要使用以下的深度類型的方法
b: {
handler(val, old) {
console.log(val);
console.log(old);
}
//如果想要查看對象內部的某個屬性值的變化锚赤,需要開啟深度檢測匹舞,被監(jiān)測者需要是一個字符串格式例如 "b.num" 的格式
//如果不開啟深度檢測對象的兩個參數返回的都是改變后的值,如果開啟了深度檢測那么還是會返回改變之前和改變之后的值
deep:true
}
}
}).$mount(".test")
Vue實例可以通過調用$watch方法來進行監(jiān)測
var vm = new Vue({
data: {
a: 8
}
methods: {
click() {
this.a = 2
},
someMethod(n, o) {
console.log(n);
},
}
}).$mount(".test")
vm.$watch("a",function (n,o) {
console.log(n);
})
parent
指定已創(chuàng)建的實例的父實例线脚,在兩者之間建立父子關系赐稽,子實例可以用this.$parent訪問父實例
子實例被推入父實例的$children數組中
<body>
<div id="parent"></div>
<div id="child"></div>
<script>
var vm = new Vue({
el: "#parent",
})
var vn=new Vue({
el:"#child",
parent:vm
})
console.log(vn.$parent.$el) //<div id="parent"></div>
console.log(vm.$children[0].$el); //<div id="child"></div>
</script>
</body>
mixins
混合對象可以包含任意組件選項,以組件使用混合對象時浑侥,所有混合對象的選項將被混入該組件本身的選項
這是vue官方對混合的解釋姊舵,比較抽象,在實際運用后自己大概有個了解寓落,可以簡單理解為混合的作用就是將我們在頁面內的組件或實例中的公共部分抽離出來括丁,將這些公共部分單獨設置為一個模塊,在使用時將該模塊導入即可零如,而不需要重復再去寫這些公共部分,
在這一部分上我們可以將它理解為組件躏将,但是與組件的不同在于,混合對象在被導入到實例/組件的時候會自動的查看是否與組件本身已有的數據沖突考蕾,如果有沖突祸憋,那么它會按照自定的規(guī)則進行合并
<body>
<div id="box">
<child></child>
<p @click="click">{{msg}}</p>
</div>
<script>
var msg = {
data: {
msg: "實例混合對象的數據"
}
},
tem = {
data() {
return {
msg: "組件混合對象的數據"
}
}
},
callback = {
methods: {
click() {
console.log("混合對象的點擊事件")
}
},
mounted(){
console.log("混合對象的掛載完成函數觸發(fā)");
}
};
Vue.component("child", {
template: `
<div>
<p @click="click">{{msg}}</p>
</div>
`,
methods: {
click(){
console.log("組件本身的點擊事件")
}
},
mixins: [tem, callback]
})
new Vue({
el: "#box",
data: {
msg: "實例原本的數據"
},
mounted(){
console.log("實例本身的掛載完成函數觸發(fā)");
},
mixins: [msg, callback]
})
</script>
</body>
在上面的栗子我們可以注意到,混合本身的混合規(guī)則:
- 如果實例/組件的值為對象的選項肖卧,如methods蚯窥,components將被混合為一個對象,在兩個對象鍵名沖突時塞帐,取組件/實例對象的鍵值對拦赠,實例中不存在相同鍵名時則會將混合對象的鍵值添加到實例/組件中
- 如果實例/組件和混合對象含有同名選項時,例如存在同名鉤子函數葵姥,那么會將這些函數混合為一個數組荷鼠,因此混合對象的鉤子函數和實例/組件的鉤子函數都將會被調用,但是混合對象的鉤子函數將會在實例/組件的鉤子函數之前被調用
也可以注冊全局混合對象榔幸,但是需要注意允乐,一旦使用全局混合對象,將會影響到所有之后所有創(chuàng)建的Vue實例削咆,包括第三方模板牍疏,大多數情況下不推薦使用
Vue.mixin({
....
})
filter
在Vue2.0之后,官方取消了內置的過濾器拨齐,但是仍然保留了自定義過濾器的方法鳞陨,我們如果需要對一些常見的文本進行格式化,可以自定義一個過濾器
Vue為我們提供了兩種自定義過濾器的方法瞻惋,第一種是在組件內部自定義一個內部使用的過濾器
<p>{{ str | upperCase}}</p>
new Vue({
//...
filters:{
upperCase(value){
return value.toUpperCase();
}
}
})
第二種就是可以在Vue實例上創(chuàng)建全局的過濾器
new Vue({
//...
})
Vue.filter("lowerCase",(value)=>{
if(!value) return;
return value.toLowerCase();
})
過濾器可以進行聯(lián)寫
<p>{{ str | upperCase | lowerCase }}</p>
在過濾器中厦滤,默認的第一個參數就是我們的就收的變量援岩,除此之外還可以接收其他參數,其他參數的第一個是我們函數中參數的第二個掏导,依次類推
<p>{{ str | upperCase | lowerCase("a","b") }}</p>
過濾器除了可以應用在{{ }}窄俏,也可以用來處理v-bind:
<div v-bind:id="rawId | formatId"></div>
在創(chuàng)建全局的filter時我們一般會將所有的過濾器放在一個文件下,然后利用Object.keys將所有的過濾器綁定到Vue實例上
import filters from './filters'
Object.keys(filters).forEach(key => Vue.filter(key, filters[key]))