The combination of Vue3.0 and Typescript is getting more and more trending, let's check how to build single file components using them and understand how it works.
Composition API
One of the most important changes in Vue3.0 is the Composition API
,Vue3.0 is backwardly compatible with the Options API
, but using the Composition API
grants you more power for code sharing.
you can find a detailed cheatsheet about composition API here
Going through the cheetsheet we can have a basic understanding of composition API:
- replacing mixins
- better code sharing across components
The composition API gets rid of mixins, using a mixin in Vue2.0 would be like:
import Mixin from "./Mixin.js";
export default {
mixins: [Mixin],
data: () => ({
data1: null
}),
methods: {
method1 () { ... }
}
}
back in 2016 Dan Abramov wrote an article called Mixins Considered Harmful
, the harm he mentioned was basically using mixin is an anti-pattern and would not recommend it. The same drawback applies to both React and Vue:
- naming collisions
- names used in mixins could confront with the one in the file that uses it
- implicit dependencies
- mixins can use methods or properties in the file too, which causes confusion, especially when refactoring code developer may omit details in mixins and causes confusion
in composition API, rather than defining a component's functionality (state, methods, computed, etc.) as an object property, we define them as JS variables that get returned from a new setup
function
// define reactive variable that functions pretty much the same as a data variable
import {ref, computed } from "vue";
export default {
setup(){
const count = ref(0);
const double = computed(() => count.value * 2)
function increment(){
count.value++;
}
return {
count,
double,
increment
}
}
while we can definitely extract the common logic to a single file
// useCounter.js
import { ref, computed } from "vue";
export default function () {
const count = ref(0);
const double = computed(() => count.value * 2)
function increment() {
count.value++;
}
return {
count,
double,
increment
}
}
and the code can be reused in another component by importing it.
// MyComponent.js
import useCounter from "./useCounter.js";
export default {
setup() {
const { count, double, increment } = useCounter();
return {
count,
double,
increment
}
}
}
notice here we need to use states or methods from logic by importing them explicitly, thus solving the naming collision
issue
Top comments (0)