Is it possible to utilize the expose method to retrieve additional reactive variables and computed properties similar to methods in Vue 3?

Switching my application from Vue 2 to Vue 3 has been quite a journey. I've utilized the Composition API to refactor my previous render function into the setup hook. One interesting discovery was the ability to expose methods using context.expose({}).

Now, I have a couple of questions:

  1. How can I replace the created method in Vue 3's Composition API? (Considering that the setup hook is executed before the create hook, I'm struggling to figure out how to perform those operations inside the setup hook.)
  2. Is it possible to return reactive variables and computed properties using context.expose?

Below is the setup script I have:

    <script>
import {h,ref,computed,provide} from 'vue';
export default {
 name: 'something',
 props: some props,
setup(props,context) {
      const currIdx = ref(0);
      const tabCnt = ref(0);
      const idxMap = ref(new Map());
      const idxs = ref([]);

      // other variables

      // computed properties
        const $_size = computed(() =>{
         // 1. check this.size
            if(props.size) {//'medium','small'
                if(props.size === 'medium') return 'medium'
                if(props.size === 'small' ) return 'small'
            }
            // 2. check flags
            if(props.medium) return 'medium'
            if(props.small ) return 'small'
            // 3. default value : 'medium'
            return 'medium';
        });
       // [COMPUTED] Props normalize : SHAPE
        const $_shape = computed(() =>{
            // 1. check this.shape
            if(props.shape) { // 'border','underline','none'
                if(props.shape === 'border'   ) return 'border'
                if(props.shape === 'underline') return 'underline'
                if(props.shape === 'none'     ) return 'none'
            }
            // 2. check flags
            if(props.border   ) return 'border'
            if(props.underline) return 'underline'
            // x. default value : 'border'
            return 'border';
        });


      // [COMPUTED] - [END REGION]
      const getLabelNode = (props) => {
            var label = props.label, idx = props.idx, disabled = !!(props.disabled || props.disable)
            return h('vu-tab-label',{props:{idx, disabled}},[label]);
        };

      
          
          // 2. make window area -> label + navi(?)
        var labelWindow = [];
        labelWindow.push(h("div",{"class":"vu-tab__label-wrapper","ref":"scroll"}, labels));
        if(props.navigation || props.addBtn) {
            labelWindow.push(h(tabNavi))
        }

        // 3. do something
        idxs.value = Array.from(idxMap.value.keys());

        // 4. make class
        let tabClass = [];
        tabClass.push("vu_tab-box");
        tabClass.push(`vu-tab-box--${this.$_shape}`);

        // methods
        const onAddClick =(e) => {
            context.emit('add-tab',e);
        };

        context.expose({
            onAddClick,
        });
  
        // x. return all nodes
        return h("div",{"class":tabClass},[
            h("div",{"class":"vu-tab__label-window","ref":"window"},labelWindow),
            h("div",{"class":"vu-tab__content-wrapper"},contents)
        ]);
    
    },
  }
</script>

Regarding question 1, my challenge lies in the created hook, and I aim to carry out those operations within the setup.

created() {
    // 1. Check default index
    if( (this.defaultIdx === 0) || this.defaultIdx ) {
        this.currIdx = this.defaultIdx;
        return;
    }
    // 2. check slots
    var slots = this.$slots['default']
    if(!!slots) {
        slots.find(vNode => {
            if (!vNode.componentOptions) { return false }
            var idx = vNode.componentOptions.propsData.idx;
            if (idx === undefined) { return false }
            this.currIdx = idx;
            return true;
        });
    }
},

Answer №1

Understanding the Composition API's 'created' hook

The Composition API does not include a created or beforeCreate hook like the Options API. Instead, it is replaced by the setup function. You can directly write your code in the setup function or organize it in separate functions called from within setup.

How are properties exposed as reactive using 'expose'

Yes, properties can be made reactive by exposing them using the expose function in the Composition API. Although accessing child component values with template refs may not align with Vue's principles, it is feasible and maintains reactivity. I conducted my own experiment since there was no official documentation on this. Check out the results in the following code sandbox:

https://codesandbox.io/s/falling-breeze-twetx3?file=/src/App.vue

(If you encounter an error message like "Cannot use import outside a module," simply refresh the browser within the code sandbox itself as there appears to be a template issue)

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

Having trouble getting Video.js SWF to work on Internet Explorer?

I've been working with video.js and am having trouble getting it to function properly on Internet Explorer. I have added the swf file like this: videojs.options.flash.swf = "http://vjs.zencdn.net/4.2/video-js.swf " Here is the code for the video pla ...

`Can controllers be included in route or template definitions?`

