VueJS: Send all unspecified attributes to child component in the same way as using v-bind="$props"

I am looking for a way to receive any props passed by the parent component into the child component without explicitly mentioning them in props:[]. This is because I may not always know which props will be bound.

Parent component

<template>
  <div id="parentComponent">
    <child-component v-bind="anyPropsToPass"></child-component>
  </div>
</template>

<script>
  import ChildComponent from './components/child-component/child-component'

  export default {
    name: 'app',
    components: {
      ChildComponent
    },
    data () {
      return {
        anyPropsToPass: {
          name: 'John',
          last_name: 'Doe',
          age: '29',
        }
      }
    }
  }
</script>

Child component

<template>
  <div>
    <p>I am {{name}} {{last_name}} and I am {{age}} old</p>
    <another-child v-bind="$props"></another-child> <!-- another child here and we pass all props -->
  </div>
</template>

<script>
  import AnotherChild from "../another-child/another-child";
  export default {
    components: {AnotherChild},
    props: [],   // I know if I mentioned props here I can receive but it's unknown, I 
                 //just want to pass it down until it received in right component to use  
    created() {
       console.log("Props", this.$props); 
       // Gets null
       // Expected : anyPropsToPass Object
    }
  }
</script> 

If props are mentioned in the props of child then it works but there should be some way to know which are the props passed or bind from the parent even though we are not interested in child.

e.g. Working fine!

Child component

<template>
  <div>
    <p>I am {{name}} {{last_name}} and I am {{age}} old</p>
    <another-child v-bind="$props"></another-child>
  </div>
</template>

<script>
  import AnotherChild from "../another-child/another-child";
  export default {
    components: {AnotherChild},
    props: ['name', 'last_name'],    
    created() {
       console.log("Props", this.$props); 
       // Gets expected props here
    }
  }
</script> 

Answer №1

If you want to access all v-bind props, even the ones that were not declared, you can simply use this.$attrs.

<!-- parent  -->
<template>
  <div id="app">
    <ChildComp :prop1="114" prop2="514" class="homo" />
  </div>
</template>
<script>
// child component
export default {
  created() {
    console.log('all props: ', this.$attrs) // { "prop1": 114, "prop2": "514" }
  }
}
</script>

Answer №2

Using this.$attrs, it is possible to achieve the desired outcome.

Child.vue:

<template>
  <div>
    <p>My name is {{getInfo('first_name')}} {{getInfo('last_name')}} and I am {{getInfo('age')}} years old</p>
  </div>
</template>

<script>
export default {
  methods:{
    getInfo(attr){
      return this.$attrs[attr];
    }
  },
  components: {},
  props: [],
  created() {
    console.log("Attributes", this.$attrs);
  }
}
</script>

Answer №3

It's not recommended to drill down the props as it can lead to inconsistency. A better approach is to use the provide/inject pattern to pass data from a grandparent component to a grandchild one:

<template>
  <div id="parentComponent">
    <child-component></child-component>
  </div>
</template>

<script>
  import ChildComponent from './components/child-component/child-component'

  export default {
    name: 'app',
    components: {
      ChildComponent
    },
  provide () {
     return {
       user: this.user
     }
   },
    data () {
      return {
        user: {
          name: 'John',
          last_name: 'Doe',
          age: '29',
        }
      }
    }
  }
</script>

In the grandchild component:

<template>
  <div>
    <p>I am {{user.name}} {{user.last_name}} and I am {{user.age}} years old</p>
    <another-child></another-child>
  </div>
</template>

<script>
  import AnotherChild from "../another-child/another-child";
  export default {
    components: {AnotherChild},
    inject:['user'],
    created() {
       console.log("injected user", this.user); 
       
    }
  }
</script

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Efficiently uploading images with AJAX when submitting a form

I am attempting to upload an image along with other variables in a form submission, and then execute my PHP code to store the image in the user's profile_picture table. I want the image upload to be integrated within the same form used for saving dat ...

The Rails/Ajax function is not replacing the DIV as expected, but rather nesting a new DIV inside

Struggling to dynamically update a DIV using AJAX after a form submission. Here is the content of my partial _inline.html.erb: <div class="large-12 columns" id="inline_posts"> <% @posts.each do |post| %> <div class="row"> <div ...

What's the secret behind generating a crisp 400 on paper?

