What is a way to pass refs from a parent component to a child component without relying on Typescript?

I am currently working on an App.vue file that has a property called "clicked" which I am trying to pass to different child components.

App.vue

<template>
  <NavBar :clicked="clicked"/>
  <BackDrop :clicked="clicked"/>
  <SideDrawer :clicked="clicked" />
  <router-view></router-view>
</template>
<script>
import { ref } from "vue";
import NavBar from "./components/Navbar/NavBar.vue";
import BackDrop from "./components/Backdrop/BackDrop.vue";
import SideDrawer from "./components/Sidedrawer/SideDrawer.vue";
export default {
  name: "App",
  components: { NavBar, BackDrop, SideDrawer },

  setup() {
    const clicked = ref(false);

    return { clicked };
  },
};
</script>
export default App;

The child components can now be rendered conditionally like so:

SideDrawer.vue

<template v-if="clicked">
  <div class="sidedrawer"></div>
</template>
<script setup>
</script>

Have I correctly passed the "clicked" ref in the "App.vue" file?

If yes, how do you access these props in the child component? I have researched online and seen various posts on StackOverflow that mention using "defineProps()", but most of them are for Typescript as shown in this code snippet:

const props = defineProps({
  msg: String,
  user: Object,
});

// Destructuring props
let { name, lastname } = props.user;
</script>

However, since I am not using Typescript, this method won't work for me. What is the alternative way of passing props without relying on Typescript?


EDIT:

Even when I tried implementing Typescript and used the following code:

SideDraw.vue

<template v-if="clicked">
  <div class="sidedrawer">
    <h1>{{ props.clicked }}</h1>
  </div>
</template>
<script setup>
const props = defineProps({
  clicked: boolean,
});
</script>

I encountered errors:

'defineProps' is not defined.eslintno-undef
'boolean' is not defined.eslintno-undef

...

After referring to a Github thread here, I attempted setting global variables as suggested, but it did not resolve the issue.

babel.config.js

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ],
    globals: {
      defineProps,
      defineEmits,
      defineExpose,
      withDefaults
    }
  }
}

Answer №1

When working with JavaScript, there are two common ways to define props. One way is to simply list the prop names in an array like this:

const props = defineProps([ 'clicked', 'someOtherProp' ]);

However, a much more preferred method (which can save hours or even days of troubleshooting) is to define each prop using an object like this:

const props = defineProps({
  clicked: { type: Boolean, default: false, required: true },
});

You can find more information on how to validate props in the Vue.js documentation here: https://vuejs.org/guide/components/props.html#prop-validation

Answer №2

No, TypeScript is not required when defining props in a Vue component. TypeScript is actually a superset of JavaScript, so any valid TypeScript code is also considered valid JavaScript.

When you use the <script setup> syntax, you can use the defineProps function to specify which props a component can receive. There's no need to explicitly declare or import this function as it works as a compiler macro. If ESlint is giving you trouble, make sure to add the configuration below to your eslint file.

module.exports = {
    env: {
        'vue/setup-compiler-macros': true
    }
}

In each child component, make sure to accept the prop "clicked".

<script setup>
const props = defineProps(['clicked'])
</script>

Alternatively, you can utilize runtime types like this (not exactly TypeScript, as mentioned by @Estus):

<script setup>
const props = defineProps({
  clicked: Boolean
})
</script>

In your App.vue file, ensure that you pass a value to the prop as shown below:

<script setup>
import { ref } from "vue";

const clicked = ref(false);
</script>

<template>
    <NavBar :clicked="clicked"/>
    <BackDrop :clicked="clicked"/>
    <SideDrawer :clicked="clicked" />
    <router-view></router-view>
</template>

If you choose not to use <script setup>, you can define accepted props like this:

export default {
  name: "NavBar",
  props: ['clicked']
};

Or using runtime types, which is not TypeScript but still effective:

export default {
  name: "NavBar",
  props: {
    clicked: Boolean
  }
};

Answer №3

It is important to remember to defineProps in your child component, rather than in your app.vue file. Additionally, make sure to utilize script setup so that you can avoid importing defineProps from Vue.

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

Setting up server-side CORS in ExpressJS will not include the "Access-Control-Allow-Origin" header

Looking to tackle a CORS request for an ExpressJS server, which is new territory for me. Despite encountering similar issues in the past, I can't seem to pinpoint the problem this time around. It appears that the required headers may not be in the cor ...

The website is failing to extend and reveal content that is being concealed by jQuery

I'm currently diving into the world of Javascript and jQuery, attempting to create a functionality where upon clicking the submit button, the website dynamically expands to display search information. Although the feature is still in progress, I am ut ...

