본문 바로가기
WEB/Vue.js

[Vue.js] Mixin

by Raymond 2022. 7. 29.

Mixin(믹스인)


Mixins는 Vue 컴포넌트에 재사용 가능한 기능을 배포하는 유연한 방법입니다. mixin 객체는 모든 구성 요소 옵션을 포함할 수 있습니다. 컴포넌트에 mixin을 사용하면 해당 mixin의 모든 옵션이 컴포넌트의 고유 옵션에 “혼합”됩니다.

 

폴더구조

project
|--src
    |--mixins
    |	|--formatter.js
    |--views
    |	|--advanced
    |       |--MixinView.vue

 

작동방식

일반적이 .vue파일은 script태그 안에 javascript코드를 별도로 만듭니다. 예를들어 script안의 코드가 다른 파일에도 쓰여 재사용을 많이 해야하는 경우에  Mixin의 사용이 고려됩니다. 사용 방법은 js파일을 만들어 script태그안에 들어가야했을  코드를 작성하고 .vue(부모)파일에 import 명칭 from '경로' 와  mixins: [명칭]을 넣어 사용을 합니다. 믹스인 파일의 코드를 병합하여 훅인 created와 mounted의 실행순서를 보면 Mixin파일의 created / 부모(.vue파일)의 created / Mixin파일의 mounted / 부모(.vue파일)의 mounted 순서로 실행됩니다. 즉 .js파일인 믹스인 파일이 먼저 실행이되고 부모인 .vue파일의 코드가 실행이 됩니다.

 

Mixin함수는 앞에 $를 붙이는게 룰입니다. 그래야 이 함수가 mixin으로 가져온 js파일에서 정의된 함수이구나를 알수있음.

Mixin 사용해보기

 

formatter.js

export default {
  created() {
    // console.log('formatter의 created')
  },
  mounted() {
    // console.log('formatter의 mounted')
  },

  methods: {
    $convertDateFormat(d, f) {
      let year = ''
      let month = ''
      let day = ''
      // '20220601' or Date()객체가 들어올수 있다.
      if (typeof d === 'string' && d.length === 8) {
        year = d.substr(0, 4)
        month = d.substr(4, 2)
        day = d.substr(6, 2)
      } else if (typeof d === 'object') {
        year = d.getFullYear()
        month = (d.getMonth() + 1).toString().padStart(2, 0)
        day = (d.getDate() + 1).toString().padStart(2, 0)
      }

      // f - 'YYYY-MM-DD' or 'MM-DD-YYYY' 입력가능
      return f.replace('YYYY', year).replace('MM', month).replace('DD', day)
    }
  }
}

 

MixinView.vue

import Formatter from '@/mixins/formatter' 와 mixin:[Formatter]을 추가하여 mixin 사용이 가능합니다.
아래 코드를 보면 method에 정의되지 않은 $convertDateFormat함수를 사용하는 것을 볼 수 있습니다.
<template>
</template>
<script>
import Formatter from '@/mixins/formatter'
export default {
  components: {},
  mixins: [Formatter],
  data() {
    return {
      sampleData: ''
    }
  },
  setup() {},
  created() {
    // console.log('Mixin의 created')
  },
  mounted() {
    console.log('Mixin의 mounted')
    console.log(this.$convertDateFormat('20220601', 'YYYY-MM-DD'))
    console.log(this.$convertDateFormat('20220601', 'MM.DD.YYYY'))
  },
  unmounted() {},
  methods: {
    }
  }
}
</script>

Mixin 응용 (데이터를 수집하기)

 

사용자의 데이터를 수집하여 몇초간 라우트 패스를 들어갔는지 등등의 정보를 기록하여 사용자의 사용방식을 알 수 있습니다. mounted hook을 이용하여 사용자가 들어갈떄와 unmounted로 나갈때를 기록하는 방식 

 

데이터 수집은 모든 화면에 전역으로 적용을 하는경우가 많으므로 main.js에 등록하여 사용을 할수 있습니다. 하지만 모든 화면의 script파일에 병합이 되므로 main.js에 적용하는것은 조심하여 사용해야 합니다.

 

project
|--src
    |--mixins
    |	|--status.js

 

status.js

export default {
  created() {},
  mounted() {
    // 현재 시간/분/초, 사용자아이디, 현재 라우트 패스를 서버 데이터베이스에 저장
    console.log(this.$route.path)
  },
  unmounted() {
    // 현재 시간/분/초, 사용자아이디, 현재 라우트 패스를 서버 데이터베이스에 저장
    console.log(this.$route.path)
  },
  methods: {}
}

Mixin 전역 설정

 

project
|--src
    |--mixins
    |	|--index.js
    |--views
    |	|--advanced
    |       |--MixinView.vue
    |--main.js

 

index.js

axios 라이브러리 사용
오픈소스 라이브러리 이고 서버와 통신하는데 사용합니다. fetch보다 훨씬 간편합니다. Mixin으로 전역으로 쓰면 좋다. 어디든 데이터 서버에서 가져오기 때문입니다. 또한 사용을 하려면 json-server와 같이 서버와 연결이 되야만 합니다.
import axios from 'axios'

export default {
  methods: {
    async $get(url) {
      return (
        await axios.get(url).catch((e) => {
          console.log(e)
        })
      ).data
    },
    $convertDateFormat(d, f) {
      let year = ''
      let month = ''
      let day = ''
      if (typeof d === 'string' && d.length === 8) {
        year = d.substr(0, 4)
        month = d.substr(4, 2)
        day = d.substr(6, 2)
      } else if (typeof d === 'object') {
        year = d.getFullYear()
        month = (d.getMonth() + 1).toString().padStart(2, 0)
        day = (d.getDate() + 1).toString().padStart(2, 0)
      }
      return f.replace('YYYY', year).replace('MM', month).replace('DD', day)
    }
  }
}

 

main.js

main.js파일에 import mixin from './mixins' 와 app.use(mixin)을 통해서 mixins/index.js에 정의된 mixin을 전역으로 사용할수 있습니다.
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// Mixin 전역으로 선언
import mixin from './mixins'

const app = createApp(App)
app.use(store)
app.use(router)
app.mixin(mixin)
app.mount('#app')

 

MixinView.vue

main.js에서 전역으로 선언한 mixin파일에 있는 $convertDateFormat, $get 함수들을 사용할수 있습니다.
<template>
  <div></div>
</template>
<script>
// 전역믹스인 선언을 위해 주석처리
// import Axios from '@/mixins/axios'
export default {
  components: {},
  // mixins: [Axios],
  data() {
    return {
      sampleData: ''
    }
  },
  setup() {},
  created() {
  },
  mounted() {
    this.getCustomers()
    console.log(this.$convertDateFormat('20220601', 'MM-DD-YYYY'))
    console.log(this.$convertDateFormat('20220601', 'MM.DD.YYYY'))
  },
  unmounted() {},
  methods: {
    async getCustomers() {
      const customers = await this.$get('http://localhost:3000/customers')
      console.log(customers)
    }
  }
}
</script>

 

참고자료

https://kr.vuejs.org/v2/guide/mixins.html

 

'WEB > Vue.js' 카테고리의 다른 글

[Vue.js] Vuex  (0) 2022.08.13
[Vue.js] 플러그인  (0) 2022.08.10
[Vue.js] Custom Directive  (0) 2022.07.27
[Vue.js] provide & inject  (0) 2022.07.25
[Vue.js] 레이아웃 컴포넌트  (0) 2022.07.24

댓글