J'ai un projet Vue 2 comportant plusieurs (50+) composants à fichier unique . J'utilise Vue-Router pour le routage et Vuex pour l'état.
Il existe un fichier, appelé helpers.js , qui contient un ensemble de fonctions à usage général, telles que la mise en majuscule de la première lettre d'une chaîne. Ce fichier ressemble à ceci:
export default {
capitalizeFirstLetter(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
}
Mon fichier main.js initialise l'application:
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')
Mon fichier App.vue contient le modèle:
<template>
<navbar></navbar>
<div class="container">
<router-view></router-view>
</div>
</template>
<script>
export default {
data() {
return {
//stuff
}
}
}
</script>
J'ai ensuite un ensemble de composants à fichier unique, que Vue-Router gère pour accéder à l'intérieur de la balise <router-view>
dans le modèle App.vue.
Supposons maintenant que je dois utiliser la fonction capitalizeFirstLetter()
à l'intérieur d'un composant défini dans SomeComponent.vue . Pour ce faire, je dois d'abord l'importer:
<template>Some Component</template>
<script>
import {capitalizeFirstLetter} from '../helpers.js'
export default {
data() {
return {
myString = "test"
}
},
created() {
var newString = this.capitalizeFirstLetter(this.myString)
}
}
</script>
Cela devient rapidement un problème car je finis par importer la fonction dans de nombreux composants différents, voire tous. Cela semble répétitif et rend également le projet plus difficile à maintenir. Par exemple, si je veux renommer helpers.js, ou les fonctions qu’il contient, je dois ensuite entrer dans chacun des composants qui l’importent et modifier l’instruction d’importation.
Longue histoire courte: comment puis-je rendre les fonctions à l'intérieur de helpers.js globalement disponibles afin que je puisse appelez-les à l'intérieur de n'importe quel composant sans les importer, puis ajoutez le préfixe this
au nom de la fonction? Je veux fondamentalement pouvoir faire ceci:
<script>
export default {
data() {
return {
myString = "test"
}
},
created() {
var newString = capitalizeFirstLetter(this.myString)
}
}
</script>
à l’intérieur de n’importe quel composant sans avoir à les importer, puis ajouter ce nom au nom de la fonction
Ce que vous avez décrit est mixin .
Vue.mixin({
methods: {
capitalizeFirstLetter: str => str.charAt(0).toUpperCase() + str.slice(1)
}
})
Ceci est un mixin global. avec cela, TOUS vos composants auront une méthode capitalizeFirstLetter
, vous pourrez donc appeler this.capitalizeFirstLetter(...)
Exemple de travail: http://codepen.io/CodinCat/pen/LWRVGQ?editors=101
Voir la documentation ici: https://vuejs.org/v2/guide/mixins.html
Sinon, vous pourriez essayer de faire fonctionner vos assistants comme un plugin:
EDITER le 1er mars 2018:
La manière officielle de créer un plugin est de créer un objet avec une fonction d'installation:
import Vue from 'vue'
import helpers from './helpers'
const plugin = {
install () {
Vue.helpers = helpers
Vue.prototype.$helpers = helpers
}
}
Vue.use(plugin)
Vous devriez alors pouvoir les utiliser n'importe où dans vos composants en utilisant:
this.$helpers.capitalizeFirstLetter()
ou n'importe où dans votre application en utilisant:
Vue.helpers.capitalizeFirstLetter()
Vous pouvez en apprendre plus à ce sujet dans la documentation: https://vuejs.org/v2/guide/plugins.html
Ancienne réponse:
import helpers from './helpers';
export default (Vue) => {
Object.defineProperties(Vue.prototype, {
$helpers: {
get() {
return helpers;
}
}
});
};
Ensuite, dans votre fichier main.js
:
import Vue from 'vue'
import helpersPlugin from './helpersPlugin';
Vue.use(helpersPlugin);
Source : https://Gist.github.com/logaretm/56126af5867e391ea9507b462259caf
Importez-le dans le fichier main.js comme "store" et vous pourrez y accéder dans tous les composants.
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)
})
Excellente question. Dans mes recherches, j'ai trouvé que vue-inject peut gérer cela de la meilleure façon. De nombreuses bibliothèques de fonctions (services) sont séparées des méthodes de traitement logique des composants vue standard. Mon choix est que les méthodes de composant soient uniquement des délégataires qui appellent les fonctions de service.