I want to make enums work in in vue file.
I first define my enums in a js file
const Status= Object.freeze({
Normal: "normal",
Loading: "loading",
Error: "error",
Done: "done",
});
export default Status;
My main.vue file can't compile:
<template>
<div v-if="status == AudioCardStatus.Normal">
</template>
import Status from "./../enums/status"
Error is
Property or method "Status" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
I have already looked at another similar SO question but the solution seems to be to use Typescript.
You should add that imported object to the data option in order to be available for the template :
import Status from "./../enums/status"
export default{
data(){
return{
status:Status
}
}
}
First, You import it as Status but use it as AudioCardStatus, Also you need to asign it to property in your data.
Second, you should import it inside a script tag.
Third, you don't need the extra ./ this enough ../enums/status
Related
I have to import a gql file based on a data or computed property but I did not find any suitable working sample to do that. Please help me if you have a method in mind.
Example:
<script>
// if isEmployee is true import a file named isEmployee.gql else import isNotEmployee.gql
export default {
data(){
isEmployee: true
}
}
<script>
You could have a watcher, looking at your state and triggering a dynamic import. Not sure if Apollo will handle this properly tho (reactive).
watch: {
async isEmployee() {
const myGqlQuery = await import('~/apollo/queries/query.gql')
},
},
Here is how to make such thing: https://stackoverflow.com/a/67825061/8816585
I have a single file component in VueJS in which I import modules from other files like this:
<template>
//Some code here that call for the function "myFunction" and pass to it an object...
</template>
<script>
import Task from "../../APIs/Task"
import Status from "../../APIs/Status"
export default{
data(){
//Some code here...
},
methods: {
myFunction(someObject){
<!-- This is the part that does not work. Please see the error message below. -->
[someObject.moduleNameAsStoredOnObject].someFunctionThatBothModulesHave(someObject.payload)
}
}
}
</script>
This is the error I get in the console:
[Vue warn]: Error in v-on handler: "TypeError: [someObject.moduleNameAsStoredOnObject].someFunctionThatBothModulesHave is not a function"
As you can see, it seems that the string stored in someObject.moduleNameAsStoredOnObject is not translated to module name. Instead, the whole expression is taken literally as is.
In other places in my code I call modules' functions dynamically by using the following syntax:
ModuleName[functionNameAsString]
The idea is to create an general purpose method that takes both module name and payload as arguments and execute basic CRUD functions on different kind of objects, using dedicated module for each object type for separation of responsibilities.
Can anyone tell me if there is a way to call a module using its name from a variable, without using switch or if statements?
Thank you in advance,
Lior.
Thanks to #Bergi suggestion in the comments I was able to call modules dynamically using string variable. The solution was to create an object in my component data where its properties were named the same as the modules and their values were references to the modules themselves. Please see the code example below.
<template>
//Some code here that call for the function "myFunction" and pass to it an object...
</template>
<script>
import Task from "../../APIs/Task"
import Status from "../../APIs/Status"
export default{
data(){
return {
modules:{
Task: Task,
Status: Status
}
}
},
methods: {
myFunction(someObject){
!-- This works! -->
this.modules[someObject.moduleNameAsStoredOnObject].someFunctionThatBothModulesHave(someObject.payload)
}
}
}
</script>
At a glance, should the brackets be around just the module name?
someObject[moduleNameAsStoredOnObject].someFunctionThatBothModulesHave(someObject.payload)
The way you have it, [someObject.moduleNameAsStoredOnObject] is an array containing the module name. So you’re trying to call someFunctionThatBothModulesHave on an array.
I have an action that I want to trigger in my component hbs file if a conditional returns true. For example, If my component.js file looks like this:
export default Ember.Component.extend({
toggleMe: false,
actions: {
changeValue() {
return this.toggleProperty('toggleMe');
}
}
});
I want to call that changeValue action in my hbs file. This is the approach that I have tried in my component.hbs file:
{{#if model.property}}
{{action changeValue}}
{{/if}}
I'm getting an error
"Assertion Failed: Action passed is null or undefined"
First, you have a misspelled syntax in the component hbs. It should start with {{.
Second, your requirement can be done by using a Ember observer.
Created a live ember twiddle for your understanding.
Modify your component js file as,
import Ember from 'ember';
export default Ember.Component.extend({
toggleMe: false,
handleProperty : function()
{
this.send("changeValue");
}.observes('modeldata.property').on('didInsertElement'),
actions: {
changeValue() {
//console.log(this.get("toggleMe"));
this.toggleProperty('toggleMe');
//console.log(this.get("toggleMe"));
}
}
});
Also you may want to read about Ember computed properties and Ember observers.
You should not call an action in a template file.
There are computed properties for this.
Here is an example:
import { computed } from '#ember/object';
export default Ember.Component.extend({
toggleMe: false,
toggleComputedProperty: computed('toggleMe', function() {^
return this.toggleProperty('toggleMe');
}
}
});
Now you have the toggleComputedProperty availible to use in your template or in your logic.
As a rule of thumb: Never try to do logic/state changing in your template file. Use computed properties or other features for this.
The error is due to the misspelled syntax during your action call. You must use double quotes for your action name when invoking them.
{#if model.property}}
{{action "changeValue"}}
{{/if}}
I have also added an twiddle for your reference.
I'm building a website that is based on Nuxt TypeScript Starter template. I've created a dynamically routed page _id.vue inside of my pages folder and I want to have access to that id property inside of my TS class.
I can access it in my template by writing {{$route.params.id}} but when I try to reference $route inside of the class I get an error:
error TS2304: Cannot find name '$route'.
As a simple solution, try importing route from vue-router, like this:
<script lang="ts">
import Component from "vue-class-component"
import { Route } from "vue-router"
#Component({})
export default class RoutingExample extends Vue {
created() {
console.log(this.$route) // this should not throw TS errors now
}
}
</script>
Other solutions I think would require you to augment the Vue module, something similar to what you'd find here in the Vue docs.
More Vue + TypeScript examples can be found in this repo: https://github.com/jsonberry/vue-typescript-examples
better and the right solution for nuxtjs project to find current page URL or param just use
{{ $nuxt.$route.name }}
I was able to access route.params via fetch function, taking params from the context object that is passed to this function by default:
<script lang="ts">
import Component from "nuxt-class-component"
#Component({})
export default class RoutingExample extends Vue {
fetch ({ store, params }) {
console.log("params:", params.id);
...
}
}
</script>
but the caveat is that params would only be available in that fetch hook, not in other hooks such as created or mounted. So Jason answer is also valid
I currently have three steps in a form that I want to show sequentially, so I created three components - one for each step of the process.
My app.js file:
import LocationList from './components/LocationList.vue';
import ChooseTime from './components/ChooseTime.vue';
import ChooseMethod from './components/ChooseMethod.vue';
Vue.component('location-list', LocationList);
Vue.component('choose-time', ChooseTime);
Vue.component('choose-method', ChooseMethod);
let store = {
isVisible: {
steps: {
one: true,
two: false,
three: false,
}
}
};
new Vue({
el: '#app-order',
data: store,
router
});
Now, when my one and only route is called,
import VueRouter from 'vue-router';
let routes = [
{
path: '/order',
component: require('./views/Order.vue')
}
];
export default new VueRouter({
routes
});
all these components are being loaded properly. The issue is that when I try to v-show them one at a time:
Order.vue:
<template>
// ...
<location-list v-show="isVisible.steps.one"></location-list>
<choose-time v-show="isVisible.steps.two"></choose-time>
<choose-method v-show="isVisible.steps.three"></choose-method>
// ...
</template>
<script>
</script>
<style>
</style>
The error message I receive is:
[Vue warn]: Property or method "isVisible" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
But when I check within Vue's browser extension, isVisible is defined within the root element?
As you can see it is in the root-element, but not inside the Order view though.
Thanks for any help!
In Vue, child components do not have direct access to data defined in their parents. You have to pass the data down.
I think you would probably save yourself a little trouble if you just defined isVisible in Order.vue. However, if you want to leave it where it is, you need to pass it into the component.
One easy way to do that is to define isVisble as a property of Order.vue and then pass it through your router-view.
<router-view :is-visible="isVisible"></router-view>
There are other ways of passing props to routes that are defined in the router documentation.
The reason I say you would save your self some trouble defining isVisible in Order.vue is because whenever you want to change the values of your steps, you will need to do it at the root as you currently have it defined.