How to isolate reusable small functions in vuejs - javascript

I have a function that let's say generates a random string for generating a token. I have this function in my methods:{} and I use it in my div without any problem.
But I am trying to put this function in it's own separate file so I can import it for future use, so I put a functions.js file inside my src like this:
// /src/functions.js
export default {
// generate tokes
tokenGenerator () { ... }
}
And in my src/components/foo.vue I am importing this file (no issues with importing)
<template>
<div> {{ tokenGenerator }} </div>
</template>
<script>
import tokenGenerator from '../../functions'
export default {
data() {
return ;
}
}
</script>
This should work, but it doesn't. Importing is not the issue, but something else.. the console error shows me that It can not find function tokenGenerator

For one, you seem to be trying to import a single function, but tokenGenerator in your code is a reference to the whole object exported in your functions file.
Secondly, you cannot access plain javascript functions using Vue interpolation {{ ... }}. The template can only reference functions defined as methods on the related Vue instance.
You can use a mixin to do what you want:
// /src/functions.js
export default {
methods: {
// generate tokens
tokenGenerator () { ... }
}
}
<!>
<template>
<div>{{ tokenGenerator }} </div>
</template>
<script>
import mixinFuncs from '../../functions'
export default {
mixins: [ mixinFuncs ],
}
</script>
Here's the documentation on mixins.
If you simply need access to the tokenGenerator function in your Vue script, then you can export it directly and import it:
// /src/functions.js
// generate tokens
export const tokenGenerator = () => {
//...
}
<!>
<template>
<div> {{ token }} </div>
</template>
<script>
import { tokenGenerator } from '../../functions'
export default {
data() {
return {
token: tokenGenerator()
}
}
}
</script>
Here's a working example.

Export it in this way in functions.js:
export class util {
static tokenGenerator() {
//do your stuff here
}
}
In foo.vue:
<template>
<div>{{ tokenGenerator }} </div>
</template>
<script>
import { util } from '../../functions';
export default {
data() {
return {
textData: util.tokenGenerator
}
}
}
</script>

Related

How to use plain javascript variables in vue 3 component?

I have a javascript file with some variables and I want to use them in a vue component like this:
<template>
<div> Hello {{ personData.name }} {{ personData.last }} </div>
<button #click="signOut"> Sign Out </button>
</template>
<script>
import { personData } from '<path>'
export default {
...
methods: {
signOut() {
personData.signed_in = false;
}
}
}
</script>
JS file:
export var personData = {
name: '<name>',
last: '<last>',
signed_in: true,
}
It says personData is undefined but obviously it isn't, and also that it was accessed but not defined on instance. I'm new to Vue so I have no idea what I'm doing wrong. Also its important that they are global and not part of the component
Made nothing appear on the page at all
The problem is, you are importing a variable and just using it inside a Vue instance.
VueJS has to know which are reactive data so that it can update the DOM based on its value.
So, you make the following changes to make it work:
<template>
<div> Hello {{ personData.name }} {{ personData.last }} </div>
<button #click="signOut"> Sign Out </button>
</template>
<script>
import { personData } from './presonalData.js'
export default {
data () {
return {
personData //register as reactive data
}
},
methods: {
signOut() {
personData.signed_in = false;
}
}
}
</script>

How to call an imported function in the template?

Consider the following code that makes use of a method and an imported function:
<template>
<div>
{{sayHello()}}
{{sayDate()}}
{{DateTime.now()}}
<div>
</template>
<script>
import {DateTime} from "luxon"
export default {
methods: {
sayHello() {
return "hello"
},
sayDate() {
return DateTime.now()
}
}
}
</script>
sayHello() works fine because it is defined in methods.
sayDate() is fine as well.
DateTime.now() in <template> fails with [Vue warn]: Property or method "DateTime" is not defined on the instance but referenced during render.
How should I call DateTime so that it is correctly addressed in <template>?
I agree with Boussadjra's recommendations, but if you really want to DateTime.now() in your template, you can import DateTime as data. Here is a similar example that I built.
ImportObjectToData.vue
<template>
<div class="import-object-to-data">
<div class="row">
<div class="col-md-6">
<span>{{ DataObject.getMessage() }}</span>
</div>
</div>
</div>
</template>
<script>
import DataObject from './data-object.js'
export default {
data() {
return {
DataObject
}
}
}
</script>
data-object.js
const DataObject = {
message: 'Hello from DataObject',
getMessage() {
return this.message;
}
}
export default DataObject;
It's not recommended to use methods for rendering purposes, instead of that you could use computed properties, for example in your case you could do :
<template>
<div>
{{sayHello}}
{{now}}
<div>
</template>
<script>
import {DateTime} from "luxon"
export default {
computed:{
sayHello() {
return "hello"
},
now(){
return DateTime.now()
}
}
}
</script>
Note that the computed properties are called without using ()

