“使用data、computed、methods、watch 组件选项来组织逻辑通常都很有效。然而,当我们的组件开始变得更大时,逻辑关注点的列表也会增长。尤其对于那些一开始没有编写这些组件的人来说,这会导致组件难以阅读和理解。”。
“这种碎片化使得理解和维护复杂组件变得困难。选项的分离掩盖了潜在的逻辑问题。此外,在处理单个逻辑关注点时,我们必须不断地“跳转”相关代码的选项块。” – vue官网
为了 将业务的 数据 和逻辑 结合在一起,Vue 3.0 提供了 组合式 API
vue3.0 提供了 setup函数,作为组合式API的入口:
<template>
<div>{{count}}div>
template>
<script>
import {ref} from 'vue'; // 关于 ref 的疑问 请往下看
export default {
setup() {
// setup 是组合API的入口函数
// 定义数据
let count = ref(0);
// 定义函数,实现相关逻辑
// 在组合api 中定义function,不用在 methods 中,直接定义即可
function addCount() {
count ++;
}
// 注意,在组合式api中定义的变量/方法 要想在外界使用,必须通过return暴露出去
return {count,addCount}
}
}
script>
⚠️注意:
在 setup 中你应该 避免使用 this,因为它不会找到组件实例。setup 的调用发生在 data property、computed property 或 methods 被解析之前,所以它们无法在 setup 中被获取。
在运行时,将在 setup 中return 的变量,添加到 data 中,将return 出来的函数 添加到 methods 中。
如 上述代码,实际就是:
export default {
data() {
return {
count: 0
}
},
methods: {
function addCount() {
this.count ++;
}
}
}
Vue 3.0 给我们提供了 一些新的函数 创建响应式变量,包括:
ref 是vue3.0提供的将 简单类型数据 转成响应式数据的方法(ref本质是下边的 reactive方法),用法如下
<template>
<div>{{counter}}div>
template>
<script>
import { ref } from 'vue'
export default {
setup() {
const counter = ref(0)
console.log(counter) // { value: 0 }
console.log(counter.value) // 0
counter.value++
console.log(counter.value) // 1
return {counter}
}
}
script>
reactive是VUE3.0中提供的实现响应式数据的方法。
在Vue2.0中使用的是defineProperty来实现的,而VUE3.0中使用的是ES6里的proxy实现的
reactive中需要注意的点:
reactive 使用如下:
<template>
<div>{{state.name}}div>
template>
<script>
import { reactive } from 'vue'
export default {
setup() {
const state = reactive({name: '李白'})
return {state}
}
}
script>
使用 ref 创建的变量,在template编译时会自动加上.value,使用reactive创建的变量不会自动加上 .value
由ref 创建的变量会带上一个私有变量 __v_isRef
export default {
setup() {
const state = reactive({name: '李白'})
const age = ref(20);
console.log(age);
console.log(state);
return {age, state}
}
}
Vue3.0 提供了 isRef 和 isReactive 两个方法区分
<script>
import { ref,reactive, isRef, isReactive} from 'vue'
export default {
setup() {
const state = reactive({name: '李白'})
const age = ref(20);
console.log(isRef(age), isReactive(age)); // true false
console.log(isRef(state), isReactive(state)); // false true
return {age, state}
}
}
</script>