前言
在学习了vue3
一些特性之后,我们可以在项目中简单的使用这些特性。不过,对于以前用vue2.x
写的项目,我们可以通过引入composition-api
,使用vue3
中的新特性。
引入composition-api
首先,我们先引入composition-api
。
npm i @vue/composition-api -S
使用
import Vue from 'vue'
import VueCompositionApi from '@vue/composition-api'
Vue.use(VueCompositionApi)
生命周期的变化
beforeCreate-> 使用 setup()created-> 使用 setup()- beforeMount -> onBeforeMount
- mounted -> onMounted
- beforeUpdate -> onBeforeUpdate
- updated -> onUpdated
- beforeDestroy -> onBeforeUnmount
- destroyed -> onUnmounted
- errorCaptured -> onErrorCaptured
生命周期的钩子跟原先的差不多,理解起来很容易,属于看一眼就懂的那种。
setup
setup
相当于是组件的入口了,可以调用所有组合函数。最后的return
,可以作为出口,确认要暴露给模板哪些内容。setup
接收两个参数,props和context
,。
setup(props, context) {
//
return {}
},
- props:跟 2.x 的 props 一样,接受父组件传过来的值。
- context:是一个上下文对象,包含了一些
2.x
this中的属性。如:
attrs: Object // => this.$attrs
emit: f() // => this.$emit
isServer: false // 是否服务端渲染
listeners: Object // => this.$listeners
parent: VueComponent // => this.$parent
refs: Object // => this.$refs
root: Vue // => main.js 中的全局唯一的 vue 实例
slots: {} // => this.$slots
ssrContext: {} // => 服务端渲染
reactive
对于响应式数据,我们可以通过reactive
来创建。响应式转换是基于es6
中的proxy
实现的,返回的是一个代理后的对象,并不等于原始对象。
<template>
<div class="hello">
<h1>{{ state.count }}</h1>
<button @click="addCount">加</button>
</div>
</template>
<script>
import { reactive } from '@vue/composition-api'
export default {
setup() {
const state = reactive({
count: 0
})
const addCount = () => {
state.count++
}
return { state, addCount }
}
}
</script>
toRefs
上面的栗子中,我们在模板中使用的是 state.count
这种方式,获取响应式的数据。如果要把
{{ state.count }}
写成{{ count }}
,就需要用toRefs
了。
import { reactive, toRefs } from '@vue/composition-api'
export default {
setup() {
const state = reactive({
count: 0
})
return {...toRefs(state)}
}
}
watch
watch
用来监听一个或多个数据的变化,并在回调中执行副作用。
setup() {
const state = reactive({
count: 0,
msg: 'ha'
})
// 监听一个数据的变化
watch(
() => state.count,
(count, preCount) => {
console.log(count, preCount)
}
)
// 监听多个数据的变化
watch([() => state.count, () => state.msg], ([count, msg], [preCount, preMsg]) => {
console.log(count, msg, preCount, preMsg)
})
const addCount = () => {
state.count++
}
return { ...toRefs(state), addCount }
}
使用watchEffect
监听数据的变化。
watchEffect(() => {
console.log(state.count)
})
-
watch 与 watchEffect 的区别
-
watchEffect 在组件初始化时,立即执行传入的一个副作用函数。并且在副作用函数中使用的属性有变化时,会重新执行。需要注意,当副作用函数中执行的函数,若该函数又改变了响应式的数据,可能会造成死循环问题。
-
watch 是监听指定的属性,当指定属性变化时,才会执行回调。watch 可以接收指定的一个或多个属性。 watch中可以获取状态变化前后的值。
-
组件通信
-
emit
// 父组件
<template>
<div class="hello">
<h1>{{ count }}</h1>
<add @addCount="addCount" />
</div>
</template>
<script>
import { reactive, toRefs } from '@vue/composition-api'
import Add from './Add'
export default {
setup() {
const state = reactive({
count: 0
})
const addCount = () => {
state.count++
}
return { ...toRefs(state), addCount }
},
components: {
Add
}
}
</script>
-------------------------------------------
// 子组件 add.vue
<template>
<button @click="addCount">加</button>
</template>
<script>
export default {
setup(props, { emit }) {
const addCount = () => {
emit('addCount')
}
return { addCount }
}
}
</script>
-
使用 2.x 的 store
在context.root 中,我们可以获取到2.x 中的this.$store。
<template>
<button @click="addCount">+{{ count }}</button>
</template>
<script>
import { computed, reactive, toRefs } from '@vue/composition-api'
export default {
setup(props, { root }) {
const store = root.$store
const state = reactive({
// 获取 store 中的值
count: computed(() => store.state.count)
})
const addCount = () => {
// 改变 store 中的值
store.commit('increase')
}
return { ...toRefs(state), addCount }
}
}
</script>
----------------------------------------
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
count: 1
}
const mutations = {
increase(state) {
state.count++
}
}
export default new Vuex.Store({
state,
mutations
})
router
对于router
来说,我们可以使用root.$options.router
获取,相当于this.$router
。