Skip to content
Advertisement

Can we use expose method to return other reactive variables and computed properties like methods in vue 3?

I am changing my application from vue 2 to vue 3. By using composition api,i have changed my previous render function in that setup hook. After checking some documentation,I got to know that i can expose methods by using context.expose({}).

Now my questions are:

  1. How to replace created method in vue 3 composition api? (As we know, setup hook occurs beforeCreate hook but not able to understand how to do those operations inside setup hook?)
  2. Can we return reactive variables and computed properties by using context.expose?

Here is my setup script:

    <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>

For question 1, It is my created hook and i want to do those operations inside 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

created hook in the composition api

This one is simple, there is no created or beforeCreate hook in the composition api. It is entirely replaced by setup. You can just run your code in the setup function directly or put it in a function you call from within setup.

Are properties exposed using expose reactive

Yes. While accessing values of child components using template refs is not really the “Vue”-way, it is possible and the values passed keep their reactivity. I couldn’t find any documentation on this, so I quickly implemented a small code sandbox to try it out. See for yourself.

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

(If you encounter an error similar to “Cannot use import outside a module”, just reload the browser within code sandbox, there seems to be an issue with the code sandbox template)

Advertisement