Vuejs component props as string - vue.js

I want to pass this prop as a string:
<list-view :avatar="pictures"></list-view>
But I think Vue thinks I am trying to call a method because I am getting these warnings:
[Vue warn]: Property or method "pictures" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
[Vue warn]: Invalid prop: type check failed for prop "avatar". Expected String, got Undefined.
How can I pass "pictures" as a string?
Vue.component('list-view', {
props: {
avatar: { type: String, required: true },
},
template: `<div>{{ avatar }}</div>`,
});
var app = new Vue({ el: '#app' });
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<list-view :avatar="pictures" ></list-view>
</div>

Right now, Vue is trying to find a variable named pictures to pass as the property value to the child component.
If you want to specify a string value in that inline expression, you can wrap the value in quotes to make it a string:
<list-view :avatar="'pictures'"></list-view>
Alternately, as #Zunnii answered below, if the value being passed is really just a static string, you can simply omit the v-bind colon shorthand:
<list-view avatar="pictures"></list-view>
This way, the avatar prop of the child component will be assigned the string value "pictures".

If you really want to pass static string, you can just pass string directly without v-bind
<div id="app">
<greeting text="world"></greeting>
</div>
then in JS file
Vue.component('greeting', {
props: ['text'],
template: '<h1>Hello {{ text }}!</h1>'
});
var vm = new Vue({
el: '#app'
});
JSFiddle => https://jsfiddle.net/dpLp4jk8/

:avatar="pictures" //vue treat pictures as a variable or computed properties
By default vue treat pictures as a variable or computed properties and vue search locally and doesn't find and throw an error. So what you have to do is tell vue externally that it is a string not a variable or computed properties. So enclose in quotes.
:avatar="'pictures'" // I guess it will work

In laravel we can pass string as shown below
function authUserCurrency(){
return '$';
}
<service :authusercurrency="'{!!authUserCurrency()!!}'"></services>
Vue.js Template
props:{authusercurrency:String},
OR
props:['authUserCurrency'],

In my case I needed to pass static string along with dynamic property value.
So did as below.
<home-card :title="'By' + post.author.name "></home-card>

Related

[Vue warn]: Property or method "Boston" is not defined on the instance but referenced during render

I'm setting up some props, as shown below.
Component 1 (Parent):
<template>
<div>
<span>{{agency1}}</span>
<span>{{workstation}}</span>
</div>
</template>
<script>
export default {
name: "work-station-view",
props: {
agency1: {
type: String
},
workstation: {
type: Number
}
},
data() {
return {};
}
};
</script>
Component 2 (Child):
<template>
<WorkStationView :workstation="1.1" :agency1="Boston" />
</template>
The workstation prop renders fine, but the agency1 prop doesn't show up at all. I get this message from Vue in the console:
[Vue warn]: Property or method "Boston" 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. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
I checked the docs, as it says to define it in data(), so I did a combination of all of these (probably more) to no avail:
// attempt 1
data() {
agency1 = this.agency1;
return {};
}
// attempt 2
data() {
return {
agency1 = this.agency1;
};
}
// attempt 3
data() {
return {
agency1: '';
};
}
If I use a number value for agency1 (<WorkStationView :workstation="1.1" :agency1="3" />), it shows! What is going on?
If you're using an inline string, you should skip the : or quote your string.
The : is short-hand for v-bind and is expected to be used with variables that you're binding when passing attributes from the parent component to the child. In this case, you don't have a variable called Boston in the parent context, and hence the error from Vue.
If all you want to do is use a constant string like Boston, just use it like
<WorkstationView :workstation="1.1" :agency="'Boston'" />
Alternatively, it would've also worked if you did the following:
<WorkstationView :workstation="1.1" agency="Boston" />
:agency1="Boston" is shorthand for v-bind:agency1="Boston". It attempts to bind a data property named Boston, but you don't have one defined. :agency1="3" works because 3 is a literal. If you were attempting to assign the literal string "Boston" to agency1, don't use the preceding colon:
<!--
<WorkStationView :agency1="Boston">
--> <!-- DON'T DO THIS -->
<WorkStationView agency1="Boston">

How to pass bound variables to a subcomponent? [duplicate]

