0
votes

I know that in Vue parents should update the children through props and children should update their parents through events.

Assume this is my parent component .vue file:

<template>
<div>
    <my-child-component :category="category"></my-child-component>
</div>
</template>

<script>
export default {
  data: {
     return {
       category: 'Test'
     }
  }
}
</script>

When I update the category data in this component, it will also update the category props in my-child-component.

Now, when I want to use Vue in Laravel, I usually use an inline template and pass the value from the blade directly to my components (as for example also suggested at https://stackoverflow.com/a/49299066/2311074).

So the above example my my-parent-component.blade.php could look like this:

@push('scripts')
   <script src="/app.js"></script>
@endpush

<my-parent-component inline-template>
    <my-child-component :category="{{ $category }}"></my-child-component>
</my-parent-component>

But now my-parent-component is not aware about the data of category. Basically only the child knows the category and there is no communication between parent and child about it.

How can I pass the data from blade without breaking the parent and child communication?

2

2 Answers

1
votes

I just had to pass the category to the inline-template component through props like this:

@push('scripts')
   <script src="/app.js"></script>
@endpush

<my-parent-component :initcategory="{$category}}" inline-template>
    <my-child-component v-model="category"></my-child-component>
</my-parent-component>

In my-parent-component I had to set the props and initialize is using the create method:

export default {
  props: {
    initcategory: '',
  },
  data() {
    return {
      category: '',
    };
  },
  created(){
    this.category = this.initcategory;
  }
}

Now my my-parent-component is fully aware of the category and it can communicate to the child using props and $emit as usual.

0
votes

Your reference to this answer is different altogether from what you are looking for!

He's binding the :userId prop of the example component but not the parent component or in simple words: Any template using the example vue can either pass a string prop or bind :userId prop to a string variable. Following is similar:

<example :userId="{{ Auth::user()->id }}"></example>

OR

<example :userId="'some test string'"></example>

So you should rather assign {{ $category }} to a data variable but rather binds to a child component prop which will have no effect on the parent.

In the following snippet you're only binding the string but rather a data key:

<my-child-component :category="{{ $category }}"></my-child-component>

Update

See the following example which will change the h1 title after 3 seconds

 // HelloWorld.vue
<template>
 <app-name :name="appName" @appNameChanged="appName = $event"></app-name>
</template>

<script>
    export default {
        props: ['name'],
        data() {
            return {
                appName: null
            }
        },
        mounted() {
            // NOTE: since Strings are immutable and thus will assign the value while objects and arrays are copied by reference
            // the following is just for the purpose of understanding how binding works
            this.appName = this.name;
        }
    }
</script>

The template which renders the app title or you can say the child component

// AppName.vue
<template>
   <h1>{{ name }}</h1>
</template>

<script>
    export default {
        props: ['name'],
        mounted() {
          setTimeout(() => {
             this.$emit('appNameChanged', 'Change App')
          }, 3000);
        }
    }
</script>

And here's how it is being used in the welcome.blade.php

<div id="app">
  <hello-world :name="'Laravel App'"></hello-world>
</div>