「这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战」。
1. Composition API 的设计动机?
2. 什么是Composition API ? 它的作用是什么?
- 一系列API的组合
- 把东西(数据、方法、computed、生存周期函数、....)注入到组件当中——集中到一个地方写
3.setup()
一个组件选项,在创建组件之前执行(beforeCreate与created之间执行),一旦 props 被解析,并作为组合式 API 的入口点
-
setup无法使用组件的其他东西(data、methods、 computed、...),也不要使用this
因为setup执行的过程中,组件中其它的东西都没有被创建
-
setup是同步的(不能使用async)
4. ref \ reactive\readonly
-
reactive
返回对象的响应式副本。
响应式转换是“深层”的——它影响所有嵌套 property。在基于 ES2015 Proxy 的实现中,返回的 proxy 是不等于原始对象的。建议只使用响应式 proxy,避免依赖原始对象。
-
ref
- 接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象具有指向内部值的单个 property
.value - 引用节点(html元素、组件)
- 接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象具有指向内部值的单个 property
// 引用节点
<div ref="elm"></div>
setup(){
const a = ref(null);
onMounted(() => {
console.log(a.value)
})
return {
a
}
}
- toRef
可以用来为源响应式对象上的某个 property 新创建一个 ref。然后,ref 可以被传递,它会保持对其源 property 的响应式连接。
const state = reactive({
foo: 1,
bar: 2
})
const fooRef = toRef(state, 'foo')
fooRef.value++
console.log(state.foo) // 2
state.foo++
console.log(fooRef.value) // 3
| ref——普通ref对象 | toRef——特殊ref对象 |
|---|---|
| 跟原始数据无关(深拷贝) | 依然会引用原始数据 |
| 重新渲染 | 不会触发渲染 |
- unRef
如果参数是一个 ref,则返回内部值,否则返回参数本身。这是 val = isRef(val) ? val.value : val 的语法糖函数
const a = ref(12)
const b = toRaw(a) // => { value: 12 } 连着value一块拿
const c = unRef(a) // => 12 unRef 是ref专用
- toRefs
将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的 ref。
- toRefs 只会为源对象中包含的 property 生成 ref。如果要为特定的 property 创建 ref,则应当使用 toRef。
const json = {a: xx, b: xxx}
toRefs(json) => {a: toRef(json,'a'), b: toRef(json,'b')}
- customRef
创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 track 和 trigger 函数作为参数,并且应该返回一个带有 get 和 set 的对象。
- readonly
保护所有操作:递归保护
const仅保护赋值、非递归
- 判断类型
- isReactive()
检查对象是否是由 reactive 或 readonly 创建的 proxy。
- isReadonly()
检查对象是否是由 readonly 创建的只读代理。
- isProxy()
检查对象是否是由 reactive 或 readonly 创建的 proxy。
- isRef()
检查值是否为一个 ref 对象。
非递归版本 shallowReactive() \ shallowRef()\shallowReadonly()
- 手动触发更新 triggerRef(ref对象)
5.raw
- toRaw
返回 reactive 或 readonly 代理的原始对象。这是一个“逃生舱”,可用于临时读取数据而无需承担代理访问/跟踪的开销,也可用于写入数据而避免触发更改。不建议保留对原始对象的持久引用。请谨慎使用。 对原始的数据进行操作,不会被监听
- markRaw
标记一个对象,使其永远不会转换为 proxy。返回对象本身。
//toRaw
setup(){
const a = reactive({json: { a: 12 }});
const json = toRow(a);
setTimeout(() => {
json.json.a++
a.json = {...json.json} //a.json = json.json 不会触发更新
})
}
6.computed
接受一个 getter 函数,并为从 getter 返回的值返回一个不变的响应式 ref 对象。
const count = ref(1)
const plusOne = computed(() => count.value + 1)
console.log(plusOne.value) // 2
plusOne.value++ // 错误
或者,它也可以使用具有 get 和 set 函数的对象来创建可写的 ref 对象。
const count = ref(1)
const plusOne = computed({
get: () => count.value + 1,
set: val => {
count.value = val - 1
}
})
plusOne.value = 1
console.log(count.value) // 0
7.watchEffect \ watch
- watchEffect
在响应式地跟踪其依赖项时立即运行一个函数,并在更改依赖项时重新运行它。
const a = reactive({count: 10})
const b = reactive({count: 11})
const stop = watchEffect((invalidate) => {
....
invalidate(() => {
})
})
stop()
- watch
cosnt stop = watch(a, () => {})
cosnt stop = watch([a,b], () => {})
cosnt stop = watch(() => {
return ...
}, () => {})
stop()
8. Provide / Inject
我们也可以在组合式 API 中使用 provide/inject。两者都只能在当前活动实例的 setup() 期间调用。
- 使用 Provide
在 setup() 中使用 provide 时,我们首先从 vue 显式导入 provide 方法。这使我们能够调用 provide 时来定义每个 property。
provide 函数允许你通过两个参数定义 property:
- property 的 name ( 类型)
- property 的 value
- 使用 inject 在 setup() 中使用 inject 时,还需要从 vue 显式导入它。一旦我们这样做了,我们就可以调用它来定义如何将它暴露给我们的组件。
inject 函数有两个参数:
- 要 inject 的 property 的名称
- 一个默认的值 (可选)
9. vue-router
import { createRouter, createWebHistory, createWebHashHistory, createMemoryHistory } from 'vue-router'
- createWebHistory 创建一个 History,即单页面应用程序中最常见的历史记录。应用程序必须通过 http 协议被提供服务。
- createWebHashHistory 创建一个 hash 历史记录。对于没有主机的 web 应用程序 (例如 file://),或当配置服务器不能处理任意 URL 时这非常有用。注意:如果 SEO 对你很重要,你应该使用 createWebHistory。
- createMemoryHistory 创建一个基于内存的历史记录。这个历史记录的主要目的是处理 SSR。它在一个特殊的位置开始,这个位置无处不在。如果用户不在浏览器上下文中,它们可以通过调用 router.push() 或 router.replace() 将该位置替换为启动位置。
createWebHistory(base) // 没有 base,应用托管在域名 `https://example.com` 的根目录下。
createWebHistory('/folder/') // 给出的网址为 `https://example.com/folder/`
import { createRouter, createWebHistory, createWebHashHistory, createMemoryHistory } from 'vue-router'
const routerHistory = createWebHistory()
const router = createRouter({
history: routerHistory,
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/login',
name: 'login',
component: Login,
meta: {
redirectAlreadyLogin: true
}
})
10. vuex
import { createStore } from 'vuex'
const store = createStore({
state: {
},
mutations:{
},
actions: {
},
getters: {
}
})