I'm trying to pass php/laravel data to my component from a custom global variable. I've seen examples of this going into the new Vue({}) area directly but I haven't seen any way to pass this by going into right into the component
<script>
var itemData = //json object
</script>
<custom-component item-data="ITEMDATAVAR"></custom-component>
I should specify that I do have item-data in my component props. The issue is that I'm not sure how to tell my component's html that I'm passing the value of the variable itemData and not the string "itemData"
I think you are referring to dynamic props
<custom-component v-bind:item-data="ITEMDATAVAR"></custom-component>
or use the shorthand syntax
<custom-component :item-data="ITEMDATAVAR"></custom-component>
You should add the item-data to the props array like this:
Vue.component('custom-component', {
props: ['item-data'],
...
}
You can research this Vue.js example
Create a variable
new Vue({
el: '#el',
data: yourJsonObject
})
In you component you have to write about props
Vue.component('custom-component', {
props: ['item-data']
...
}
Pass the data to the component the same way
<custom-component item-data="ITEMDATAVAR"></custom-component>
I have not tested how it will work, guided by the documentation.

How do I get a literal expression from a custom directive in Vue.js 2?

I am trying to transfer a Vue 1.x custom directive to Vue 2.x and I can't find anywhere how to get my expressions again as a literal. Let's say this example is my custom directive:
<div v-custom="file.txt"></div>
In Vue1
Vue.directive('custom', function () {
console.log(this.expression)
})
will return "file.txt" as a string.
In Vue2
Vue.directive('custom', {
bind: function (el, binding) {
console.log(binding.expression)
}
})
will return
[Vue warn]: Property or method "file" is not defined on the instance
but referenced during render. Make sure to declare reactive data
properties in the data option
and
[Vue warn]: Error in render function: "TypeError: Cannot read property
'txt' of undefined"
This means my expression in Vue2 is no longer a string, but a variable. How do I get it to return a string now?
Simply wrap your text in single quotes to make it a string literal. However, as noted in your comment, if trying to access binding.expression, it will include the wrapping single quotes. Instead, you should use the binding.value property.
Template:
<div id="app">
<div v-custom="'file.txt'"></div>
</div>
Javascript:
Vue.directive('custom', {
bind: function (el, binding) {
console.log(binding.value)
}
})
new Vue({
el: '#app'
})
Sample Fiddle.

How to bind to attribute in Vue JS?

I got this error
Interpolation inside attributes has been removed. Use v-bind or the
colon shorthand instead. For example, instead of <div id="{{ val }}">,
use <div :id="val">.
on this line
<a href="/Library/#Model.Username/{{myVueData.Id}}">
It works in Angular 1. How do you do it in Vue?
In your template:
<a :href="href">
And you put href in data:
new Vue({
// ...
data: {
href: 'your link'
}
})
Or use a computed property:
new Vue({
// ...
computed: {
href () {
return '/foo' + this.someValue + '/bar'
}
}
})
Just complementing ... solve the interpolation error (simple solution, I am Junior front-end developer):
Example post object in a loop:
instead of
<a href="{{post.buttonLinkExt}}">
try this way
<a v-bind:href="post.buttonLinkExt">
Use javascript code inside v-bind (or shortcut ":") :
:href="'/Library/#Model.Username' + myVueData.Id"
and
:id="'/Library/#Model.Username' + myVueData.Id"
Update Answer
Some directives can take an “argument”, denoted by a colon after the directive name. For example, the v-bind directive is used to reactively update an HTML attribute:
<a v-bind:href="url"></a>
Here href is the argument, which tells the v-bind directive to bind the element’s href attribute to the value of the expression url. You may have noticed this achieves the same result as an attribute interpolation using href="{{url}}": that is correct, and in fact, attribute interpolations are translated into v-bind bindings internally.
Found in Google this topic when searching $attrib.
Question don't specify what value is used (maybe not defined before)
For ANY parent attribute or to FILTER it, use something like that:
<template>
<component
is="div"
v-bind="$attrs"
class="bg-light-gray"
>
EXAMPLE
</component>
</template>
This instruct to create specific, dynamic and context aware, wrapper:
v-bind="$attrs" instruct to take all sended params. Not needed to declare as param object in script.
Work even with valid html attribute like class
example above mix static class with parent and join it. Use ternary operator (x=1?x:y) to choose proper one.
bonus: by "is" you can dynamically set tag like header or secion instead of div
$attrs can be binded to any tag in component so this easily enable simple transmission for one tag dynamic attributes like you define class for <input /> but wrapper and actions are added in component
Source with description: https://youtu.be/7lpemgMhi0k?t=1307
you can either use the shorthand : or v-bind
<div>
<img v-bind:src="linkAddress">
</div>
new Vue({
el: '#app',
data: {
linkAddress: 'http://i3.kym-cdn.com/photos/images/newsfeed/001/217/729/f9a.jpg'
}
});
or for when you need more than just binding an attribute you can also do:
new Vue({
el: '#app',
data: {
finishedLink: ' Google '
}
});

In Vue 2 after passing props v-for does not get updated after items are removed

If I pass an array of objects using props in Vue 2 and on this array I use the v-for directive, view does not get updated if one of the array elements get removed.
This seems to work only if the v-for elements are declared as data, but my component needs to receive props...
In the example below you can see that the elements in the services array are indeed removed, but the v-for isn't triggered.
I'm pretty sure I'm doing here something wrong...
Vue.component('location-service-list', {
props: ['services'],
template: '<div>{{ services }}<div v-for="(service, index) in services">{{ service.id }} - {{ service.name }} <a #click.prevent="remove(index)">remove</a></div></div>',
methods: {
remove(index) {
this.services.splice(index, 1);
console.log(this.services);
},
}
});
const app = window.app = new Vue({
el: '#admin-app'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.8/vue.js"></script>
<div id="admin-app">
<location-service-list :services='[{"id":1,"name":"Test 1"},{"id":2,"name":"Test 2"}]'></location-service-list>
</div>
Try defining your servicesList inside the root component as follows:
const app = window.app = new Vue({
el: '#admin-app',
data: {
servicesList: [{"id":1,"name":"Test 1"},{"id":2,"name":"Test 2"}]
}
});
And your template as:
<div id="admin-app">
<location-service-list :services='servicesList'></location-service-list>
</div>
Now it will work alright without any issues. It was not working earlier because you passed it as a constant / immutable object (JSON string in the parent template which always evaluates to the same value whenever the parent template re-renders).
Technically you are not supposed to change objects passed via props in the child component. If you do the same to a string value that is passed via props, you will get an error message like:
[Vue warn]: Avoid mutating a prop directly...
To process this remove action from parent component, you may refer to the answer under this question: Delete a Vue child component
The jsFiddle in that answer provides a way to send an event from child component to parent component, so that the appropriate child component can be deleted.