JSFiddle - React, Tailwind, and code Playground
VueJS 3 nested ref
by shenron
HTML
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
</div>
JavaScript
const {
ref,
computed,
createApp,
defineComponent,
provide,
inject,
watchEffect,
} = Vue;
const OptionsSymbol = Symbol('options');
const provideOptions = () => {
const options = ref([])
const addOption = (option) => {
const _options = inject(OptionsSymbol, options);
_options.value.push(option);
}
return {
provide() {
return provide(OptionsSymbol, options);
},
addOption,
options: inject(OptionsSymbol, options),
}
}
const VOption = defineComponent({
template: '<option ref="root" :value="opt.value">{{ opt.label }}</option>',
props: ['value', 'label'],
setup(props) {
const { addOption } = provideOptions();
const root = ref();
const opt = {
value: props.value,
label: props.label,
root
};
addOption(opt);
return {
opt,
root,
}
}
})
const VSelect = defineComponent({
template: `
<select><slot /></select>
nb options: {{ nbOptions }}
`,
setup() {
const { provide, options } = provideOptions();
provide();
const nbOptions = computed(() => options.value.length);
watchEffect(() => {
debugger;
options.value.forEach((opt) => console.log(opt.value.label))
});
return {
nbOptions,
}
}
})
const App = defineComponent({
template: `<VSelect>
<VOption :value="0" label="-" />
<VOption :value="1" label="First Value" />
<VOption :value="2" label="Second Value" />
</VSelect>`,
components: {
VSelect,
VOption
},
})
createApp(App).mount('#app')