How to call an imported function in the template? - javascript

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 ()

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>

Vue Component Event triggers but doesnt do anything

This is my code:
Tablecomponent:
<template>
<rowcomponent #reloadTable="fetchData(pagination.current_page)" :item_data="item" :isDOMadd="false" :workflowoffer_id="workflowoffer_id"></rowcomponent >
</template
<script>
import rowcomponent from "./rowcomponent";
export default{
methods :{
fetchData(url){
console.log('test');
},
components: {
rowcomponent,
},
}
}
</script>
Rowcomponent:
<script>
export default{
methods :{
safeData(){
console.log('safe');
this.$emit('reloadTable');
}
},
}
</script>
Console Output:
safe
The Vue Event gets triggered (vue-devtool) but it doesnt do anything
i Know it should work, but it doesnt. Has anyone some solutions or tips what it could be.
UPDATE: So i found the error, but i cant explain it ^^
I add this line in the Tablecomponent in export default {...}:
name: "TableComponent",
and now it works**
Since you didn't share your row-component completely I made a working example. Can you please look at this and compare with yours ?
Parent component:
<template>
<div id="app">
<rowcomponent #reloadTable="reloadTable" />
</div>
</template>
<script>
import rowcomponent from "./components/rowcomponent";
export default {
name: "App",
methods: {
reloadTable () {
console.log("test")
}
},
components: {
rowcomponent
}
};
</script>
rowcomponent
<template>
<div class="hello">
click me to see the results
<button #click="safeData"> click me </button>
</div>
</template>
<script>
export default {
name: "rowcomponent",
methods :{
safeData(){
console.log('safe');
this.$emit('reloadTable');
}
}
};
</script>
Output will be : safe and test

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

How to isolate reusable small functions in vuejs

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>

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