vueschool.io
@vueschool_io
Author of The Majesty of Vue.jsย 1 & 2
Founder & Teacher @ Vue School
Enterprise Consultant
Vue.js Contributor
Amsterdam
Our goal
280+ Video Lessons
60000 users
Alex Kyriakidis
Rolf Haug
Debbie O'Brien
Chris Fritz
Maria Lamardo
Roman Kuba
Sรฉbastien Chopin
Filip Rakowski
Alexander Lichter
Lydia Hallie
new Vue({
data: {
loading: false,
count: 0,
user: {}
},
computed: {
double () { return this.count * 2 },
fullname () {/* ... */}
},
methods: {
increment () { this.count++ },
fetchUser () {/* ... */}
}
})
๐ smaller + ๐โโ๏ธ faster
๐ improved TypeScript support
๐ more maintainable codebase
๐งฑ exposes lower level APIs
โญ๏ธ new features
๐ coming In a few Months
๐ค most user code remains the same
๐ท pre-alpha
๐ advanced feature
๐ options API is not being deprecated
โ addition to the current API
(Pre Alpha - RFC Status)
a set of lower level APIs
use Vue features outside of Vue components
New!
New!
import {ref, computed, watch} from 'vue'
the setup option
Vue Components
using setup
new Vue({
beforeCreate () {
},
setup () {
},
created () {
}
})
the setup option
the setup option
<template>
<button @click="increaseCount">count {{count}} | double {{double}}</button>
</template>
<script>
import {computed, ref} from 'vue'
export default {
setup () {
const count = ref(0)
const double = computed(() => count.value * 2)
const increaseCount = () => {
count.value++
}
return {increaseCount, count, double} // render context - unwrapped
},
mounted () {
this.count = 40
this.increaseCount()
}
}
</script>
the setup option
ButtonCounter.vue
โป๏ธ Logic Reuse
๐ Code Organization
๐ Improved TypeScript Support
import axios from 'axios'
import orderBy from 'lodash.orderby'
export default {
data () {
return {
characters: [],
loadingState: null,
orderKey: 'id'
}
},
computed: {
charactersOrdered() {
return orderBy(this.characters, this.orderKey)
}
},
methods: {
fetchAllCharacters () {
this.loadingState = 'loading'
axios.get('https://rickandmortyapi.com/api/character')
.then(response => {
setTimeout(() => {
this.loadingState = 'success'
this.characters = response.data.results
}, 1000)
})
},
setOrderKey(key) {
this.orderKey = key
}
},
created () {
this.fetchAllCharacters()
}
}
import axios from 'axios'
import orderBy from 'lodash.orderby'
import {computed, ref} from '@vue/composition-api'
export default {
setup () {
const characters = ref([]) // use const because you dont want to lose this value
const loadingState = ref(null)
const fetchAllCharacters = () => {
loadingState.value = 'loading'
return axios.get('https://rickandmortyapi.com/api/character')
.then(response => {
loadingState.value = 'success'
characters.value = response.data.results
})
}
const orderKey = ref('id')
const charactersOrdered = computed(() => {
return orderBy(characters.value, orderKey.value)
})
const setOrderKey = (key) => {
orderKey.value = key
}
return {characters, loadingState, fetchAllCharacters, charactersOrdered, orderKey, setOrderKey}
},
created () {
this.fetchAllCharacters()
}
}
<script>
import {computed, ref} from 'vue'
const useCounter = () => {
const count = ref(0)
const double = computed(() => count.value * 2)
const increaseCount = () => {
count.value++
}
return {count, double, increaseCount}
}
export default {
setup () {
const {increaseCount, count, double} = useCounter()
return {increaseCount, count, double} // render context
}
}
</script>
<script>
import {computed, ref} from 'vue'
const useCounter = (initial = 0) => {
const count = ref(initial)
const double = computed(() => count.value * 2)
const increaseCount = () => {
count.value++
}
return {count, double, increaseCount}
}
export default {
setup () {
const {increaseCount, count, double} = useCounter(40)
return {increaseCount, count, double}
}
}
</script>
Can extract to another file
<template>
<div>
<div
v-for="character in characters"
:key="character.id"
>
<!-- character card -->
</div>
<div v-if="loadingState === 'loading'">Loading...</div>
</div>
</template>
CharacterCards.vue
import axios from 'axios'
export default {
data () {
return {
characters: [],
loadingState: null,
}
},
methods: {
fetchCharacters () {
this.loadingState = 'loading'
axios.get('https://rickandmortyapi.com/api/character')
.then(response => {
this.loadingState = 'success'
this.characters = response.data.results
})
}
},
created () {
this.fetchCharacters()
}
}
CharacterCards.vue
import {ref} from 'vue'
import axios from 'axios'
export default function useFetchResource (url) {
const data = ref([])
const loadingState = ref(null)
const fetchResource = () => {
loadingState.value = 'loading'
return axios.get(url)
.then(response => {
loadingState.value = 'success'
data.value = response.data.results
})
}
return {data, loadingState, fetchResource}
}
fetchResource.js
<script>
import useFetchResource from '../use/fetchResource'
export default {
setup () {
const {data, loadingState, fetchResource} = useFetchResource('rickandmortyapi.com/...')
return {
characters: data,
loadingState,
fetchAllCharacters: fetchResource
}
},
created () {
this.fetchAllCharacters()
}
}
</script>
CharacterCards.vue
<template></template>
<script>
import useMousePosition from '../use/mousePosition'
export default {
setup () {
const {x, y} = useMousePosition()
// ...
}
}
</script>
Respective Drawbacks when compared with the Composition API
vueschool.io
vueschool.io
vueschool.ioย ย ย ย ย @vueschool_io
@hootlex
Vue.js 3 courses
coming soon
vueschool.io