Understanding Why it Prints 400 I'm struggling to comprehend the logic behind this var x = {}, y = { key: "y" }, z = { key: "z" }; x[y] = 100; x[z] = 200; console.log(x[y] + x[z]); ...

Having trouble with the dropdown menu in Bootstrap?

I'm having trouble creating a responsive dropdown menu. When I click on the dropdown items, nothing happens. Here's the code: <div class="navbar-header"> <button type="button" class="navbar-toggel" data-toggel="collapse" data-target="#m ...

Using NodeJS in conjunction with Nginx

Running both NodeJS and Nginx on the same server has posed a unique challenge for me. I have successfully configured Nginx to handle requests from "www.example.com" while also wanting NodeJS to take requests from "api.example.com". The setup is almost comp ...

Utilizing JavaScript to create a single selection from two Listboxes

Seeking assistance with integrating ASP.NET (C#) code. In my web application, I have implemented two listboxes - one displaying a list of companies fetched from the database (lstCompanies), and the other allows users to filter these companies (lstFilter). ...

Generating parameters on the fly from an array using jQuery

After implementing a successful plugin on my website, I am now looking to enhance it further by defining state-specific styles dynamically. The current setup allows for passing parameters for specific states, as shown below: $('#map').usmap({ ...

The lack of definition for the Nuxtjs document is causing an issue

Currently, I am in the process of setting up a reviews page within nuxtjs. To achieve this, I have integrated the vue-star-rating library into my project. However, I have encountered an error despite attempting various solutions that have worked for others ...

Best methods for deleting an element's attribute or style attribute

Imagine this snippet of CSS code: .notif-icon { display: inline-block; } In my HTML, I have the following element which starts off hidden by overriding the display property of the notif-icon class: <span id="error" class="notif-icon& ...

What is the best way to insert CSS code into a custom Vue directive file?

I need a solution that applies a gradient background to the parent div in case an image fails to load. I've attempted to create a directive for this purpose: export default { bind(el: any, binding: any) { try { ..... ...

Automatically populate the options of a dropdown menu using jQuery

I am a beginner in the world of Javascript, JSON, and jQuery. I am seeking some guidance as I navigate through this new territory. On my JSP page, there is a drop down list that needs to be populated with content when the page loads. To achieve this, I hav ...

Using Javascript to multiply strings

While working on the leetcode problem related to multiplication, I encountered an interesting issue. Given two non-negative integers num1 and num2 represented as strings, the task is to return the product of these two numbers, also in string form. However ...

Displaying information from an array using AngularJS

I'm struggling to display data from an array and I could use some help. Here's a snippet from my service.js file: this.fetchData = function() { var myArray = $resource('url', {method: 'get', isArray: true}); myArray ...

What is the best method for transmitting the filename using Plupload?

I've been trying to solve this issue for a while now. My problem seems straightforward – I want to send the filename along with the file as a multipart request in Plupload, but so far, I haven't had any success. The main thing I'm missin ...

Using AngularJS to dynamically bind data based on certain conditions

I am managing an array of tasks that each have titles and labels. function Task(taskTitle, taskType) { this.title = taskTitle; this.type = taskType; } $scope.tasks = []; As I create different tasks with various types and add them to the array. In ...

Creating an object based on its type in JavaScript is a simple task

In a recent project, I found myself using the following code: function foo(type, desc) { var p = new type(desc); } Although I am not a JavaScript expert, it seems to be functioning properly in Chrome. Can anyone confirm if this is valid JavaScript? Th ...

How can you access the index of an object in Vue.js when one of its properties has been modified

Here's the Vue component code I'm working with: data: function () { return { products: [ { product_id: '', price: ''}, { product_id: '', price: ''}, ], ...

looking to retrieve the corresponding value of a specific array key

I am trying to determine the value of a complex array, but I keep getting values like 0,1,2,3,4,5 as answers. Here is the code snippet I am using to retrieve the state value of the array: var shardState = Object.keys(mydata.cluster.collections[collection ...

The onchange functionality is not functioning as expected

I've added an onchange event to the select box, but it doesn't seem to be working. Any suggestions would be greatly appreciated. Thank you in advance. HTML [<select id="notifyBy" ng-change="selectchange()" style="border:none" class="formtex ...

"Executing the command 'npm run dev' is successful, however, the command 'next dev' does not yield the expected result

Trying out Next for the first time using npx create-next-app, but running into issues with the scripts. While npm run dev works without any problems, executing next dev gives me an error saying zsh: command not found: next. Any idea why this is happening? ...