Call function from imported helper class in Vue.js component data

I am trying to call a JavaScript function from an imported helper class in my Vue.js component. I import my helper class in my component and try to use mounted() to call it and pass a paramter to the helper class.
I tried out some solutions from here, but didn't help:
Vue.js: Import class with function and call it in child component
https://forum.vuejs.org/t/how-to-use-helper-functions-for-imported-modules-in-vuejs-vue-template/6266
This is what I tried so far, any ideas?
I have a helper class myHelper.js:
export default myHelper {
myHelperFunction(param) {
return param;
}
}
I have a Vue component MyComponent.vue:
<template>
<v-text-field :rules="[myRule]"></v-text-field>
</template>
<script>
import myHelper from './myHelper.js';
export default {
name: 'MyComponent',
data() {
return {
myCls: new myHelper(),
myRule: this.callHelperFunction,
};
},
components: {
myHelper,
},
mounted() {
this.myCls.myHelperFunction();
},
methods: {
callHelperFunction(param) {
this.myCls.myHelperFunction(param);
}
},
};
</script>
You are not really exporting the class. It is a plain object. To export a class instead of an object do this:
// Notice the use of class keyword
export default class MyHelper {
myHelperFunction(param) {
return param;
}
}
Also, you do not need:
components: {
myHelper,
},
Rest of the code stays the same.

Can I require/import files for a ViewModel in Vue.js?

I'm using Vue.js for an MVVM project and I want to separate out the View and ViewModel as much as possible for code maintainability and testing.
Here is my Example.vue file:
<template>
<div>
<h1>Example: {{message}}</h1>
</div>
</template>
<script>
require('../ViewModels/Example');
export default {
data() {
return new Example();
}
}
</script>
Then here is the Example.js file:
class Example {
constructor() {
this.message = "Hello World";
}
}
But I get an Error: "ReferenceError: Example is not defined"
If I paste the Example class into my script tag it works fine but when I try importing or requiring it doesn't work.
Anyone have an idea why?
I figured it out.
I needed to import and export in a specific way so my Example.vue:
<template>
<div>
<h1>Example: {{message}}</h1>
</div>
</template>
<script>
import Example from '../ViewModels/Example';
export default {
data() {
return new Example();
}
}
</script>
and my Example.js class file:
export default class Example {
constructor() {
this.message = "Hello World";
}
}

vue.js passing data from parent single file component to child

Using single file architecture I'm trying to pass data (an object) from a parent component to a child:
App.vue
<template>
<div id="app">
<app-header app-content={{app_content}}></app-header>
</div>
</template>
<script>
import appHeader from './components/appHeader'
import {content} from './content/content.js'
export default {
components: {
appHeader
},
data: () => {
return {
app_content: content
}
}
}
</script>
appHeader.vue
<template>
<header id="header">
<h1>{{ app_content }}</h1>
</header>
</template>
<script>
export default {
data: () => {
return {
// nothing
}
},
props: ['app_content'],
created: () => {
console.log(app_content) // undefined
}
}
</script>
Seems to be such a trivial task and probably the solution is quite simple. Thanks for any advice :)
You're almost there.
In order to send the app_content variable from App.vue to the child component you have to pass it as an attribute in the template like so:
<app-header :app-content="app_content"></app-header>
Now, in order to get the :app-component property inside appHeader.vue you will have to rename your prop from app_component to appComponent (this is Vue's convention of passing properties).
Finally, to print it inside child's template just change to: {{ appContent }}

Categories