pass props through template - vue.js

Is it possible to pass custom config attributes through a template like this?:
<template v-slot:name="{data}" config="myConfig">{{data.field}}</template>
If possible how do I get access to that in the render method?
let a = this.$scopedSlots.name[0]['config']; //something like this

In your example, you pass custom config through props. You can access it in the render method with this.$props.
Take a look at the doc to see how to pass data to child component.

Related

Understanding when to use : , # and without any in vue

I have been going through an already existing code and trying to understand different parameters passed inside a tag.
<some-element
placeholder ="show first name"
:someElement = "true"
#error = "showErrorAlert"
>
so what exactly is the difference between these three parameters passed and when to pass them.
I am very new to vue so I am struggling a bit.
If any one needs any further information please let me know.
to communicate data between components in vuejs we have two concept: props and events.
vue props
vue custom events
read the two links above to learn about them from vue documentation but in short say we have a component structure like this:
<parent-component>
---- | <child-component>
data flow from parent to child is done with the help of props. that is when you're defining child-component you can set in its vue instance object that this component can accept some prop like this.
props: {
text: { type: String },
value: { type: Boolean },
}
then when you use this component in the parent one you can pass the defined props to the component like this:
<child-component text="some text" :value="false" />
notice the : notation is just a shorthand for v-bind:value="false", if you don't use this binding the false will be sent to the child component as a string. for any other value type you should use binding.
please read the docs to learn more about binding in vue
attribute binding
v-bind shorthand
now, the data flow from child to parent is done via events so in your child component you can emit an event for the parent one to listen to like this:
this.$emit('event-name', payload)
then in the parent component where you used child component you can listen to this event like this
<child-component #event-name="doSomethingFun($event)" />
where doSomethingFun() is a method in parent component and we are passing the payload sent from child component to this method with $event
notice # notation is shorthand for v-on like v-on:event-name="doSomethingFun($event)"
: is shorthand for v-bind: and this is used for dynamic rendering for the attributes such as src, href etc.
# is shorthand for v-on:click which is event handler for function calls.
You can read more Event handling shorthand syntax

Pattern to add user-interface relevant data to Vue array props?

