i getting error message when i am passing my prop to component. This props is a to displaying button element in payment. Certain component must not show this button but when i pass the prop all the component that uses this button is hidden here are my code for the parent. My problem is same as this (https://laracasts.com/discuss/channels/vue/using-v-if-to-render-one-template-or-another-based-on-a-props) and the solution does not work for me
<payment :sharedButton="false"><payment>
this is my payment.vue button
<div class="col-lg-auto" v-if="unpaid.qr_code === 1 && sharedButton === true">
<q-btn glossy
size="md"
:label="$t('Common.GetQrCode.Button')"
#click="makePayment(unpaidIndex, true)" color="positive"
>
</q-btn>
</div>
export default{
props: {
sharedButton: {
type: Boolean,
default: true
},
here is the logic that when the sharedButton is false then hide it but when the sharedButton is true then show the button
Expected result:
Button in certain component is hidden
Current Result:
All the component with the button is hidden and get avoid mutate props directly
so i solve the my problem apparently i cannot directly assigned instead i declare a variable called isHidden in data()
data(){
isHidden : false;
}
then declare it by <payment-tab sharedButton = "isHidden">
You are facing the issue as you are directly mutating the prop in the child component and the parent isn't notified about the same. A simple way to solve this is to sync the value of prop in the child and the parent component. So, you can change the value directly in the parent component and since props are reactive the new value of the prop would directly get assigned to the child component.
I am assuming that you'd have an option to change the value back to true in your parent component.
<payment :sharedButton.sync="sharedButton"><payment>
(The second sharedButton would be the value kept in the parent component)
Now, when you want to change the prop inside the child just use
this.$emit('update:sharedButton', false)
Related
I'm working with BootstrapVue to get this Accordian like component to work. Part of that entails setting the visibility of a particular item.
Ie,
const obj = {
someData: [...// properties here],
visible: false
}
And this gets fed down to an Accordian component like so:
<Accordian :visible.sync="obj.visible" />
And inside Accordian:
props: {
visible: {
type: Boolean
}
}
THEN... I need to attach it to a b-collapse html tag using v-model because that is how it is suggested on their site. But that throws me this very long list of 'don't modify props directly error'
<b-collapse v-model="visibile" />
Any idea what I am doing wrong?
EDIT: And an important part I forgot to mention, the error only occurs on initial page load. Afterwards the accordian's are fine to use and work (most of the time).
You can't use v-model with a prop because props are meant to be readonly.
Instead, bind <b-collapse>.visible to the visible prop, and emit the update:visible event with the event data whenever <b-collapse>.input event occurs. The update:visible event updates the parent's visible prop via the .sync modifier.
<b-collapse :visible="visible" #input="$emit('update:visible', $event)">
demo
I am new with formik and I have a very annoying problem that I am stuck on with days. So basically I have a parent component in which I have a code like this:
const refs=[]
{data.map((v,i) =>
<Child formikRef={refs}}/> )}
And my child component uses formik:
...
<Formik
innerRef={i => props.formikRef.push(i)}
....../>
So my Child component is rendered a couple of times in my parent component, and I need to track the values of each in my parent component. To be more clear, when I click on button that is located in my parent component, I need to have the values from each (I need to pass data from child to parent component). That's why I am using innerRef. The problem is that I am using an array of refs to track values of each rendered , and a new value is added in the array every time I change a field in my form, so I have far more elements in my array than I should have. I think innderRef is triggered each time a change in a field is made, instead of only onSubmit. How I can solve this problem? Pls help.
You could try like below, Here we are passing index value to Child component to have Formik ref in the same place.
const refs=[]
{data.map((v,i) =>
<Child index={i} formikRef={refs}}/>
)}
<Formik
innerRef={props.formikRef[props.index]}
/>
When I change the props value (Boolean) in the parent Vue component, the child component won't update in order to trigger a modal to open.
In my parent component a click event is setting the value of openModal from false to true. This value is then passed through a prop down to a child component. Within that child component the updated Boolean value should then add a class through class-binding to a div which in return opens a modal.
Parent component:
<FilmListItem
v-for="slice in slices"
#click.native="openModal=true"
/>
<child-component :modal="openModal">
...
data() {
return {
openModal: false
}
}
Child component:
<div
class="modal__container"
:class="{ 'modal--show': showModal }">
...
export default {
props: {
modal: Boolean
},
data() {
return {
showModal: this.modal
}
In the vue dev tools I can see, that the value of the prop changes in the parent. Yet, my child component doesn't update. It worked when I forced the child component to reload when I was assigning a new :key value together with changing the Boolean. But that feels a little hacky to me. Also, a watcher within the child component didn't do the trick. It simply wouldn't watch the changed prop value. Any ideas very much appreciated. Thanks in advance.
I actually found the solution myself jut now:
In the child component I was trying to access the props' data through the data object. But I just accessed to props' data directly like so:
<div
:class="{ 'modal--show': modal }">
...
export default {
props: {
modal: Boolean
}
}
Correct.
Other options for syncing if this parent/child relationship is more complex, or you needed to pass back upward to the parent:
Put the :modal value in a Vuex store and use a computed property on the child component.
Use an EventBus: https://alligator.io/vuejs/global-event-bus/
Let's say I've got a Tooltip component that shows & hides depending on whether there is text data for it or not:
{this.state.tooltipText && (
<Tooltip
text={this.state.tooltipText} />
)}
If I wanted to transition this component in and out, I might instead include a boolean on prop and let the component manage transitioning out itself.
<Tooltip
on={this.state.tooltipText !== null}
text={this.state.tooltipText} />
With this setup, though, I lose the text prop right when the transition out should begin. There is very clearly never a state where on is false and I still have access to the text prop.
Is there a good way to handle this scenario?
Should the component keep an internal record of the previous state of tooltipText?
Or is it best to use two properties to track the state of the tooltip (tooltipOn and tooltipText) and never erase this.state.tooltipText?
Should the component keep an internal record of the previous state of tooltipText?
Yes. Otherwise the parent would have to decide when the transition starts / ends, which is not his authority.
Actually componentWillReceiveProps is best for this as you can access the current & next props:
componentWillReceiveProps(nextProps) {
if(this.props.text && !nextProps.text) {
this.fadeOut();
} else if(!this.props.text && nextProps.text) {
this.setState({ text: nextProps.text });
this.fadeIn();
}
}
Then the parent just has:
<Tooltip text={this.state.tooltipText} />
I'm using a component library and I cannot figure this out. I'm new to react and javascript and need help.
There is a component in the library that renders a header panel with tabs.
Component
|_Component.Tab
The Tab component has 2 states that change its appearance when it is clicked. But the click handler and state changes have to be defined by me outside of Tab component. How do I do this?
Seems to me by your question that you need to use props to pass the function to change state from the Component to the Tabs. Something like this:
Component
changeState(value) {
this.setState({ appearance: value });
}
render() {
return (
<div>
<Tab
appearance={this.state.appearance}
onChangeState={this.changeState}
/>
</div>
);
}
Tab
render() {
console.log('Appearance: ', this.props.appearance); // Use it for whatever you need it
return (
<div>
<Button
onClick={(value) => this.props.onChangeState(value)} />
</div>
);
}
Not sure why do you want to handle a function and it’s state outside of the component when it has to be within the Tab component. But here is the solution what you actually have to do in your Tab component to handle your state
Bind your handler function inside a constructor like below
Eg:
this.handlerFunction = this.handlerFunction.bind(this)
Call this.handlerFunction reference in your tab onClick
Eg:
onClick={this.handlerFunction}
Set state in handlerFunction
Eg:
handlerFunction(event){
this.setState({
tabClicked: event.target.value
})
}
Else I guess The outside component should be a child component that you are talking about. If so pass your tab click state as props to your outside component (i.e., child component) and receive that state as props in your child component and do setState there.
If you are still unclear then
Post your component code here. With Just theory it’s little difficult to understand the actual problem that you are talking about.