Vue.js - Disponibilizando funções auxiliares globalmente para componentes de arquivo único

100

Eu tenho um projeto Vue 2 que tem muitos (50+) componentes de arquivo único . Eu uso o Vue-Router para roteamento e Vuex para o estado.

Existe um arquivo, chamado helpers.js , que contém várias funções de uso geral , como colocar a primeira letra de uma string em maiúscula. Este arquivo tem a seguinte aparência:

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

Meu arquivo main.js inicializa o aplicativo:

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')

Meu arquivo App.vue contém o modelo:

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

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

Então, tenho um monte de componentes de arquivo único, que o Vue-Router lida com a navegação dentro da <router-view>tag no modelo App.vue.

Agora, digamos que eu precise usar a capitalizeFirstLetter()função dentro de um componente definido em SomeComponent.vue . Para fazer isso, primeiro preciso importá-lo:

<template>Some Component</template>

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

Isso se torna um problema rapidamente porque acabo importando a função em muitos componentes diferentes, senão em todos eles. Isso parece repetitivo e também torna o projeto mais difícil de manter. Por exemplo, se eu quiser renomear helpers.js, ou as funções dentro dele, eu preciso ir para cada componente que o importa e modificar a instrução import.

Resumindo: como faço para tornar as funções dentro de helpers.js globalmente disponíveis para que eu possa chamá-las dentro de qualquer componente sem ter que primeiro importá-las e depois acrescentar thiso nome da função? Eu basicamente quero ser capaz de fazer isso:

<script>
export default {
    data() {
        return {
            myString = "test"
        }
    },
    created() {
         var newString = capitalizeFirstLetter(this.myString)
    }
}
</script>
Ege Ersoz
fonte
Você poderia usar um mixin global, mas teria que usar this.
Bert
2
Você considerou expor seus auxiliares como filtros para que eles possam ser usados ​​diretamente em seus modelos sem a necessidade de importá-los? Essa é a estratégia que estou adotando e está funcionando bem até agora.
David Weldon

Respostas:

152

dentro de qualquer componente sem ter que primeiro importá-los e, em seguida, acrescentar isso ao nome da função

O que você descreveu é mixin .

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

Este é um mixin global. com isso TODOS os seus componentes terão um capitalizeFirstLettermétodo, então você pode chamar this.capitalizeFirstLetter(...)de métodos de componente ou pode chamá-lo diretamente como capitalizeFirstLetter(...)no template de componente.

Exemplo de trabalho: http://codepen.io/CodinCat/pen/LWRVGQ?editors=1010

Veja a documentação aqui: https://vuejs.org/v2/guide/mixins.html

CodinCat
fonte
Agradável! Obrigado!
Alexey Shabramov
19
Seria bom ter mais detalhes nesta resposta, como como você armazena a função mixin em seu próprio arquivo dedicado e como você a importa em main.js?
Alexis.Rolland
Como posso usar a capitalizeFirstLetterpartir de uma const vm = new Vue()instância? Porque vm.capitalizeFirstLetternão funciona.
Marcelo Rodovalho
Todos os componentes farão referência à capitalizeFirstLetterfunção no mixin ou terão sua própria cópia dele? Estou procurando um lugar para armazenar uma função que deve ser acessível a todos os componentes, mas de outra forma não relacionada a eles (buscar dados de um servidor para armazenar em um armazenamento vuex)
Daniel F
Obrigado ! Funciona bem em componentes, mas não em "store.js". Eu tenho um mixin que customiza o "console.log": "log: str => console.log ('% c' + str + '', 'background: #aaa; color: #fff; padding: 5px; border- raio: 5px ') ". Como posso usá-lo no store.js, por favor?
bArraxas
65

Caso contrário, você pode tentar fazer com que seus ajudantes funcionem como um plugin:

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

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

Vue.use(plugin)

Em sua helper.jsexportação de funções, desta forma:

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 };

ou

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

Você deve ser capaz de usá-los em qualquer lugar em seus componentes usando:

this.$helpers.capitalizeFirstLetter()

ou em qualquer lugar em seu aplicativo usando:

Vue.helpers.capitalizeFirstLetter()

Você pode aprender mais sobre isso na documentação: https://vuejs.org/v2/guide/plugins.html

Hammerbot
fonte
Liste o conteúdo de helpers.vue
Marius
Você poderia incluir um exemplo de como acessar a loja Vue? this. $ store funciona em componentes, mas não em um mixin.
Marius
1
O conteúdo de helpers.js está em questão
Hammerbot
9

Crie um novo mixin:

"src / mixins / generalMixin.js"

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

Em seguida, importe-o para o main.js como:

import '@/mixins/generalMixin'

De agora em diante, você poderá usar a função como this.capitalizeFirstLetter(str)dentro do script de componente ou sem thisum modelo.

Você tem que usar thisporque misturou um método na instância principal do Vue. Se houver maneiras de removê- thislo, provavelmente envolverá algo não convencional, pelo menos é uma forma documentada de compartilhar funções que será fácil de entender para qualquer futuro desenvolvedor Vue para o seu projeto.

desenterrar
fonte
0

Ótima pergunta. Em minha pesquisa, descobri que o vue-inject pode lidar com isso da melhor maneira. Tenho muitas bibliotecas de funções (serviços) separadas dos métodos de manipulação de lógica de componente vue padrão. Minha escolha é que os métodos de componente sejam apenas delegadores que chamam as funções de serviço.

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

user3525949
fonte
0

Usando Webpack v4

Crie um arquivo separado para facilitar a leitura (apenas coloquei o meu na pasta de plug-ins). Reproduzido das respostas de @CodinCat e @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')
      }
    }
  })

Em seguida, importe em seu arquivo main.js ou app.js

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

USO:

Ligue this.sampleFunction()outhis.capitalizeFirstLetter()

DAVID AJAYI
fonte
-5

Importe-o no arquivo main.js como em 'store' e você poderá acessá-lo em todos os componentes.

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)
})
user2090357
fonte
11
você pode completar a resposta mostrando como usá-lo em um componente?
JeanValjean