Props in Vue components are exclusively accessible within the $vnode

Exploring the realm of Vue.js, I am tasked with constructing a recursive Component renderer that transforms JSON into rendered Vue components.

The recursive rendering is functioning smoothly; however, the props passed to the createElement function (code below ;) ) are not accessible as props but are located inside the $vnode.data object. Any suggestions on what could be missing?

Illustrated below is the mock JSON structure being utilized:

{
  "_id": "aslwi2",
  "template": "NavigationBar",
  "data": {},
  "substructure": [
    {
      "_id": "assd2",
      "template": "NavigationBarListItem",
      "data": {
        "title": "NavList Item 1"
      }
    },
    {
      "_id": "a2323uk",
      "template": "NavigationBarListItem",
      "data": {
        "title": "NavList Item 2"
      }
    }
  ]
}

Implementation of Recursive Rendering Component:

const createComponent = function(node ,h){
    if(!node || !node.template){
        return;
    }

    let children = [];
    if(node.substructure instanceof Array){
        node.substructure.map( async childNode => {
            const childComponent = createComponent(childNode, h);
            children.push(childComponent);
        });
    }

    return h(node.template, {xdata : clone(node.data)}, children.length > 0 ? children : null );
};



export default Vue.component('Structure', {
    render: function(createElement){

        if(!this.structure) return;
        const component =  createComponent(this.structure, createElement, registry);
        console.log(component);
        return component;
    },
    props: {
        structure: {
            type: Object
        }
    }
})

Dynamically Instantiated Components Example:

<!-- Component: NavBar -->
<template>
    <div class="nav-bar">
        <slot></slot>
    </div>
</template>

<script>
    export default {
        props: {
            data: {
                type: Object
            }
        }
    }
</script>

<!-- Component: NavBarListItem -->
<template>
    <div class="nav-bar-item">
        {{title}}
    </div>
</template>

<script>
    export default {
        data () {
            return {
                title : "default"
            }
        },
        created() {
            console.log('list item: ', this)
        }
    }
</script>

Upon inspecting the log within the list item component's created method, we observe the passed props present within the $vnode...

https://i.sstatic.net/VZh7Y.png

Answer №1

There seems to be an issue at this point:

