一、基础
1.扩展全局属性
内置的全局属性有以下这些
因此,我们可以直接在模板中使用
如果想要扩展全局属性,在main.js中,将自定义变量挂载globalProperties中,然后就可以在任意组件中进行使用了
2.内置指令
v-show 切换display:block|none来实现切换
v-memo 类似react usememo
3.响应式基础
3.1 ref
在模板中使用 ref 时,不需要附加 .value。为了方便起见,当在模板中使用时,ref 会自动解包(在模板渲染上下文中,只有顶级的 ref 属性才会被解包。)
可以通过 shallow ref 来放弃深层响应性。对于浅层 ref,只有 .value 的访问会被追踪。浅层 ref 可以用于避免对大型数据的响应性开销来优化性能、或者有外部库管理其内部状态的情况。
3.2 reactive
reactive() 的局限性
reactive() API 有一些局限性:
- 有限的值类型:它只能用于对象类型 (对象、数组和如
Map、Set这样的集合类型)。它不能持有如string、number或boolean这样的原始类型。 - 不能替换整个对象:由于 Vue 的响应式跟踪是通过属性访问实现的,因此我们必须始终保持对响应式对象的相同引用。这意味着我们不能轻易地“替换”响应式对象,因为这样的话与第一个引用的响应性连接将丢失:
- 对解构操作不友好:当我们将响应式对象的原始类型属性解构为本地变量时,或者将该属性传递给函数时,我们将丢失响应性连接:
ref的解包特性感觉要分好多种情况,有时候有有时候不行,😄感觉只要涉及到ref的都用value去取值是最保险的,而且容易区分reactive
4.计算属性
- 计算属性的返回值是ref对象,但因为和ref一样,存在解包特性,所以在模板中使用时,不需要带上value
- 我们经常说,computed和methods的区别是,computed有缓存,但是其只是对响应式依赖有缓存!!!,同理,watch也是只监听响应式数据
5.v-for
使用in和of均可
遍历对象时
const myObject = reactive({
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
})
<li v-for="(value, key, index) in myObject">
{{ index }}. {{ key }}: {{ value }}
</li>
v-if和v-for不能同时使用
6.v-on
模板编译器会通过检查 v-on 的值是否是合法的 JavaScript 标识符或属性访问路径来断定是何种形式的事件处理器。举例来说,foo、foo.bar 和 foo['bar'] 会被视为方法事件处理器,而 foo() 和 count++ 会被视为内联事件处理器。
// 在内联处理器中调用方法
<button @click="say('hello')">Say hello</button>
// 方法事件处理器
<button @click="say">Say hello</button>
事件修饰符
生命周期
二、API
1、组合式API
1.1、setup()
setup第一个参数是props,props是响应式的,不能解构;
第二个参数是
context,context中包含的attrs, slots, emit, expose是非响应式的,可以解构
1.2 computed
computed返回的是一个ref对象,通常是只读的,但是可以通过set,get的方式,使其可写
1.3 readonly
接受一个对象 (不论是响应式还是普通的) 或是一个 ref,返回一个原值的只读代理
<script setup>
import { ref, readonly } from 'vue';
const userAge = ref(23);
const myAge = readonly(userAge);
const handleAdd = () => {
// userAge.value++; myAge.value会变
myAge.value++; myAge.value值不变
};
</script>
<template>
<div class="card">
<button @click="handleAdd">add</button>
<p>我的年龄是{{ myAge }}</p>
</div>
</template>
<style scoped>
.read-the-docs {
color: #888;
}
</style>
1.4 toRef()
基于响应式对象上的一个属性,创建一个对应的 ref。这样创建的 ref 与其源属性保持同步:改变源属性的值将更新 ref 的值,反之亦然
const state = reactive({
foo: 1,
bar: 2
})
// 双向 ref,会与源属性同步
const fooRef = toRef(state, 'foo')
// 更改该 ref 会更新源属性
fooRef.value++
console.log(state.foo) // 2
// 更改源属性也会更新该 ref
state.foo++
console.log(fooRef.value) // 3
1.5 toRefs()
将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。每个单独的 ref 都是使用 toRef() 创建的
const state = reactive({
foo: 1,
bar: 2
})
const stateAsRefs = toRefs(state)
/*
stateAsRefs 的类型:{
foo: Ref<number>,
bar: Ref<number>
}
*/
// 这个 ref 和源属性已经“链接上了”
state.foo++
console.log(stateAsRefs.foo.value) // 2
stateAsRefs.foo.value++
console.log(state.foo) // 3
1.6 toRaw()
根据一个 Vue 创建的代理返回其原始对象
const foo = {}
const reactiveFoo = reactive(foo)
console.log(toRaw(reactiveFoo) === foo) // true
toRaw() 可以返回由 reactive()、readonly()、shallowReactive() 或者 shallowReadonly() 创建的代理对应的原始对象。
tips: 一定要注意,曾经花了一个晚上排查,最终发现问题出现在toRaw上面,使用toRaw返回的对象不是响应式的,后续的更改不会修改其响应式对象,所以追踪不到最新值!!!
1.7 markRaw()
将一个对象标记为不可被转为代理。返回该对象本身。