본문 바로가기
Vue/Vue.js

2-1. Custom Directive

by 문자메일 2024. 9. 20.

 

v-model, v-for, v-if, v-show 이런게 vue에서 지정해놓은 default directive 이다.

그런데 custom directive라고 하는 것은, Vue에서 default로 만들어 놓은 디렉티브 외에도 개발자가 추가적인 디렉티브를 만들어서 선언해서 사용할 수 있게끔 제공을 해주는 것이다.

 

 

 

기본 사용법

1. data를 아무것도 binding 안 해도 된다.

  • 아래에서 v-focus

2. 하나의 값만 binding 해도 된다.

  • 아래에서 v-color

3. key-value로 여러개 넣어도 된다.

  • 아래에서 v-demo
<template>
  <div>
    <div>
      <label for="email" class="form-label">이메일주소</label>
      <input type="email" name="" id="email" class="form-control" v-focus />
    </div>
    <div>
      <label for="pw" class="form-label">비밀번호</label>
      <input type="password" name="" id="pw" class="form-control" />
    </div>
    <div>
      <button class="btn btn-primary">로그인</button>
    </div>
    <div v-color="color" style="height: 50px"></div>
    <div v-demo="{ color: 'red', text: 'hello!' }"></div>
  </div>
</template>
<script>
export default {
  components: {},
  directives: {
    focus: {
      // el은 element, binding은 바인딩한 어떤 data를 가져온다.
      mounted(el, binding) {
        el.focus()
      }
    },
    color: {
      created(el, binding) {
        console.log(binding.value)
        el.style.backgroundColor = binding.value
      }
    },
    demo: {
      mounted(el, binding) {
        el.innerText = binding.value.text
        el.style.color = binding.value.color
      }
    }
  },
  data() {
    return {
      sampleData: '',
      color: 'red'
    }
  },
  created() {},
  mounted() {},
  unmounted() {},
  methods: {}
}
</script>

 

 

 

------------------------

 

Custom Directive 전역으로 설정하기

main.js에서 설정하면 된다.

 

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import PageTitle from './components/fragments/PageTitle.vue'
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.min.js'

const app = createApp(App)

app.use(store)
app.use(router)
app.component('page-title', PageTitle) // 특정 컴포넌트를 글로벌하게 선언하여 다른 곳에서 아요할 수 있다.
app.directive('focus', {
  mounted(el, binding) {
    el.focus()
  }
})
app.directive('lowercase', {
  mounted(el) {
    el.addEventListener('input', (event) => {
      console.log(event.target.value)
      event.target.value = event.target.value.toLowerCase()
    })
  }
})
app.directive('uppercase', {
  mounted(el) {
    el.addEventListener('input', (event) => {
      event.target.value = event.target.value.toUpperCase()
    })
  }
})
app.directive('number', {
  mounted(el) {
    el.addEventListener('input', (event) => {
      console.log(event.target.value)
      event.target.value = event.target.value.replace(/\D/g, '')
    })
  }
})

app.directive('korean', {
  mounted(el) {
    el.addEventListener('input', (event) => {
      console.log(event.target.value)
      event.target.value = event.target.value.replace(
        /[^ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/g,
        ''
      )
    })
  }
})
app.mount('#app')

 

 

 

 

 

<template>
  <div>
    <div>
      <label for="email" class="form-label">이메일주소</label>
      <input type="email" name="" id="email" class="form-control" v-focus />
    </div>
    <div>
      <label for="pw" class="form-label">비밀번호</label>
      <input type="password" name="" id="pw" class="form-control" />
    </div>
    <div>
      <button class="btn btn-primary">로그인</button>
    </div>
    <div v-color="color" style="height: 50px"></div>
    <div v-demo="{ color: 'red', text: 'hello!' }"></div>
    <div>
      <input type="text" name="" id="" v-lowercase class="form-control" />
    </div>
    <div>
      <input type="text" name="" id="" v-uppercase class="form-control" />
    </div>
    <div>
      <input type="text" name="" id="" v-number class="form-control" />
      <input type="number" name="" id="" class="form-control" />
    </div>
    <div>
      <input type="text" name="" id="" v-korean class="form-control" />
    </div>
  </div>
</template>
<script>
export default {
  components: {},
  directives: {
    // focus: {
    //   // el은 element, binding은 바인딩한 어떤 data를 가져온다.
    //   mounted(el, binding) {
    //     el.focus()
    //   }
    // },
    // lowercase: {
    //   mounted(el) {
    //     el.addEventListener('input', (event) => {
    //       console.log(event.target.value)
    //       event.target.value = event.target.value.toLowerCase()
    //     })
    //   }
    // },
    // uppercase: {
    //   mounted(el) {
    //     el.addEventListener('input', (event) => {
    //       event.target.value = event.target.value.toUpperCase()
    //     })
    //   }
    // },
    // number: {
    //   mounted(el) {
    //     el.addEventListener('input', (event) => {
    //       console.log(event.target.value)
    //       event.target.value = event.target.value.replace(/\D/g, '')
    //     })
    //   }
    // },
    // korean: {
    //   mounted(el) {
    //     el.addEventListener('input', (event) => {
    //       console.log(event.target.value)
    //       event.target.value = event.target.value.replace(
    //         /[^ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/g,
    //         ''
    //       )
    //     })
    //   }
    // },
    color: {
      created(el, binding) {
        console.log(binding.value)
        el.style.backgroundColor = binding.value
      }
    },
    demo: {
      mounted(el, binding) {
        el.innerText = binding.value.text
        el.style.color = binding.value.color
      }
    }
  },
  data() {
    return {
      sampleData: '',
      color: 'red'
    }
  },
  created() {},
  mounted() {},
  unmounted() {},
  methods: {}
}
</script>

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

2-2. mixin  (0) 2024.09.21
1-11. slot  (0) 2024.09.13
1-10. 재사용 컴포넌트, 심플 그리드  (0) 2024.09.13
1-9. 재사용 컴포넌트, 부모<->자식 간 값 전달  (0) 2024.09.12
1-8. 라이프사이클 훅  (0) 2024.09.12

댓글