Compositon API
一、Composition API使用
1. 使用Vue3.0
先创建一个空文件夹,然后进入文件夹执行npm init -y
,再执行npm install vue@3.0.0-rc.1
安装vue3.0
创建index.html,vue3.0的使用
<body>
<div id="app">
x: {
{ position.x }} <br>
y: {
{ position.y }} <br>
</div>
<script type="module">
import {
createApp } from './node_modules/vue/dist/vue.esm-browser.js'
const app = createApp({
data () {
return {
position: {
x: 0,
y: 0
}
}
}
})
console.log(app)
app.mount('#app')
</script>
</body>
Vue 3.0 和 Vue2.0 的区别,成员要少很多,没有$开头, 使用方式和以前一样
2. setup、reactive的使用
- createAPP:创建Vue对象
- setup:CompositionAPI的入口
- reactive:创建响应式对象
<body>
<div id="app">
x: {
{ position.x }} <br>
y: {
{ position.y }} <br>
</div>
<script type="module">
import {
createApp, reactive } from './node_modules/vue/dist/vue.esm-browser.js'
const app = createApp({
setup () {
// 第一个参数 props,props是一个响应式对象,不能被解构
// 第二个参数 context, 包含:attrs、emit、slots
const position = reactive({
x: 0,
y: 0
})
return {
position
}
},
mounted () {
this.position.x = 2
}
})
console.log(app)
app.mount('#app')
</script>
</body>
二、 setup中的生命周期钩子函数
setup中使用生命周期函数,只需要在vue钩子函数首字母大写,并且钩子函数前面加上on,就可以了。setup是在组件初始化之前执行的,就是在created和beforecreate之间执行的,这两个生命周期的逻辑可言直接写在setup中
原本的生命周期中的destroy对应的是onUnmounted。
<body>
<div id="app">
x: {
{ position.x }} <br>
y: {
{ position.y }} <br>
</div>
<script type="module">
import {
createApp, reactive, onMounted, onUnmounted } from './node_modules/vue/dist/vue.esm-browser.js'
function useMousePosition () {
const position = reactive({
x: 0,
y: 0
})
const update = e => {
position.x = e.pageX
position.y = e.pageY
}
onMounted(() => {
window.addEventListener('mousemove', update)
})
onUnmounted(() => {
//当鼠标移动的时候显示鼠标移动的位置,当组件卸载时,鼠标移动的事件也要移除
window.removeEventListener('mousemove', update)
})
return position
}
const app = createApp({
setup () {
const position = useMousePosition()
return {
position
}
},
mounted () {
//this.position.x = 2//这里也可以改变position,但是为了都放在一个函数里面,采用setup。调用useMousePosition,这样功能简洁
}
})
console.log(app)
app.mount('#app')
</script>
</body>
三、reactive-toRefs-ref
-
上面的代码如果对position进行解构,x,y数据不是响应式的了
-
这里的 position 是响应式对象,因为在useMousePosition中调用了reactive 函数,把传入的对象包装成了 Proxy 对象,也就是说 position 就是 proxy对象,当 position 访问 x, y的时候会调用代理中的 getter 拦截收集依赖,变化的时候会调用 setter
-
reactive创建的响应式数据解构后不再是响应式,toRefs可以把响应式对象的所有属性也转化成响应式的,所以可以解构toRefs返回的对象,解构之后还是响应式数据。
-
使用 toRefs
import { createApp, reactive, onMounted, onUnmounted, toRefs } from './node_modules/vue/dist/vue.esm-browser.js' ... return toRefs(position)//函数里返回position的地方包裹一下toRefs,把x,y也转化成响应式的
-
-
toRefs原理
toRefs 要求传入的参数 必须为代理对象,当前的 position 就是 reactive返回的代理对象,如果不是的话,会发出警告,提示传递代理对象,
内部会创建一个新的对象,然后遍历传入代理对象的所有属性,把所有属性的值都转换成响应式对象,相当于将postion 的x, y属性转换成响应式对象,
挂在到新创建的对象上,最后把新创建的对象返回。内部为代理对象的每一个属性创建一个具有 value 属性,value属性具有 getter,setter, getter 中返回对象属性的值,
setter中给代理对象赋值。所以返回的每一个属性都是响应式的 -
reactive是将普通对象转化成响应式对象,而ref是将基本类型数据包装成了响应式对象。
- ref的使用:
<body> <div id="app"> <button @click="increase">Button</button> <span>{ {count}}</span> </div> <script type="module"> import { createApp, ref } from './node_modules/vue/dist/vue.esm-browser.js' function useCount () { const count = ref(0) // 将基本类型数据转化成响应式对象 return { count, increase: () => { count.value++ } } } createApp({ setup () { return { ...useCount() } } }).mount('#app') </script> </body>
四、Computed
computed可以创建一个响应式数据,这个响应式数据依赖于其他响应式数据,就是计算属性。
-
第一种用法
- computed(() => count.value + 1)
-
第二种用法
const count = ref(1) const plusOne = computed({ get: () => count.value +