Vue.js-단일 파일 구성 요소에서 전역 적으로 사용 가능한 도우미 기능 만들기


100

많은 (50 개 이상의) 단일 파일 구성 요소 가있는 Vue 2 프로젝트가 있습니다 . 라우팅에는 Vue-Router를 사용하고 상태에는 Vuex를 사용합니다.

문자열의 첫 글자를 대문자로 바꾸는 것과 같은 많은 범용 함수를 포함하는 helpers.js 라는 파일 이 있습니다. 이 파일은 다음과 같습니다.

export default {
    capitalizeFirstLetter(str) {
        return str.charAt(0).toUpperCase() + str.slice(1);
    }
}

main.js 파일은 앱을 초기화합니다.

import Vue from 'vue'
import VueResource from "vue-resource"
import store from "./store"
import Router from "./router"
import App from "./components/App.vue"

Vue.use(VueResource)

const app = new Vue({
    router: Router,
    store,
    template: '<app></app>',
    components: { App }
}).$mount('#app')

App.vue 파일에는 다음 템플릿이 포함되어 있습니다.

<template>
    <navbar></navbar>
    <div class="container">
        <router-view></router-view>
    </div>
</template>

<script>
export default {
    data() {
        return {
            //stuff
        }
    }
}
</script>

그런 다음 Vue-Router가 <router-view>App.vue 템플릿 의 태그 내부로 이동하는 작업을 처리하는 단일 파일 구성 요소 가 많이 있습니다.

이제 SomeComponent.vue에capitalizeFirstLetter() 정의 된 구성 요소 내 에서 함수 를 사용해야한다고 가정 해 보겠습니다 . 이렇게하려면 먼저 가져와야합니다.

<template>Some Component</template>

<script>
import {capitalizeFirstLetter} from '../helpers.js'
export default {
    data() {
        return {
            myString = "test"
        }
    },
    created() {
         var newString = this.capitalizeFirstLetter(this.myString)
    }
}
</script>

모두는 아니지만 많은 다른 구성 요소로 함수를 가져 오기 때문에 이것은 빠르게 문제가됩니다. 이것은 반복적으로 보이며 또한 프로젝트를 유지하기 어렵게 만듭니다. 예를 들어 helpers.js 또는 그 안에있는 함수의 이름을 바꾸려면이를 가져 오는 모든 단일 구성 요소로 이동하여 import 문을 수정해야합니다.

간단히 말해서 , helpers.js 내부의 함수를 전역 적으로 사용 가능 하게 만들려면 먼저 함수 를 가져온 다음 함수 이름 앞에 추가하지 않고도 모든 구성 요소 내에서 호출 할 수 있도록 하려면 어떻게해야 this합니까? 나는 기본적으로 이것을 할 수 있기를 원합니다.

<script>
export default {
    data() {
        return {
            myString = "test"
        }
    },
    created() {
         var newString = capitalizeFirstLetter(this.myString)
    }
}
</script>

글로벌 믹스 인을 사용할 수 있지만 this.
Bert

2
도우미 를 가져올 필요없이 템플릿에서 직접 사용할 수 있도록 도우미를 필터 로 노출하는 것을 고려 했습니까 ? 그것이 제가 취하는 전략이고 지금까지 잘 진행되고 있습니다.
데이비드 웰던

답변:


154

먼저 가져 와서 함수 이름 앞에 추가 할 필요없이 컴포넌트 내부에

당신이 묘사 한 것은 mixin 입니다.

Vue.mixin({
  methods: {
    capitalizeFirstLetter: str => str.charAt(0).toUpperCase() + str.slice(1)
  }
})

이것은 글로벌 믹스 인입니다. 이 모든 구성 요소에는 capitalizeFirstLetter메서드가 있으므로 this.capitalizeFirstLetter(...)구성 요소 메서드에서 호출 하거나 capitalizeFirstLetter(...)구성 요소 템플릿에서 와 같이 직접 호출 할 수 있습니다 .

작업 예 : http://codepen.io/CodinCat/pen/LWRVGQ?editors=1010

https://vuejs.org/v2/guide/mixins.html 에서 문서를 참조하십시오.


잘 했어! 감사!
Alexey Shabramov

20
이 답변에 mixin 함수를 자체 전용 파일에 저장하는 방법과 main.js에서 가져 오는 방법과 같은 자세한 내용을 갖는 것이 좋을 것입니다.
Alexis.Rolland

인스턴스 capitalizeFirstLetter에서 어떻게 사용할 수 const vm = new Vue()있습니까? 때문에 vm.capitalizeFirstLetter하지 않습니다 작동합니다.
Marcelo Rodovalho

모든 구성 요소가 capitalizeFirstLetter믹스 인의 함수를 참조 합니까 아니면 자체 복사본을 가지고 있습니까? 모든 구성 요소에 액세스 할 수 있어야하지만 관련이없는 기능을 저장할 위치를 찾고 있습니다 (vuex 스토리지에 저장하기 위해 서버에서 데이터 가져 오기)
Daniel F