When it comes to defining a route with a template, there are two main ways to set the controller for the view: In the route: $routeProvider .when('/phone/:phoneId', { controller: 'PhoneDetailController', templateUrl: &ap ...

Clear all events from an HTML element and its descendants with TypeScript

Each time the page loads, I have HTML from an API that is constantly changing. Is there a way to strip away all events attached to it? The original HTML looks like this: <div id="content"> <h2 onclick="alert('hi');">Test 1< ...

html inserting line break using label

I am attempting to dynamically set text to a label using jQuery. However, I am having trouble getting the <br> or \n to create new lines. Instead, all the text displays on the same line and wraps around. If you want to see my code in action, ch ...

Remove the border of the icon within the input field in Bootstrap

Currently, I am working on integrating Bootstrap with React and faced a challenge while trying to add a password field with an icon that allows users to toggle between displaying text and hiding it inside the input field. While I have successfully implemen ...

Is bower install failing to detect a local npm package?

After running bower install, I encountered the following error message: $ bower install module.js:340 throw err; ^ Error: Cannot find module 'minimist' at Function.Module._resolveFilename (module.js:338:15) at Function.Module._l ...

How can I organize the selected options from a select2 form element using a basic sorting method?

I am utilizing select2 by ivaynberg and encountering an issue with the data arrangement upon submission. Is there a method to have the results in the form submit data reflect the order in which they were selected in the select2 element, without relying on ...

Retrieve an array from a JSON object by accessing the corresponding key/value pair using the utility library underscore

I have a dataset in JSON format (as shown below) and I am attempting to use the _.where method to extract specific values from within the dataset. JSON File "data": [{ "singles_ranking": [116], "matches_lost": ["90"], "singles_high_rank": [79 ...

Pause the event listener temporarily and reattach it after specific actions have been completed

I am currently working on a React app that includes a scrollable div. Here is an example: <main id="main" onScroll={this.handleScroll}> My question is, how can I temporarily remove the onScroll event listener from the main element and then reattach ...

Display the current count of selected radio buttons in real-time

I am working with radio buttons that are generated dynamically using a 2D array within a while loop. I want to display the number of radio buttons checked when one is clicked. Here are my radio buttons: $n=0; while($row=mysqli_fetch_row($rs)){?> <f ...

Steps to verify the current time and execute a task if it matches the designated time

After successfully implementing a time function which changes the value of an input text based on a specific time, I encountered an issue. Although the time function is designed to change the input text value to 1 when the time reaches 2:30:35 PM... if(b ...

To enable RTL in TextField, please note that the JssProvider is only available in "react-jss/src/JssProvider" and not in "react-jss/lib/JssProvider"

Seeking help to convert LTR to RTL in the following code: <TextField id="date" label="EmployeeDate" type="date" onChange= ...

Step-by-step guide to creating a dynamic button that not only changes its value but also

I am trying to implement a translation button on my website that changes its value along with the text. Currently, I have some code in place where the button toggles between divs, but I am struggling to make the button value switch as well. Given my limit ...

Disregard the sorting of rows in the MUI Datagrid

Any advice on excluding the "TOTAL" row from sorting in MUI library? onSortModelChange={(test, neww) => { neww.api.state.sorting.sortedRows = [14881337, 2, 3] neww.api.setState({...neww.api.state}) } } Review ...

Arranging elements based on specific coordinates

const renderTimeSlots = () => { const timeSlots = []; for (let i = parseInt(workStartsAt); i <= parseInt(workEndsAt); i++) { if (i !== 0) { timeSlots.push( <div className="flex flex-row cursor-pointer"> ...

Deploying an AngularJS 1.x application bundled with Webpack to Tomcat server

I've scoured the depths of Google and combed through the official documentation for Webpack, but I’ve yet to stumble upon a tutorial, guide, or plugin that addresses this particular issue. Does anyone have any experience with this problem, or should ...

Using values from a designated line within the textarea to successfully submit a GET form

How can I extract values from a specific line in a TextArea and use them to submit a form? <!DOCTYPE html> <html> <body> <input type='button' value='submit' onclick='document.getElementById("submit-line-3") . ...

Display the flowplayer div when the anchor is clicked

I have a dynamic CGI page that displays a list of files. The number of files varies based on uploaded content, so I am looking to create previews for video files. Below is a snippet of HTML code: <TMPL_LOOP files> <tr> <td&g ...

Guide to accessing a method from a separate file with the help of an event bus

I'm working on CreateEntryStepper.vue where I have a button that needs to call a function in CreateEntryStepperImageUpload.vue when pressed. I understand that event busses need to be used, but I am unsure about what exactly needs to be passed and how ...

jQuery slideToggle function not working properly when clicking on a link within a div

I am facing a slight issue with the slideToggle function when there is a link inside the slideup panel. My goal is to create a button that, when clicked, will slide up a div displaying related posts. Subsequently, when another button or project link is cli ...