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:
- 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?)
- 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;
});
}
},
Advertisement
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)