导图概览
入口文件
App.vue -> src/main.ts -> index.html
对app调用use()可以开启路由,pinia等功能
vue2组件结构
<template>
<div class="my-component">
</div>
</template>
<script>
export default {
name: 'MyComponent',
data() {
return {
title: 'Vue 2 组件示例',
count: 0
};
},
methods: {
incrementCount() {
this . count += 1 ; // 这里通过this访问
}
}
};
</script>
<style scoped>
</style>
vue3组件结构
vue3 中兼容vue2,但是不建议混用
<template>
<div></div>
</template>
< script setup >
import { ref } from 'vue';
const title = ref('Vue 3 组件示例');
const count = ref(0);
function incrementCount() {
count. value += 1 ; // 这里没有this
}
// 可以直接返回 template
</script>
<style scoped>
</style>
setup 语法糖
<script setup></script>
自动return,且内容相当于在setup函数中 但是export要写在单独的script标签中
也可以使用 vite-plugin-vue-setup-extend 以支持写在setup script 的 name 属性中
核心API
computed
计算属性 let value = computed(()=>{}) 相当于自动计算依赖的effect,且修改state,相当于useMemo。自动缓存 。 value是一个ComputedRefImpl 只读。可读可写的需要自己写get & set 手动修改依赖项
watch
监听 watch(data,(newValue,oldValue)=>{}) 相当于使用effect;只能监视4种数据:ref,reactive,getter,上述内容的数组
- 默认监听的是对象/基本类型的地址,浅监视
- 可以通过option 开启deep : true 深监视
- reactive 定义的数据的监听默认开启 deep
- 监听对象的某个属性,且属性非对象,需要函数形式,属性是对象也建议使用函数形式
watchEffect
watchEffect(()=>{}) 不需要明确指出需要的依赖,会自动计算。默认执行一次
生命周期
生命周期 vue2
- 创建 创建前 beforeCreate,创建完毕 created
- 挂载 挂载前 beforeMount,挂载完毕 mounted
- 更新 更新前 beforeUpdate,更新完毕 updated
- 销毁 销毁前 beforeDestroy,销毁完毕 destoryed
生命周期 vue3
- 创建 setup
- 挂载 onBeforeMount,onMounted
- 更新 onBeforeUpdate,onUpdated
- 卸载 onBeforeUnmount,onUnmounted
-
自定义hook
- 直接写成js函数文件,可以使用钩子
路由
基本功能
- 路由配置 :配置模式 histroy,和KV组
- 路由使用 :
main.ts -> app.use(routes) - 路由跳转 :
<RouterLink to='' >to里面可以写path或者对象(path/name) |userRouter().push()/.replace() - 路由插槽 :
<RouteView>
传参
- 通过urlQuery传参 魔法字符串 | 通过对象query属性传值
- 通过params传参 router中:key占位,跳转的时候直接像子路径一样传入,魔法字符串 | 对象 param传参(path失效,必须用name)
- 使用props传参,在params传参的routers配置项基础上加props:true | 定义porps 回调,porps回调接受routeProxy参数
pinia
- 创建pinia和使用
app.createApp()
cosnt pinia = createPinia()
app.use(pinia)
add.mount("#app")
2. pinia数据存储
1. store 是一个Proxy(object)
const useCountStore = defineSotre('count',{
state(){
return {}
}
actions:{},
getters:{}
})
3. 使用组合式api,就像写一个reactHook一样使用,返回响应式的内容
-
数据修改
- 直接修改原state属性
- 通过$patch({}) 批量处理,patch是state对象
- 通过action调用store方法 , store.action,action中通过this.key修改内容
- 通过解构的需要使用toRef/storeToRef包裹,这里和react有区别,react可以解构的,因为react需要通过action修改数据,不关心响应式丢失
- 监听 store.$subscribe((mutate,state)=>{})
组件通信方式
props
props:props: 父组件直接传,加冒号传变量,子组件使用let props = defineProps(['key'])获取 使用withdefault配置默认值
自定义事件
@customEmit --> const emit = defineEmits([]) --> emit('haha')
发布订阅
任意组件通信:pubsub/$bus/mitt
const emitter = mitt()
emitter.on('eventName',()=>{})
emitter.emit('eventName')
emitter.off('eventName') // 组件卸载的时候要记得解绑
v-model
- 在html标签上是双向绑定,在组件标签上会传递modelValue和update:modelValue事件
//父组件传递的时候可以使用v-model:name对modelValue命名,所以可以传多个v-model
defineProps(['modelValue'])//vue2 叫 :value
const emit = defineEmits(['update:modelValue'])//vue2 叫 :input
对于原生标签 $event 就是事件对象
对于组件 $event 是触发事件的时候传递的数据
$attr (祖孙通信)
父组件传了props,但是子组件没有接收,在子组件中可以通过{{attr}} 获取 `<GrandChild v-bind="attr">`
$refs
通过ref获取到组件实例Proxy,组件通过defineExpose暴露组件数据。通过$refs批量获取子组件实例
$parent
在子组件中可以通过$parent获取父组件数据,父组件需要通过defineExpose暴露数据给子组件
Provide Inject
后代通信 provide('name',value) ,后代使用 let value = inject('name',default,) 获取内容
对比react的 provider context
插槽
-
默认插槽,标签中间传入的内容,在组件中slot渲染
-
具名插槽
v-slot:name --> <slot name=''v-slot 可以用 # 代替 -
作用域插槽 向slot 传递props,父元素在v-slot中可以获取到params。数据在子元素内,但是有父元素确定渲染方式
-
// 父元素.vue <template v-slot:name="params"> ...//可以使用params.a/.b </template> // 子元素.vue <slot a='' b=''/>
-
其他API
- shallowRef 追踪第一层的数据变化
- shallowReactive 追踪第一层的数据变化
- readonly
- shallowReadonly
- toRaw 读取响应式对象对应的普通对象,对其操作不引起页面更新
- markRaw 将数据永远转换为普通对象
- customRef 自定义接受一个回调函数必须返回get和set
- Teleport 将DOM渲染到其他节点上,类似于React中的createPortal
笔者才疏学浅,各位读者多多担待,不吝赐教。