감사 ! 컴포넌트에서는 잘 작동하지만 "store.js"에서는 작동하지 않습니다. "console.log"를 사용자 정의하는 믹스 인이 있습니다. "log : str => console.log ( '% c'+ str + '', 'background : #aaa; color : #fff; padding : 5px; border- 반경 : 5px ') ". store.js에서 어떻게 사용할 수 있습니까?
bArraxas

66

그렇지 않으면 도우미가 플러그인으로 작동하도록 만들 수 있습니다.

import Vue from 'vue'
import helpers from './helpers'

const plugin = {
  install () {
    Vue.helpers = helpers
    Vue.prototype.$helpers = helpers
  }
}

Vue.use(plugin)

당신에 helper.js당신의 기능 수출, 이러한 방법 :

const capFirstLetter = (val) => val.charAt(0).toUpperCase() + val.slice(1);
const img2xUrl = (val) => `${val.replace(/(\.[\w\d_-]+)$/i, '@2x$1')} 2x`;

export default { capFirstLetter, img2xUrl };

또는

export default { 
  capFirstLetter(val) {
    return val.charAt(0).toUpperCase() + val.slice(1);
  },
  img2xUrl(val) {
    return `${val.replace(/(\.[\w\d_-]+)$/i, '@2x$1')} 2x`;
  },
};

그런 다음 다음을 사용하여 구성 요소의 어디에서나 사용할 수 있어야합니다.

this.$helpers.capitalizeFirstLetter()

또는 다음을 사용하여 애플리케이션의 모든 위치에서

Vue.helpers.capitalizeFirstLetter()

https://vuejs.org/v2/guide/plugins.html 문서에서 이에 대해 자세히 알아볼 수 있습니다.


helpers.vue의 내용을 나열하십시오
Marius

Vue 스토어에 액세스하는 방법에 대한 예를 포함 해 주시겠습니까? this. $ store는 구성 요소에서 작동하지만 믹스 인에서는 작동하지 않습니다.
Marius

1
helpers.js의 내용은 질문에
Hammerbot

9

새 믹스 인 만들기 :

"src / mixins / generalMixin.js"

Vue.mixin({
  methods: {
    capitalizeFirstLetter(str) {
        return str.charAt(0).toUpperCase() + str.slice(1);
    }    
  }
})

그런 다음 다음과 같이 main.js로 가져옵니다.

import '@/mixins/generalMixin'

이제부터는 this.capitalizeFirstLetter(str)구성 요소 스크립트 내에서 또는 this템플릿 없이 기능을 사용할 수 있습니다 .

this메인 Vue 인스턴스에 메서드를 혼합했기 때문에 사용해야 합니다. 제거 this하는 방법 이 아마도 틀에 얽매이지 않는 것을 포함 할 수 있다면 , 이것은 적어도 당신의 프로젝트에 대한 미래의 Vue 개발자가 이해하기 쉬운 기능을 공유 하는 문서화 된 방법 입니다.


1

Webpack v4 사용

가독성을 위해 별도의 파일을 만듭니다 (플러그인 폴더에 내 파일을 놓았습니다). @CodinCat 및 @digout 응답에서 재현

//resources/js/plugins/mixin.js
import Vue from 'vue'

Vue.mixin({
    methods: {
      capitalizeFirstLetter: str => str.charAt(0).toUpperCase() + str.slice(1),
      sampleFunction(){
        alert('Global Functions')
      }
    }
  })

그런 다음 main.js 또는 app.js 파일에서 가져옵니다.

//app.js
import mixin from './plugins/mixin' 

용법:

전화 this.sampleFunction()또는this.capitalizeFirstLetter()


1

렌더링 할 때 데이터 형식이 지정되는 방식에만 관련된 경우 전역 필터를 사용하십시오. 다음은 문서 의 첫 번째 예입니다 .

{{ message | capitalize }}
Vue.filter('capitalize', function (value) {
  if (!value) return ''
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})

0

좋은 질문입니다. 내 연구에서 나는 vue-inject가 이것을 가장 좋은 방법으로 처리 할 수 ​​있음을 발견했습니다. 표준 vue 구성 요소 논리 처리 방법과 별도로 유지되는 많은 함수 라이브러리 (서비스)가 있습니다. 내가 선택한 것은 컴포넌트 메소드가 서비스 함수를 호출하는 위임자가되는 것입니다.

https://github.com/jackmellis/vue-inject


-5

'store'와 마찬가지로 main.js 파일에서 가져 오면 모든 구성 요소에서 액세스 할 수 있습니다.

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  store,
  router,
  render: h => h(App)
})

11
구성 요소에서 사용하는 방법을 보여주는 답변을 완성 할 수 있습니까?
JeanValjean
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.