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


100

У мене є проект 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')

Файл My App.vue містить шаблон:

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

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

Потім у мене є купа <router-view>однофайлових компонентів, до яких Vue-Router обробляє навігацію всередині тегу в шаблоні 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 або функції всередині нього, мені потрібно перейти до кожного окремого компонента, який його імпортує, та змінити оператор import.

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

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

Ви можете використовувати глобальний мікс, але вам доведеться використовувати this.
Берт

2
Ви розглядали можливість виставляти своїх помічників як фільтри, щоб їх можна було використовувати безпосередньо у ваших шаблонах без необхідності їх імпорту? Це стратегія, яку я приймаю, і вона досі добре працює.
Девід Уелдон,

Відповіді:


154

всередині будь-якого компонента без необхідності спочатку імпортувати їх, а потім додавати це до імені функції

Те, що ви описали, - це міксин .

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


Хороший! Дякую!
Олексій Шабрамов

20
Було б непогано мати більше деталей у цій відповіді, наприклад, як ви зберігаєте функцію mixin у власному виділеному файлі та як імпортуєте її в main.js?
Alexis.Rolland

Як я можу використовувати capitalizeFirstLetterз const vm = new Vue()примірника? Тому vm.capitalizeFirstLetterщо не працює.
Марсело Родовальо

Чи всі компоненти будуть посилатися на capitalizeFirstLetterфункцію в міксіні, або вони матимуть свою власну копію? Я шукаю місце для зберігання функції, яка повинна бути доступною для кожного компонента, але в іншому випадку не повинна бути пов’язана з ними (отримати дані із сервера для зберігання у сховищі vuex)
Даніель Ф,

Дякую ! Він добре працює в компонентах, але не в "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
Маріус,

Не могли б ви навести приклад того, як отримати доступ до магазину Vue? this. $ store працює в компонентах, але не в міксіні.
Маріус

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

Імпортуйте його у файл 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)
})

11
Ви можете заповнити відповідь, показуючи, як використовувати його в компоненті?
ЖанВальжан,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.