return h(node.template, {xdata : clone(node.data)}, ...

I am unsure about the purpose of xdata, as it doesn't seem like a suitable parameter to pass to h. For correct options, refer to the documentation available at https://v2.vuejs.org/v2/guide/render-function.html#The-Data-Object-In-Depth.

If you intend to pass props, use props instead.

return h(node.template, {props : clone(node.data)}, ...

Furthermore, your code raises concerns regarding the lack of a definition for the title prop in NavBarListItem. A title cannot be passed unless properly defined as a prop; specifying it within data won't have the same effect.

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

Puzzling array challenge. Lack of clarity in explanation

I am currently working on a series of JavaScript tests available at js-assessment One of the tasks states: it("you should be able to find all occurrences of an item in an array", function() { var result = answers.findAllOccurrences('abcdefab ...

Updating a MongoDB document using only the data from checked checkboxes

Imagine having data structured like this: _id:60e2edf7014df85fd8b6e073 routineName:"test" username: "tester" monday:[{ _id: 60e430d45395d73bf41c7be8 exercise: "a" }{ _id: 60e4329592e ...

Adding LocalStorage functionality to buttons in order to switch colors can be done by storing the

I've run into an issue trying to incorporate LocalStorage with the buttons that change colors as themes in JavaScript. I'm new to coding and eager to add this feature to my personal blog. $(document).ready(function () { $(".header--theme-button ...

Wordpress tabs with dynamic content

I came across a code on webdeveloper.com by Mitya that had loading content tabs and needed the page to refresh after clicking the tab button. It worked perfectly fine outside of WordPress, but when I tried implementing it into my custom theme file, it didn ...

npm build issues stemming from browserlist configurations

I am encountering an issue with my create-react-app failing to build, showing the following error: ./src/index.css Module build failed: BrowserslistError: Unknown browser query `dead` at Array.forEach (<anonymous>) I have carefully reviewed my ...

Issue with recognizing global methods in Vue and Typescript – help needed

I have a Vue mixin that looks like this: const languageMixin = Vue.extend({ methods: { $getLanguages: function(): object { return { en: 'english' } } } } Vue.mixin(languageMixin) ...

What steps should I take to set up nuxt 3 in such a way that it functions properly when I attempt to directly access a static page created through the command

Everything is functioning properly in my project when I execute npm run generate followed by npx serve .output/public. However, if I open the index.html file located in .output/public directory directly through my file system, only the initial display appe ...

Having trouble with CORS in your Angular application?

I am attempting to retrieve data from a site with the URL: Using the $http service After extensive research, I have come up with this CoffeeScript code snippet: angular.module('blackmoonApp') .controller 'PricingCtrl', ($scope, $ht ...

Ignore linting errors in the Webpack React Fast Refresh plugin for faster performance

I have integrated the following plugin for Hot Module Replacement (HMR): https://www.npmjs.com/package/@pmmmwh/react-refresh-webpack-plugin. How do I prevent it from blocking the page display due to non-breaking errors, such as linting issues? Here is a ...

Image pop-ups that overlay text on the homepage

I'm facing an issue and I'm looking for a solution... Upon entering my homepage, I would like to display a popup image showcasing a new event so visitors can see it before accessing the website. I attempted to achieve this using JavaScript but w ...

Ways to activate flashlight on mobile using React.Js

Is it possible to control the torch light of a mobile device by toggling a button? https://i.stack.imgur.com/x9nIf.png <IconButton onClick={() => setFlashOn(!flashOn)} style={{ position: "absolute", right: 80, top: 20, zIndex: ...

Limiting the style of an input element

How can I mask the input field within an <input type="text" /> tag to restrict the user to a specific format of [].[], with any number of characters allowed between the brackets? For example: "[Analysis].[Analysis]" or another instance: "[Analysi ...

How can we calculate mesh positions and create a new Point3D object with specified coordinates (x, y,

private void BuildVertices(double x, double y, double len) { if (len > 0.002) { mesh.Positions.Add(new Point3D(x, y + len, -len)); mesh.Positions.Add(new Point3D(x - len, y - len, -len)); mesh.Positions.Add(new Point3D(x + len, y - len, -l ...

What strategies can be implemented to avoid re-rendering in Angular 6 when the window is resized or loses focus?

I am currently working with a component in Angular 6.0.8 that consists of only an iframe element. Here is the code in page.component.html: <iframe [src]="url"> The logic for setting the URL is handled in page.component.ts: ngOnInit() { this.u ...

Display the modal in Angular 8 only after receiving the response from submitting the form

I am encountering an issue where a pop-up is being displayed immediately upon clicking the submit button in Angular 8, before receiving a response. I would like the modal to only appear after obtaining the response. Can someone assist me with achieving thi ...

Specify the dependencies in the package.json file to ensure that the React package designed for React v17 is compatible with React v18 as well

Recently, I developed an npm package using React v17.0.2. The structure of the package.json file is as follows: { "name": "shoe-store", "version": "0.1.0", "private": true, "dependencies": ...

React Prop Local Modal Redux

Just diving into the world of React and Redux, and I'm a bit lost on how to effectively utilize both local properties and redux properties simultaneously. After trying different approaches without success, I'm reaching out for guidance. My goal i ...

AngularJS - Not binding $scope to the DOM

Recently starting out with Angular, I decided to practice by creating a simple website. One of the features I want to include is displaying the number of times a button has been clicked through data binding. Here's the controller code I've writte ...

Looking for nested objects within an array in JavaScript

Currently, I am dealing with a REST API that provides data in the following format: students = [{ batch_id: 22 id: 1 image: null name: "a new batch student", attendance: [ { id: 1, student_id: 1, batch_id: 22, absent_on: "2019-09-15", ti ...

Exploring Angular component testing through jasmine/karma and utilizing the spyOn method

I have been facing an issue while trying to test my component. Even though the component itself works perfectly, the test keeps generating error messages that I am unable to resolve. Here is the snippet of code that I am attempting to test: export cl ...