Vue的几个compose模式
大约 3 分钟
Vue的几个compose模式
单文件+Composition 的文件格式
/////代码层
<script setup>
//导入区
import {} form 'vue'
import {} form 'child.vue'
//导出变量区
const props = defineProps({msg: String})
//导出事件区
const emit = defineEmits(['response'])
emit('response', 'hello from child')
//响应常量区
const foo = ref(0)
const text = ref(``)
const str = ref(`zheyang`)
const titleClass = ref(`title`)
//属性-计算属性体系
const todos = ref([
{ id: id++, text: 'Learn HTML', done: true },
{ id: id++, text: 'Learn JavaScript', done: true },
{ id: id++, text: 'Learn Vue', done: false }
])
const filteredTodos = computed(() => {
return hideCompleted.value
? todos.value.filter((t) => !t.done)
: todos.value
})
//
const name = ref('Hello')
const title = computed(() =>`${name.value} - World`)
//变量侦听器体系
const count = ref(0)
watch(count, (newCount) => {
console.log(`new count is: ${newCount}`)
})
//函数区
function afterClick(){
}
function xxX(){}
function increment() {
count.value++
}
//生命周期区
onMounted(() => {
p.value.textContent = 'mounted!'
})
</script>
/////模版页面层
<template>
<h1 :class='titleClass'>Make me red</h1>
<input v-model='text'>
<button @click='increment'>{{ count }}</button>
<p ref='p'>hello</p>
<slot>Fallback content</slot>
</template>
/////CSS样式层
<style>
.title {
color: red;
}
</style>
关键之处在于:三重映射
css->(id,class)->template->(属性的值,插槽内绑定的文本值)->script setup
我们主要要分清楚一个赋值语句的两个地方——等号左边和等号右边(对象内是冒号左边和冒号右边)
即:变量名=变量值
在script setup内,定义了 变量名=变量值。
在template内,在属性内,通过''(最好用单引号)引用了表达式。在插槽内,通过引用了表达式
属性id、class引用到的变量名的具体的变量值,作为css的class选择器、id选择器名。
在style内,定义选择器。
生命周期
说是生命周期,其实就是触发事件。
前端其实就是一个页面渲染工程,总共有如下事件——
加载数据->渲染页面->根据数据更新渲染页面->组件不再使用时更新渲染页面
等等。
在vue中,对应:
vue的数据对象的创建->dom树的初始化渲染->数据更新同时渲染dom->组件卸载
在对应的事件发生前后,有不同的数据被加载着。

组合式 API:生命周期钩子 | Vue.js (vuejs.org)
设计模式
https://www.bilibili.com/video/BV1x54y1V7H6
https://talks.antfu.me/2021/vueconf-china
接受ref作为函数参数
值类型使用ref,对象类型使用reative
接受Ref作为参数,返回一一个响应式的结果
function add(a: Ref<number>, b: Ref<number>) {
return computed(() => a.value + b.value)
}
const a = ref(1)
const b = ref(2)
const c = add(a, b)
c.value // 3
同时接受传入值和Ref
function unref<T>(r: Ref<T> | T): T {
return isRef(r) ? r.value : r
}
function add(
a: Ref<number> | number,
b: Ref<number> | number
) {
return computed(() => unref(a) + unref(b))
}
const a = ref(1)
const c = add(a, 5)
c.value // 6
MaybeRef类型工具
type MaybeRef<T> = Ref<T> | T
让你的函数变得更灵活
重复使用已有Ref
const foo = ref(1) // Ref<1>
const bar = ref(foo) // Ref<1>
foo === bar // true
Ref体系
ref->得到ref
unref->得到值
type MaybeRef<T> = Ref<T> | T
function useBala<T>(arg: MaybeRef<T>) {
const reference = ref(arg) // 得到 ref
const value = unref(arg) // 得到值
}
Ref组合对象
import { ref, reactive } from 'vue'
function useMouse() {
return {
x: ref(0),
y: ref(0)
}
}
const { x, y } = useMouse() //得到ref
const mouse = reactive(useMouse()) //得到自动解包的reactive
mouse.x === x.value // true
异步编程->先构建数据引用,再等待填充
副作用自动清除
Vue中原生的watch、computed API会在组件销毁时自动解除其内部的依赖监听。我们可以编写我们的函数时,遵循同样的模式。
import { onUnmounted } from 'vue'
export function useEventListener(target: EventTarget, name: string, fn: any) {
target.addEventListener(name, fn)
onUnmounted(() => {
target.removeEventListener(name, fn) // <--
})
}