Vue 常用 API
===
###### tags: `Vue.js` `Vue`
官網:https://cn.vuejs.org/v2/api/
## 使用 **Extend** 做元件重複部分的Reuse
```javascript=
const newExtend = Vue.extend({
...
mounted() {
console.log('Extend mounted', this);
}
});
```
```javascript=
Vue.component('extend-cmpt-one', {
...
extends: newExtend
});
```
```javascript=
Vue.component('extend-cmpt-two', {
...
extends: newExtend,
mounted() {
console.log('extend-cmpt-two mounted');
}
});
```
實作範例:https://codepen.io/lala-lee-jobs/pen/wvaYzBB
## 使用 **Filter** 自定義畫面資料格式
### 寫在元件內 (Local registration)
```javascript=
Vue.component('my-cmpt', {
...,
filters: {
dollarSign(n) { return `$ ${n}`; },
currency(n) { return ...; }
},
...
});
```
### 寫在全域 (Global registration)
```javascript=
Vue.filter('dollarSign', (n) => { return `$ ${n}`; });
Vue.filter('currency', (n) => { return ...; });
```
實作範例:https://codepen.io/lala-lee-jobs/pen/JjdmRez
## 無法寫入的資料,使用$set做設定
**Vue Reactivity (Vue 的響應式原理)**
https://cn.vuejs.org/v2/guide/reactivity.html
有些資料無法預先定義資料格式,例如ajax下來的資料內容,因為Vue會封裝成自己的資料結構(...),使用getter/setter方法去存取(Vue會在初始化實例時對屬性執行getter/setter轉化)
![](https://i.imgur.com/qby9pGR.png)
在HTML模版只會反應Vue綁定好的資料結構,所以需要使用$set把資料寫到Vue的結構內,才能被Vue監控變化用以重新渲染畫面
> 如果要動態設定某個物件的值
> const someObj = { propname: 2 };
> 這樣設定是不會直接反應在畫面上,需要透過set的方式
* 使用全局Vue.set設定的方式
Vue.set(object, propertyName, value)
```javascript=
Vue.set(this.someObj, 'propname', 2);
```
* 使用Vue實例的方式,這也是全局Vue.set方法的別名
this.$set(object, propertyName, value);
```javascript=
this.$set(this.someObj, 'propname', 2)
```
### 補充
>**物件部分:一開始沒有被註冊到的物件,不會響應式更新**
>* 方法一:在 data 中要把所有需要響應式的資料設定進去 (預先定義)
>* 方法二:動態添加新的響應式屬性 Vue.set(...) or this.$set(...)
>* 方法三:建立新的物件 Object.assign({}, obj1, obj2, ...);
>**陣列部分:利用陣列索引直接設值時,沒有辦法產生響應式的變化**
>* 方法一:使用 Vue 可觀察到的陣列方法 (可促使畫面重新渲染)
>`push()`、`pop()`、`shift()`、`unshift()`、`splice()`
>`sort()`、`reverse()`
>* 方法二:使用Set方法動態設定
>`Vue.set(array, index, value)`
>`this.$set(array, index, value)`
## Mixin 混合多個元件的行為
```混合mixins```和```繼承extends```
其實兩個都可以理解為繼承,用來使元件部分的程式碼可以Reuse
* mixins 接收物件陣列(可理解為多繼承)
```
mixins: [mixinObj1, mixinObj2]
```
* extends接收的是物件或函式(可理解為單繼承)
```
extends: extendObj
```
```javascript=
const extendObj = {
created () {
console.log('extendObj created')
}
};
const mixinObj1 = {
created () {
console.log('mixinObj1 created')
}
};
const mixinObj2 = {
created () {
console.log('mixinObj2 created')
}
};
Vue.component('my-cmpt', {
extends: extendObj,
mixins: [mixinObj1, mixinObj2],
created () {
console.log('my-cmpt created')
}
}
```
執行範例:https://codepen.io/lala-lee-jobs/pen/YzXJgOL
![](https://i.imgur.com/O0xaRDM.png)
可以發現同時宣告extends和mixins時,extends的Lifecycle觸發的時機點會早於mixins,mixins則早於元件本身
## 使用 Directive 開發自己的互動 UI
### 宣告 Directive
#### 全域
```
Vue.directive('focus', {
inserted: function (el) {
el.focus()
}
});
```
#### 局部
```
directives: {
focus: {
inserted: function (el) {
el.focus()
}
}
}
```
### 使用 Directive
```
<input v-focus>
```
### Directive Hook Function
* bind:只調用一次,Directive第一次綁定到元素時調用。初始化設置可在此實作。
* inserted:被綁定Directive的元素插入父節點時調用
* update:所在Component的VNode更新時調用,但是可能發生在其子VNode更新之前。Directive的值可能發生了改變,也可能沒有。但是你可以通過比較更新前後的值來忽略不必要的模板更新
* componentUpdated:Directive所在Component的 VNode 及其子VNode全部更新後調用。
* unbind:只調用一次,Directive與元素解綁時調用
### Directive Hook Arguments
* el:Directive 所綁定的元素,可以用來直接操作DOM。
* binding:Object,包含以下屬性:
* name:不包括v-前綴的Directive名稱
* value:Directive的綁定值,例如:v-my-directive="1 + 1"中,綁定值為2。
* oldValue:Directive綁定的前一個值,僅在update和componentUpdated鉤子中可用。無論值是否改變都可用。
* arg:傳給Directive的參數,可選。例如v-my-directive:foo中,參數為"foo"。
* vnode:Vue編譯生成的虛擬節點。
* oldVnode:上一個虛擬節點,僅在update和componentUpdated鉤子中可用。
實作範例:https://codepen.io/lala-lee-jobs/pen/mdJQMRv