The problem is that I can't pass dynamic Pug variables to Vue component via attributes, if they're of "String" type. Vue considers the string that I'm trying to pass as a name of Vue property.
The problem
template.pug
- var pugVariable = 'John';
my-component(v-bind:name= pugVariable)
*MyComponent.Vue*
export default {
name: 'MyComponent',
props: {
name: {
type: String
}
}
}
I get an error: "Property or method "John" is not defined on the instance but referenced during render.", which means, as far as I understand, that Vue considers string that is in pugVariable as a name of Vue property.
The question
So, the question is: now to persuade Vue to treat this variable as a string?
What I've already tried:
I tried to pass an object literal instead of string, as follows:
my-component(v-bind:name= {value: pugVariable})
It works, but we lose the ability to check the type of passed value, so I don't like this solution.
I've got an answer earlier that whoever:)
As described here https://stackoverflow.com/a/45175556/7473709, in case if we want just to pass static string, we have to simply get rid of v-bind: prefix, so it looks like as follows:
my-component(name= {value: pugVariable})
Related
I have an existing Vue component with multiple props which are declared in an array without types:
props: ["prop1", "prop2"]
I'd now like to add a new prop with the type Boolean. This requires me to change the array to an object and set the type for the existing properties.
props: {
"prop1": ???,
"prop2": ???,
"newProp": Boolean
}
What type do I need to choose in place of ??? so that nothing is changed in regards to those props? I assume Object, but I can't find any documentation to confirm that.
It depends on what prop1 and prop2 will be, based on the docs you can pass null or undefined to make it any type.
props: {
"prop1": null,
"prop2": null,
"newProp": Boolean
}
Or if you already know what type of prop1 and prop2 will be, you can pass a type instead.
The type can be one of the following native constructors:
String
Number
Boolean
Array
Object
Date
Function
Symbol
From: https://v2.vuejs.org/v2/guide/components-props.html#Type-Checks
I want to know what is the difference in VueJs between these two types of declaration :
data() {
return {
foo = 'bar'
}
}
and this :
created() {
this.foo = 'bar'
}
I know that I an access both using 'this' in or in methods.
Also, if the returned object in data() is saved in "memory" of the component, where does the object declared in created() is saved? are they in different scopes?
Also, I know that to fetch data, the fetcher lands in created() and then updates the data object, but this question is specifically about the differences between the two ways of declarations i mentioned
Is there any differences in the background?
You can read more about vue data here.
Vue will recursively convert its ($data) properties into getter/setters to make it “reactive”..
created() {
this.foo = 'bar'
}
Declaring like above, you won't be able to watch the attributes.
You can check this example out, watch function isn't fired with the attribute being not defined in data()
If I bind a class:
:class="['string-class', {'test-case-class': true}]
It will add both of the classes above, but how can I evaluate the above to a string form. I need to do this as a third party component I am using only accepts strings for a class property.
Edit
I want the above to be able to output: 'string-class test-case-class' just as you would see on a component that :class would be on.
You can bind the class to a function, rather than literals. For instance:
:class="getClasses"
where the function is computed:
computed: {
getClasses: function() {
return 'string-class test-case-class'
},
You can then use it just like any other computed function:
{{ getClasses }}
Should show the string literal 'string-class test-case-class'.
I'm not new to Vue.js, but I'm going through the docs again, trying to pick up on anything I missed the first time. I came across this statement in basic example section of using computed properties:
You can data-bind to computed properties in templates just like a normal property. Vue is aware that vm.reversedMessage depends on vm.message, so it will update any bindings that depend on vm.reversedMessage when vm.message changes. And the best part is that we’ve created this dependency relationship declaratively: the computed getter function has no side effects, which makes it easier to test and understand.
The part about we’ve created this dependency relationship declaratively: the computed getter function has no side effects, isn't clear to me. I do understand that a side effect is some action happening that is not directly related to the pure intentions of the function, but I'm not clear how it's being used in this statement.
Could someone explain further what the opposite could be? What are the potential side effects that could be happening?
The term side effect here refers to any data mutations performed in the computed property getter. For example:
export default {
data() {
return {
firstName: 'john',
lastName: 'doe',
array: [1,2,3]
}
},
computed: {
fullName() {
this.firstName = 'jane'; // SIDE EFFECT - mutates a data property
return `${this.firstName} ${this.lastName}`
},
reversedArray() {
return this.array.reverse(); // SIDE EFFECT - mutates a data property
}
}
}
Notice how fullName mutates firstName, and reversedArray mutates array. If using ESLint (e.g., from Vue CLI generated project), you'd see a warning:
[eslint] Unexpected side effect in "fullName" computed property. (vue/no-side-effects-in-computed-properties)
[eslint] Unexpected side effect in "reversedArray" computed property. (vue/no-side-effects-in-computed-properties)
demo
in vue guide doc, I have looked at the documentation about prop validation :
The type can be one of the following native constructors:
String
Number
Boolean
Function
Object
Array
In addition, type can also be a custom constructor function and the assertion will be made with an instanceof check.
so, how can I use the instanceof operator to achieve parameter custom type checking ?
you can use custom type like:
props: {
file: { type: File, required: true }
}