Vue.js - Rende le funzioni di supporto disponibili a livello globale per i componenti a file singolo


101

Ho un progetto Vue 2 che ha molti (50+) componenti a file singolo . Uso Vue-Router per il routing e Vuex per lo stato.

C'è un file, chiamato helpers.js , che contiene un mucchio di funzioni generiche, come la capitalizzazione della prima lettera di una stringa. Questo file ha questo aspetto:

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

Il mio file main.js inizializza l'app:

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

Il mio file App.vue contiene il modello:

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

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

Quindi ho un sacco di componenti a file singolo, che Vue-Router gestisce la navigazione all'interno del <router-view>tag nel modello App.vue.

Ora diciamo che ho bisogno di utilizzare la capitalizeFirstLetter()funzione all'interno di un componente definito in SomeComponent.vue . Per fare ciò, devo prima importarlo:

<template>Some Component</template>

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

Questo diventa rapidamente un problema perché finisco per importare la funzione in molti componenti diversi, se non tutti. Questo sembra ripetitivo e rende anche il progetto più difficile da mantenere. Ad esempio, se voglio rinominare helpers.js, o le funzioni al suo interno, devo quindi entrare in ogni singolo componente che lo importa e modificare l'istruzione import.

Per farla breve: come faccio a rendere disponibili globalmente le funzioni all'interno di helpers.js in modo da poterle chiamare all'interno di qualsiasi componente senza doverle prima importare e poi anteporre thisal nome della funzione? Fondamentalmente voglio essere in grado di farlo:

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

Potresti usare un mixin globale, ma dovresti usare this.
Bert

2
Hai considerato di esporre i tuoi helper come filtri in modo che possano essere utilizzati direttamente nei tuoi modelli senza bisogno di importarli? Questa è la strategia che sto prendendo e sta funzionando bene finora.
David Weldon

Risposte:


155

all'interno di qualsiasi componente senza dover prima importarli e quindi anteporre questo al nome della funzione

Quello che hai descritto è mixin .

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

Questo è un mixin globale. con questo TUTTI i tuoi componenti avranno un capitalizeFirstLettermetodo, quindi puoi chiamare this.capitalizeFirstLetter(...)dai metodi del componente o puoi chiamarlo direttamente come capitalizeFirstLetter(...)nel modello del componente.

Esempio di lavoro: http://codepen.io/CodinCat/pen/LWRVGQ?editors=1010

Consulta la documentazione qui: https://vuejs.org/v2/guide/mixins.html


Ben fatto! Grazie!
Alexey Shabramov

20
Sarebbe bello avere più dettagli in questa risposta come come si memorizza la funzione mixin nel proprio file dedicato e come la si importa in main.js?
Alexis.Rolland

Come posso utilizzare capitalizeFirstLetterda const vm = new Vue()un'istanza? Perché vm.capitalizeFirstLetternon funziona.
Marcelo Rodovalho

Tutti i componenti faranno riferimento alla capitalizeFirstLetterfunzione nel mixin o ne avranno una propria copia? Sto cercando un posto in cui memorizzare una funzione che dovrebbe essere accessibile a tutti i componenti, ma per il resto non correlata a loro (recupera i dati da un server per archiviarli in un archivio vuex)
Daniel F

Grazie ! Funziona bene nei componenti ma non in "store.js". Ho un mixin che personalizza "console.log": "log: str => console.log ('% c' + str + '', 'background: #aaa; color: #fff; padding: 5px; border- raggio: 5 px ') ". Come posso usarlo in store.js per favore?
bArraxas

66

Altrimenti, potresti provare a far funzionare i tuoi helper come plugin:

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

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

Vue.use(plugin)

Nella tua helper.jsesportazione le tue funzioni, in questo modo:

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

o

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

Dovresti quindi essere in grado di usarli ovunque nei tuoi componenti usando:

this.$helpers.capitalizeFirstLetter()

o ovunque nella tua applicazione utilizzando:

Vue.helpers.capitalizeFirstLetter()

Puoi saperne di più su questo nella documentazione: https://vuejs.org/v2/guide/plugins.html


Elenca i contenuti di helpers.vue
Marius

Potresti includere un esempio su come accedere al negozio Vue? this. $ store funziona in componenti, ma non in un mixin.
Marius

1
Il contenuto di helpers.js è nella domanda
Hammerbot

9

Crea un nuovo mixin:

"src / mixins / generalMixin.js"

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

Quindi importalo nel tuo main.js come:

import '@/mixins/generalMixin'

D'ora in poi sarai in grado di utilizzare la funzione come this.capitalizeFirstLetter(str)all'interno dello script del tuo componente o senza thisin un modello.

Devi usare thisperché hai mescolato un metodo nell'istanza principale di Vue. Se ci sono modi per rimuoverlo thisprobabilmente implicherà qualcosa di non convenzionale, almeno questo è un modo documentato di condividere funzioni che sarà facile da capire per qualsiasi futuro sviluppatore Vue del tuo progetto.


1

Utilizzando Webpack v4

Crea un file separato per leggibilità (ho appena lasciato cadere il mio nella cartella dei plugin). Riprodotto dalle risposte di @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')
      }
    }
  })

Quindi importa nel tuo file main.js o app.js

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

UTILIZZO:

Chiama this.sampleFunction()othis.capitalizeFirstLetter()


1

Usa un filtro globale se riguarda solo il modo in cui i dati vengono formattati durante il rendering. Questo è il primo esempio nella documentazione :

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

0

Ottima domanda. Nella mia ricerca ho scoperto che vue-inject può gestirlo nel migliore dei modi. Ho molte librerie di funzioni (servizi) tenute separate dai metodi di gestione della logica dei componenti vue standard. La mia scelta è che i metodi dei componenti siano solo delegatori che chiamano le funzioni di servizio.

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


-5

Importalo nel file main.js proprio come "store" e potrai accedervi in ​​tutti i componenti.

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
puoi completare la risposta mostrando come usarlo in un componente?
JeanValjean
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.