在vue3.0引入了composition API , setup函数是其核心函数
在setup函数中,可以使用ref函数,用于创建一个响应式数据,当数据发生改变时,Vue会自动更新UI
例如:使用ref函数定义一个变量count
import { ref } from 'vue';
function useChangeCount() {
let count = ref(0);
function change_count() {
count.value += 1;
}
return { count, change_count }
}
export default useChangeCount;
然后在组件中引入该模块:import useChangeCount from "./composition_tiny_js/count"
并且在组件的setup中使用,并通过return的形式将外界需要用到的变量和函数暴露出去
setup() {
let { count, change_count } = useChangeCount();
return { count, change_count };
}
这样上面暴露的count变量,change_count方法就可以在外界使用了
需要注意的是:
在setup中定义的变量或方法,都必须通过return {xxx,xxx}暴露出去,外界才能使用
ref函数仅能监听基本类型的变化,不能监听复杂类型的变化(比如对象、数组 [ 详见reactive() ])
reactive创建响应式对象,将数据变成响应式数据,当数据发生变化时UI也会自动更新。
reactive的用法与ref的用法相似,不同的是ref用于基本数据类型,而reactive是用于复杂数据类型,比如对象和数组。
setup() {
const form = reactive({
oldPassword: '',
newPassword: '',
...
})
return {
form
}
},
ref允许我们创建一个任意类型的响应式的ref对象,在使用时需要带上.value
模板中使用ref对象时,假如ref位于顶层,就不需要使用value,它会自动解包
但如果ref对象是作为一个属性声明于对象之中,在模板中进行运算时仍然要使用.value
通常使用reactive()来创建一个响应式的对象或数组,这样的对象或数组状态都是默认深层响应式的,无论嵌套多深,都能跟踪到。
但他也有局限性,就是只对 对象类型有效,对基本数据类型无效
并且假如用一个新对象替换了原来的旧对象,那么原来的旧对象会失去响应性
1、ref多用来定义基本数据类型(也可以定义对象,内部会自动通过reactive转为代理对象),而 reactive只能用来定义对象数组类型
2、ref操作数据需要.value,reactive操作数据不需要.value
3、ref通过Object.defineProperty()的get和set来实现响应式, reactive通过Proxy来实现响应式,并通过Reflect操作源对象内部的数据
let obj = { name: "aa", age: 18 };
let state = reactive(obj);
console.log(obl === state) false
state 和 obj是引用关系,state的本质是一个Proxy对象,在这个Proxy对象中引用了obj
如果想通过toRaw拿到ref类型的原始数据(创建时传入的那个数据)
必须明确的告诉toRaw方法,要获取的是.value的值
因为经过Vue处理之后,.value中保存的才是当初创建时传入的那个原始数据
isRef: 检查一个值是否为一个 ref 对象
isReactive: 检查一个对象是否是由 reactive 创建的响应式代理
isReadonly: 检查一个对象是否是由 readonly 创建的只读代理
isProxy: 检查一个对象是否是由 reactive 或者 readonly 方法创建的代理
// isRef: 检查一个值是否为一个 ref 对象
console.log(isRef(ref({}))); // true
// isReactive: 检查一个对象是否是由 reactive 创建的响应式代理
console.log(isReactive(reactive({}))); // true
// isReadonly: 检查一个对象是否是由 readonly 创建的只读代理
console.log(isReadonly(readonly({}))); // true
// isProxy: 检查一个对象是否是由 reactive 或者 readonly 方法创建的代理
console.log(isProxy(readonly({}))); // true
console.log(isProxy(reactive({}))); // true