PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Sunday, October 16, 2022

[FIXED] How to get a change of prop of useSlot() in Vue 3

 October 16, 2022     slot, vue-render-function, vue.js, vuejs3     No comments   

Issue

I have a question about how to get the change of props retrieved from useSlots()

this is a file declaring Parent component with Child component as Parent component's slot. Also I passed some props to Child component.

<script setup>
import { ref } from "vue";
import Parent from "./components/Parent.vue";
import Child from "./components/Child.vue";

const name = ref("Nagisa");
function updateName() {
  name.value = "Daniel";
}
</script>

<template>
  <Parent><Child :name="name"></Child></Parent>
  <hr />
  <button @click="updateName">update name</button>
  <p>name: {{ name }}</p>
</template>

In Parent component, because of some limitations, I need to call render function and re-store what has been declared in slot.

// Parent component

<script setup>
import Child from "./Child.vue";
import { h, useSlots } from "vue";

const slots = useSlots();
const defaultSlot = slots.default(); // <====== retrieving slot of Parent component

const render = (e) => {
  return h("div", {}, h(Child, defaultSlot[0].props)); <======= restoring Child with props coming from defaultSlot of Parent
};

// ========================
const render = (e) => {
  return h("div", {}, defaultSlot); <==== or alternatively this renders Child correctly
};
// ========================
</script>
<template>
  <render></render>
</template>

// Child component


<script setup>
defineProps(["name"]);
</script>
<template>
  <div>
    {{ name }}
  </div>
</template>

This correctly renders Child component with Parent component but Child component never updates if its prop value changes

enter image description here

After I click updateName button

enter image description here

Is there any way to catch and update the change of Child component's prop in Parent component from useSlot()?


Solution

Your usage of slot in Parent is incorrect. Whole point of slots is to render something the Parent knows nothing about (ie. anything you pass to it). So rendering Child directly is wrong (as it tights Parent into always rendering Child instead of slot content)

Second problem is using const defaultSlot = slots.default(); inside the setup - slots are functions and arguments of those functions (such as props and other reactive data from the parent scope) change when the template is re-rendered. So the slot function needs to be executed every time the Parent re-renders. But setup runs only once. This is why you don't see any update of Child. Instead use a slot directly in render function:

// Parent component
<script setup>
import { h, useSlots } from "vue";

const slots = useSlots();

const render = () => {
  return h("div", {}, slots.default ? slots.default() : null);
};
</script>


Answered By - Michal Levý
Answer Checked By - Terry (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing