Vue.js - глобальная доступность вспомогательных функций для однофайловых компонентов.

У меня есть проект Vue 2, в котором много (50+) однофайловых компонентов . Я использую 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.

Теперь предположим, что мне нужно использовать функцию capitalizeFirstLetter() внутри компонента, определенного в SomeComponent.vue. Для этого мне сначала нужно импортировать его:

<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 или функции внутри него, мне нужно перейти к каждому компоненту, который его импортирует, и изменить оператор импорта.

Короче говоря: как сделать функции внутри helpers.js глобально доступными, чтобы я мог вызывать их внутри любого компонента без предварительного импортировать их, а затем добавить this к имени функции? Я в основном хочу уметь это делать:

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

person Ege Ersoz    schedule 05.03.2017    source источник
comment
Вы можете использовать глобальный миксин, но вам придется использовать this.   -  person Bert    schedule 05.03.2017
comment
Рассматривали ли вы возможность использовать своих помощников как фильтры, чтобы их можно было использовать непосредственно в вашем шаблоны без необходимости их импорта? Это моя стратегия, и пока она работает хорошо.   -  person David Weldon    schedule 06.03.2017


Ответы (7)


внутри любого компонента без необходимости сначала импортировать их, а затем добавить это к имени функции

Вы описали смесь.

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

person CodinCat    schedule 06.03.2017
comment
Хороший! Спасибо! - person Alexey Shabramov; 14.11.2017
comment
Было бы неплохо получить более подробную информацию в этом ответе, например, как вы храните функцию микширования в отдельном файле и как импортировать ее в main.js? - person Alexis.Rolland; 26.01.2019
comment
Как я могу использовать capitalizeFirstLetter из const vm = new Vue() экземпляра? Потому что vm.capitalizeFirstLetter не работает. - person Marcelo Rodovalho; 15.02.2019
comment
Все ли компоненты будут ссылаться на функцию capitalizeFirstLetter в миксине или у них будет ее собственная копия? Я ищу место для хранения функции, которая должна быть доступна для каждого компонента, но в остальном не связана с ними (получение данных с сервера для хранения в хранилище vuex) - person Daniel F; 11.07.2019
comment
Спасибо ! Он хорошо работает в компонентах, но не в store.js. У меня есть миксин, который настраивает console.log: log: str = ›console.log ('% c' + str + '', 'background: #aaa; color: #fff; padding: 5px; border-radius: 5px '). Как я могу использовать его в store.js, пожалуйста? - person bArraxas; 08.01.2020
comment
Кто не понимает, как звонить: нужно добавить Vue.mixin в ваш main.js, а не в файл .vue;) - person Falselight; 17.01.2020

В противном случае вы можете попробовать заставить своих помощников работать с плагином:

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

or

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

person Hammerbot    schedule 05.03.2017
comment
Перечислите содержимое helpers.vue - person Marius; 30.10.2019
comment
Не могли бы вы включить пример того, как получить доступ к магазину Vue? this. $ store работает в компонентах, но не в миксине. - person Marius; 30.10.2019
comment
Под вопросом содержание helpers.js - person Hammerbot; 30.10.2019
comment
Эй, я попробовал ваш метод, но почему я не могу получить доступ к Vue.helpers? this. $ helpers доступен. Мне нужен доступ из внешнего компонента. Любой, кто может мне помочь, будет признателен. Спасибо - person Rifqi; 21.09.2020

Создайте новый миксин:

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 в шаблоне. то есть:

<template>
    <div>{{ capitalizeFirstLetter('hello') }}</div>
</template>

Используя с <script />, вы должны использовать this, потому что вы смешали метод с основным экземпляром Vue. Если есть способы удаления this, это, вероятно, будет связано с чем-то нетрадиционным, по крайней мере, это задокументированный способ функций совместного использования, которые будут легко понятны любым будущим разработчикам Vue, участвующим в вашем проекте.

person digout    schedule 04.11.2019

Использование 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()

person DAVID AJAYI    schedule 15.02.2020

Используйте глобальный фильтр, если он касается только того, как данные форматируются при рендеринге. Это первый пример в документации:

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

Отличный вопрос. В своем исследовании я обнаружил, что vue-inject может справиться с этим наилучшим образом. У меня есть много библиотек функций (сервисов), которые хранятся отдельно от стандартных методов обработки логики компонентов vue. Я предпочитаю, чтобы методы компонентов были просто делегаторами, вызывающими служебные функции.

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

person user3525949    schedule 06.03.2017

Импортируйте его в файл main.js точно так же, как store, и вы сможете получить к нему доступ во всех компонентах.

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)
})
person user2090357    schedule 11.04.2017
comment
Можете ли вы заполнить ответ, показывающий, как использовать его в компоненте? - person JeanValjean; 24.05.2018