Allows you to create "detached" reactive values
import Vue from 'vue';
// create reactive state.
const state = Vue.observable({
x: 0,
y: 0
});
// Previously if you needed to do that:
const state = new Vue({
data: () => ({
x: 0,
y: 0
})
});
<MousePosition v-slot="{ x, y }">
<div>x: {{ x }}</div>
<div>y: {{ y }}</div>
</MousePosition>
Example: Mouse Position Component
import Vue from 'vue';
// create reactive state.
const state = Vue.observable({
x: null,
y: null
});
// Handle position updates.
const updatePosition = e => {
state.x = e.pageX;
state.y = e.pageY;
};
let isDoneSetup = false;
export const MousePosition = {
name: 'MousePosition',
functional: true,
render(_, { scopedSlots }) {
if (!isDoneSetup) {
document.addEventListener('mousemove', updatePosition);
isDoneSetup = true;
}
// render the scoped slot.
return scopedSlots.default(state);
}
};
import { onMounted, onUnmounted, value, createElement as h } from "vue";
function useMouse() {
const x = value(0);
const y = value(0);
const update = e => {
x.value = e.pageX;
y.value = e.pageY;
};
onMounted(() => {
window.addEventListener("mousemove", update);
});
onUnmounted(() => {
window.removeEventListener("mousemove", update);
});
return { x, y };
}
export default {
setup() {
const { x, y } = useMouse();
return () => {
return h("div", {}, `${x.value} ${y.value}`);
};
}
};
Hint: JavaScript execution is single-threaded.