I am using nuxt.js. I have a helper.js script inside plugins folder which has a simple Test() function. Now how can I can call the Test() method inside pages which is in helper.js file.
helper.js file:
export default function Test() {
return 'This is test'
}
to access your global methods entire application:
1-create ./plugins/helpers.js .
2-edit ./plugins/helpers.js :
import Vue from 'vue'
Vue.mixin({
methods:{
mySpecialMethod(value){
console.log(value)
},
}
})
3-edit ./nuxt.config.js :
plugins: [
...
{ src: '~/plugins/helpers' },
...
],
now you can access your global method by:
this.mySpecialMethod()
Using the inject method
There is actually an easy way to do this by using the 'inject' method.
As described in the docs...
The plugins directory contains JavaScript plugins that you want to run before instantiating the root Vue.js Application. This is the place to add Vue plugins and to inject functions or constants. Every time you need to use Vue.use(), you should create a file in plugins/ and add its path to plugins in nuxt.config.js.
in your plugin simply use inject like this:
export default ({ app }, inject) => {
inject('myInjectedFunction', (string) => console.log('That was easy!', string))
}
and in your components you can use it as follows:
export default {
mounted(){
this.$myInjectedFunction('works in mounted')
},
asyncData(context){
context.app.$myInjectedFunction('works with context')
}
}
"Manual" injection
If you plan on injecting something yourself check out the Vue Docs on Adding Instance properties
There may be data/utilities you’d like to use in many components, but you don’t want to pollute the global scope. In these cases, you can make them available to each Vue instance by defining them on the prototype
Vue.prototype.$appName = 'My App'
And prefix these injected properties with '$'...
$ is a convention Vue uses for properties that are available to all instances. This avoids conflicts with any defined data, computed properties, or methods.
If you just want to use the code in your components (pages), you only need to import and use the method:
TestPage.vue
<template>
<div>
<h1>{{ getTest }}</h1>
</div>
</template>
<script>
import test from '~/plugins/helper.js'
export default {
computed: {
getTest () {
return test()
}
}
}
</script>
Hello you can inject the function globally into Vue doing the following:
./plugins/myPluging.js
import Vue from 'vue'
Vue.prototype.$nameOfMyPlugin = (args) => {
// Code here
}
Them in all your components you can access it this way:
./components/myComponent.vue
<script>
export default {
name: 'c',
mounted () {
this.$nameOfMyPlugin('something useful')
}
}
</script>
And that's it :) hope this helps.
-- Reference: https://nuxtjs.org/guide/plugins/#inject-in-root-amp-context
Below is a a custom js plugin that I have used in one of my nuxt projects.
create your file inside the plugins folder, and make your own function as below
export default (context, inject) => {
const formatDate = (dateTime) => {
if (typeof(dateTime) === 'undefined' || dateTime === null) {
return null;
}
let tempDate = new Date(dateTime);
tempDate.setMinutes(tempDate.getMinutes() -
tempDate.getTimezoneOffset());
tempDate = tempDate.toISOString().slice(0, 16);
return tempDate;
}
// Inject $hello(msg) in Vue, context and store.
inject('formatDate', formatDate)
// For Nuxt <= 2.12, also add 👇
context.$formatDate = formatDate
}
Add the plugin to nuxt.config.js and you will be able to use it globally.
myPlugin.js
export default (_, inject) => {
const myFuncA = value => return value;
const myFuncB = value => return myFuncA(1) + value;
inject('myPlugin', { myFuncA, myFuncB }
)
nuxt.config.js
plugins[
'#/plugin/myPlugin.js'
]
myComponent.vue
created(){
console.log( this.$myPlugin.funcA(2) );
}
in myPlugin.js, instead of "_" can use some public nuxt variables like {$config}
Related
I'm using Nuxtjs 2.15.4 and I wanna revise my Utils. Right now I'm using a mixin as my utils but I wanna do something like this:
import {func1 , func3} from '~/plugins/mixins/utils.js'
export default{
// ------------
methods:{
myMethod(){
this.func1()
},
}
}
I also want my utils be like a mixin so I can have access to this. ; because I use this to access store or $router or other methods and computed data in my utils.js .
Is it possible at all?
You could create a plugin and include this in the nuxt.config.js file where you 'inject' objects or methods. Now you can also access the (store) context.
export default ({ app }, inject) => {
/* Here we inject the method 'func1' */
inject('func1', (params) => console.log('This is func1', params))
}
and then you can use it like this
methods: {
myMethod() {
this.$func1()
}
}
Here you can read more about inject
I am trying to use bugsnagClient and its notify method in plugins/axios.js I have this code in plugins/bugsnag.js
import Vue from "vue"
import bugsnag from "#bugsnag/js"
import bugsnagVue from "#bugsnag/plugin-vue"
// const bugsnagClient = bugsnag(`${process.env.BUGSNAG_API_KEY}`)
var bugsnagClient = bugsnag({
apiKey: "",
notifyReleaseStages: ["production"]
})
bugsnagClient.use(bugsnagVue, Vue)
I want to attach a method to app or context as
export default ({ app }, inject) => {
function bugsnagNotify(error) {
return bugsnagClient.notify(new Error(error))
}
// Set the function directly on the context.app object
app.bugsnagNotify = bugsnagNotify
}
And I want to use it in plugins/axios.js
export default function({ store, app }) {
if (store.getters.token) {
console.log(app.bugsnagNotify("ss"))
app.$axios.setToken(store.getters.token, "Bearer")
} else {
//app.$bugsnag.notify(new Error("Bearer tooken is missing in Axios request."))
}
}
In this file, when I do console.log for just app
I can see bugsnagNotify: ƒ bugsnagNotify(error)
but when I call app.bugsnagNotify("error") I only get error such as VM73165:37 TypeError: app.bugsnagNotify is not a function
I have also tried this in plugins/bugsnag.js
export default (ctx, inject) => {
inject('bugsnag', bugsnagClient)
}
I only get an error as
app.$bugsnag.notify(new Error("Bearer tooken is missing in Axios request."))
If you are injecting into context inside one plugin and want to use that function inside another, you need to make sure that the plugin in which you are injecting comes first inside nuxt.config.js
...
plugins: [
'~/plugins/bugsnag.js',
'~/plugins/axios.js'
],
...
I want to create a plugin for Nuxtjs to log everything I want only in client mode, something like this :
// ~/plugins/client-log.js
export default ({ app }, inject) => {
app.clog = string => console.log(string)
}
This plugin is working in components where I have access to context for example:
export default {
fetch({app}){
app.clog("some string")
}
};
But I want to be able to use it inside vuex (actions, mutations...). How can I do that?
Thanks in advance.
You're so close, you just need to change one thing:
// ~/plugins/client-log.js
export default ({ app }, inject) => {
inject('clog', string => console.log(string))
}
Then you're able to call it like:
export default {
fetch({app}){
// Note: inject will automatically prefix with a "$"
app.$clog("some string")
},
mounted() {
// this.$clog can also be accessed within vuex
this.$clog("I'm in a component")
}
};
Am from Angular2 whereby i was used to services and injection of services hence reusing functions how do i achieve the same in vuejs
eg:
I would like to create only one function to set and retrieve localstorage data.
so am doing it this way:
In my Login Component
this.$axios.post('login')
.then((res)=>{
localstorage.setItem('access-token', res.data.access_token);
})
Now in another component when sending a post request
export default{
methods:{
getvals(){
localstorage.getItem('access-token') //do stuff after retrieve
}
}
}
Thats just one example, Imagine what could happen when setting multiple localstorage items when retrieving one can type the wrong key.
How can i centralize functionality eg: setting token(in angular2 would be services)
There are a few different ways to share functionality between components in Vue, but I believe the most commonly used are either mixins or custom modules.
Mixins
Mixins are a way to define reusable functionality that can be injected into the component utilizing the mixin. Below is a simple example from the official Vue documentation:
// define a mixin object
var myMixin = {
created: function () {
this.hello()
},
methods: {
hello: function () {
console.log('hello from mixin!')
}
}
}
// define a component that uses this mixin
var Component = Vue.extend({
mixins: [myMixin]
})
var component = new Component() // => "hello from mixin!"
Custom module
If there are a lot of shared functionality with a logical grouping it might make sense to instead create a custom module, and import that where you need it (like how you inject a service in angular).
// localStorageHandler.js
const localStorageHandler = {
setToken (token) {
localStorage.setItem('access-token', token)
},
getToken () {
localstorage.getItem('access-token')
}
}
export default localStorageHandler
And then in your component:
// yourcomponent.vue
import localStorageHandler from 'localStorageHandler'
export default{
methods:{
getvals(){
const token = localStorageHandler.getToken()
}
}
}
Modules are using the more modern syntax of JavaScript, which is not supported in all browsers, hence require you to preprocess your code. If you are using the vue-cli webpack template it should work out of the box.
How can I load my static data in a single location within a nuxt/vue app?
Ideally I would have a JSON file holding all this data which would get loaded into vuex and would be accessible anywhere...
I've been suggested 2 options, but I don't find them clean...
When using the webpack template (not webpack-simple), you can use environment variables for that: http://vuejs-templates.github.io/webpack/env.html.
Alternatively, you can always just create some file - constants.js - anywhere in your project folder, which you use to store your static data (e.g. export const API_URL = 'https:/my-api.com' ).
Import the data from that file anywhere you need it (e.g. import { API_URL } from 'path/to/constants' ).
I've found an elegant solution using vue prototype
Hence with Nuxt.js
1) Create a plugin at ~/plugins/globals.js
import Vue from 'vue'
import globals from '~/globals.json'
import _get from 'lodash/get'
Vue.prototype.$g = (key) => {
let val = _get(globals, key, '')
if (!val) console.warn(key, ' is empty in $g')
return val || key
}
2) Create your json file at ~/global.json
{
"website_url": "https://www.company.com",
"social": {
"facebook": {
"url": "https://www.facebook.com/company"
},
"twitter": {
"url": "https://www.twitter.com/company"
}
}
}
3) Use these in every .vue file
<template>
<div>
<p>URL: {{ $g('website_url') }}</p>
<p>Facebook: {{ fburl }}</p>
<p><a :href="$g('social.twitter.url')">twitter</a></p>
</div>
</template>
<script>
export default {
data () {
return {
fburl: this.$g('social.facebook.url')
}
}
}
</script>
I found one easiest way to set configs (json) file and and use in any component.
Steps -
Create setting.json file in root directory.
in middleware, create a file settings.js (or keep any name) and paste this code
import settings from '../settings.json'
export default function ({ store, route, redirect, req}) {
process.env = settings
}
3 in nuxt.config.js - add settings in
router: {
middleware: ['users', 'settings']
},
uses -
In any component or page -
data(){
return {
settings: process.env
}
},
Now you can use settings anywhere in component.