If props are not editable how does one go about adding data relevant to the user interface in a local component?
Say you receive an Array of blog posts, each post can be iterated in the interface with v-for - but each elements also needs a few extra properties only relevant to the interface like "is_active" or "is_expanded".
How does one go about adding these extra properties to each element in the array received from the prop if props should not be modified?
In particular case i am using inertia.js
So the data can not be modified outside of the component that receives the prop - in a Vuex setup one might mutate the data from the backend and prepare it for the interface before going to the component, but this isn't available here.
create a computed property which maps the prop array and adds the extra properties
computed:{
_array(){
return this.propArray.map((item) => {
return {
...item,is_active:false,is_expanded:false
})
}
}

how to update the props in vue when the grandchild file has send the succeed PUT request

i have three vue.js file. where the parent file (parent.vue) contains data of profile:[]
the data of profile is send to child file (child.vue) using props methods.
the child.vue also has it's own child file (grandchild.vue) that has been pass with the profile data by using props.
grandchildren will send a put request to API to change some data in profile.
my question is. how can i make sure the props will update on every change made in the profile data.
information : (parent.vue = main file, child.vue = drawer(from ant design), grandchild = popover)
i need the child.vue to update the profile data after the grandchild succeed send a put request to the API.
is there any way or reference link so i could make the props update after a put request from grandchild.vue i have tried watch method but the problem is the user need to close the drawer (child.vue) first and re open the drawer to update the props. is there any way the props update without closing the drawer?
example of code :
parent.vue :
// structure
<child.vue
:profile="profile"
/>
child.vue & grandchild.vue :
//script
props : [profile],
profile can be used as {{profile.subsdata}} in html or this.profile.subsdata javascript
Use an emit. Tell the parent component to update via another GET request or just pass the data back directly.
Child Method:
notifyParent () {
this.$emit('updateProfile')
}
Parent Template:
<ChildComponent v-on:updateProfile="someMethod"/>
Parent Method:
someMethod () {
//GET request or whatever
}
More details here: https://v2.vuejs.org/v2/guide/components-custom-events.html
The keyword here is eventBus, you need an eventBus to $emit an event changing the data in the parent component from the grandchild component. If you only need to change up the data 1 layer instead of 2 in this case, you only need custom event + $emit, without the eventBus. But as it's greater than 2 layers, you need eventBus, or even more relegent ways to do state management.

Can't Access Props Outside of Constructor React Native

I'm working on an app in React Native, and am having trouble accessing props that I feed into a component I made.
If I do console.log(this.props) within the constructor, I can see the props display in the console as desired, however if I put it in any other method, it prints undefined. How can I access the props that are clearly being sent to the component from outside of the constructor method?
You are probably adding new methods that are not binding this.
Check if you are writing the method like this:
myMethod(){
//Code
}
and just change it to:
myMethod = () => {
//Code
}
Edit: Like #Li357 says, these are called arrow functions. Arrow functions don't bind this automatically, and as a consequence receive the this of the surrounding class. In your case it will solve your issue as you want to access the properties of that class but you might want to read about it and how binding works in JS classes.
Another option is to write function.bind() but either way should work.

Best way of executing js function located in parent page from custom element

Aurelia: I have a custom element that should execute a function that located in the parent page. the custom element doesn't "know" what function it should execute - it depends on the parent page, and currently I send the name of the function as an attribute to the custom element (the attribute - on-focus-out-action-name):
<form-input field-name="firstName" title="First Name" on-focus-out-action-name ="validateInput()" />
I manage to run the function when it has no params, but when I want to send params (simple string type which is also sent as attribute) - no success
Is there a better way to do it ?
The best way was if I could pass the function as an object (Dependency Injection ?)
You should use the call binding command for this. The way to pass parameters to a function when using the call bind is a bit wonky, but once you understand it, it's easy.
In the custom element, you will pass an object to the bound function. Each property of this function will be matched to the named parameters in the binding. Let's look at it in action. In the page VM, I'll have a function:
pageFunction(paramOne, paramtwo) {
//.. stuff happens
}
This function will be called by a custom element. So in the page view, we will write the binding like this:
<my-element some-func.call="pageFunction(paramOne, paramTwo)"></my-element>
Inside my-element's VM, we can call the bound function, and pass the parameters to it like this:
this.someFunc({paramOne: this.someProp, paramTwo: this.otherProp});
I've created a runnable gist example here: https://gist.run/?id=864edc684eb107cdd71c58785b14d2f9
I prefer using a CustomEvent for this, this makes it clear in the template what is going on.
In your component you dispatch the event like this - the "details" can be any object/data you want:
let event = new CustomEvent('on-focus-out-action-name', {
detail: <some-data-you-want-to-send>,
bubbles: true
});
this.element.dispatchEvent(event);
You'll also need to inject the element in the constructor (you'll also need to use autoinject or inject Element manually)
constructor(private element: Element) {}
Your parent template would then look something like this:
<form-input field-name="firstName"
title="First Name"
on-focus-out-action-name.delegate="validateInput($event)" />
And in your parent component, you use the data you sent like this:
validateInput(event) {
let data = event.detail;
// do stuff
}
Check out this blog post for more details https://ilikekillnerds.com/2015/08/aurelia-custom-elements-custom-callback-events-tutorial/
I managed to do it in Aurelia: This is the custom element with the foucusout.trigger which calls to the focusoutAction in the appropriate timing:
<template>
<label>
${title} - ${fieldName}<input title.bind="title"
focusout.trigger="focusoutAction()" focusin.trigger="focusInAction()"
class="${cssClass}" />
</label>
</template>
This is the usage of the custom element in the parent view with the focusout.call attribute:
<form-input field-name="firstName" title="First Name"
place-holder="Enter first name"
on-focusout.call="validateInput(nameOfElement)" />
And this is the relevant code in the view model of the custom control:
#bindable onFocusout;
focusoutAction() {
var args =
{
nameOfElement: this.fieldName
};
this.onFocusout(args);
}