---
# System prepended metadata

title: '【VUE】常用API (extend, filter...)'
tags: [VUE]

---

---
tags: VUE
---
【VUE】常用API (extend, filter...)
===
## Extend
```javascript=
// extend 是基礎建構的概念
var newExtend = Vue.extend({
  data: function() {
    return {
      data: {},
      extendData: '這段文字是 extend 得到'
    }
  },
  template: '#row-component',
  mounted: function() {
    console.log('Extend:', this)
  }
})
var childOne = {
  props: ['item'],
  extends: newExtend
}

var childTwo = {
  props: ['item'],
  data() {
    return {
      childTwo: '元件2',
      extendData: '這得的的的'
    }
  },
  template: '#row-component-two',
  extends: newExtend,
  mounted() {
    console.log('childTwo')
  }
}
```

## Filter
```htmlmixed=
<div id="app">
  <table class="table">
    <tbody>
      <tr is="row-component" v-for="(item, key) in data" :item="item" :key="key"></tr>
    </tbody>
  </table>
  {{ data[1].cash }}
</div>

<script type="text/x-template" id="row-component">
  <tr>
    <td>{{ item.name }}</td>
    <td>{{ item.cash | currency }}</td>
    <td>{{ item.icash | currency | dollarSign}}</td>
  </tr>
</script>

<script>
var child = {
  props: ['item'],
  template: '#row-component',
  data: function() {
    return {
      data: {}
    }
  },
  filters: {
    // 局部註冊
    dollarSign(n) {
      return `$ ${n}`
    },
    currency (n) {
      return n.toFixed(2).replace(/./g, function(c, i, a) {
        return i && c !== "." && ((a.length - i) % 3 === 0) ? ',' + c : c;
      });
    }
  },
  mounted: function() {
    console.log('Component:', this)
  }
}
```
- 全域掛載
```javascript=
Vue.filter('dollarSign', (n) => {
  return `$ ${n}`
})
Vue.filter('currency', (n) => {
  return n.toFixed(2).replace(/./g, function(c, i, a) {
    return i && c !== "." && ((a.length - i) % 3 === 0) ? ',' + c : c;
  });
})
```
# $set
- 無法寫入資料時，用$set
```javascript=
// data沒有item 
  this.$set(this.data, 'item', {
    name: this.item.name
  })
  console.log(this.data, this);
```
## Mixins
```javascript=
let mixinFilter = {
  template: '#row-component',
  filters: {
    dollarSign: function (n) {
      return `$ ${n}`
    },
    currency: function(n) {
      return n.toFixed(2).replace(/./g, function(c, i, a) {
          return i && c !== "." && ((a.length - i) % 3 === 0) ? ',' + c : c;
      });
    }
  },
}
let mixinMounted = {
  mounted () {
    console.log('這段是 Mixin 產生')
  }
}
Vue.component('row-component', {
  props: ['item'],
  data: function() {
    return {
      data: {},
    }
  },
  mixins: [mixinFilter, mixinMounted]
});
Vue.component('row-component-two', {
  props: ['item'],
  data: function() {
    return {
      data: {
        data: 'two'
      },
    }
  },
  mixins: [mixinFilter, mixinMounted]
});
```
# Directive 自定義指令
[文件](https://cn.vuejs.org/v2/guide/custom-directive.html)
- inserted 被綁定元素插入父節點時調用
```htmlmixed=
<input type="email" v-model="email" v-focus >
```
```javascript=
Vue.directive('focus', {
  inserted(el) {
    el.focus()
  }
})
```
- bind
    - 只調用一次，指令第一次綁定到元素時調用。
    - 在這裡可以進行一次性的初始化設置

```javascript=
Vue.directive('validator', {
  bind(el, binding, vnode) {
    el.className = 'form-control'
  },
  update(el, binding, vnode, oldVnode) {
    console.log('oldVnode ', oldVnode)
    console.log('vnode', vnode)
  }
});
```
- update
    - 組件的VNode更新時調用
    - oldVnode: 上一個虛擬節點，僅在update和componentUpdated鉤子中可用

- componentUpdated
    - 指令所在組件的VNode 及其子VNode全部更新後調用。