Adding pictures to the select choices in bootstrap-vue

How can I include images in the dropdown list of a Bootstrap-vue select component like the example shown in the image below? https://i.sstatic.net/5PQWd.png ...

I am struggling with converting text to code using the $ symbol. Can anyone provide guidance on what steps

What to do if the dollar sign does not convert text to code? if(this.rules.min && this.value.length < this.rules.min){ return 'Minimum length is ${this.rules.min}' } https://i.sstatic.net/o0joR.png ...

Issue with Django and Javascript internationalization resulting in translations not displaying on website

I have gone through the documentation thoroughly. ./manage.py makemessages -d djangojs is working as expected. ./manage.py compilemessages has generated the necessary .po files However, the translation doesn't seem to be reflected on the site. url ...

Issues encountered with integrating external jQuery/JavaScript functions with Wordpress child theme template

After creating a custom template in my WordPress child theme, I added a link to the Bootstrap v3.0.3 .js file stored on my site. While the popup modal is functioning properly, the jQuery tabs seem to be having some issues. Although they are being display ...

Updating fields in MongoDB using dot notation

In my Mongo Schema, I have defined the following structure: var OrderSchema = new Schema({ postcode: String, ... status: { last_check: { type: Date }, date: Date, code: String, postnum: String, text: Str ...

Sending a multitude of variables using strings, evaluating them through various functions, and incorporating a variety of methods

To put it simply, my goal is to utilize an object literal that allows me to pass an unknown quantity of variables in any order to a function. While this may seem straightforward in principle, within my code, this object literal is passed to a second functi ...

Generate a variety of files using GraphicsMagick

I'm trying to enhance my function that deals with uploaded images. Currently, it captures the image, converts it, and saves only one version of it on the server. However, I would like to modify it to achieve the following goals: Goals: Save multipl ...

Exploring VueJS watchers: How to get started?

Struggling to grasp the concept of Watchers in VueJS, particularly when trying to implement them for tracking tab changes and resetting values. Even though I have set up a watch with parameters like `oldValue` and `newValue`, their usage remains unclear to ...

The collapsible list feature that includes the use of plus and minus signs is malfunctioning

Below is the script that I wrote to address this issue, but for some reason the + and - swapping is not functioning correctly. $('.showCheckbox').click(function(e) { var dynamicBox = $(this).attr('val'); var collapseSign = $(th ...

Managing simultaneous access to a variable in NodeJS: Best practices

For instance: var i = 0; while(true) http.request('a url', callback_f); function **callback_f**(){ **i++**; } In this straightforward scenario, multiple requests could unintentionally increase the value of i simultaneously. How can I creat ...

The data retrieved from the $.ajax() request in Vue.js is not properly syncing with the table

After setting up an $.ajax() function and ensuring the data binding is correctly configured, I expected the data to append to a table on page load without any issues. However, the data is not appearing as expected. Is there something that I might be overlo ...

The absence of the Django CSRF token has been detected

Inside the custom.js file, there is a function defined as shown below : function contactTraxio(fullname, telephone, email) { if (typeof(fullname)==='undefined') fullname = null; if (typeof(telephone)==='undefined') telephone = ...

Switching the URL without reloading the page in NEXT.JS

Currently, I am in the process of building an ecommerce store using NEXT.JS and Redux. Within the product listing page, I have incorporated a sorting select dropdown featuring options such as Price Low to High, Price High to Low, and New Arrivals. My goal ...

Node.js is unable to handle the contents of an SNS event message

I am encountering an issue while attempting to extract content from a Message in an SNS event within a Node.js Lambda project Below is the code snippet for processing the message: exports.handler = (event, context, callback) => { var message = event. ...

Guide to implementing 301 redirection from HTTP to HTTPS in Next.js

What is the process for implementing a 301 redirection from HTTP to HTTPS in Next.js? One example of this would be redirecting from "http://stackoverflow.com/" to "https://stackoverflow.com/". ...

A "Uncaught TypeError" error occurs when trying to execute a function using the dollar sign

After successfully recognizing the hover function, the console displays an error message: Uncaught TypeError: $ is not a function <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> <script> $(docume ...

Utilizing Prototype in Node.js Modules

Currently, I am working on a project involving multiple vendor-specific files in node. These files all follow a similar controller pattern, so it would be more efficient for me to extract them and consolidate them into a single common file. If you're ...

The time zones between Node 8 and Node 11 are not the same

Executing a basic new Date().toString() command produces different results on Node 11 compared to Node 8. In Node 11, the output includes the full timezone abbreviation like this: 'Fri May 10 2019 10:44:44 GMT-0700 (Pacific Daylight Time)' On t ...