前端前端vue重读vue3
omi基础
风格指南
结构风格
vue推荐: 先声明,后使用
<script setup></script> <template></template> <style scoped></style>
|
子组件命名
<ButtonCounter />
<button-counter />
|
方法命名
<MyComponent @some-event="callback" />
|
cdn方式使用
<script type="module"> import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js' </script>
<script type="importmap"> { "imports": { "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js" } } </script> <script type="module"> import { createApp } from 'vue' </script>
|
全局处理
app.config.errorHandler = (err) => {}
app.component('Component', Component)
|
多实例挂载
const app1 = createApp(...) app1.mount('#app1')
const app2 = createApp(...) app2.mount('#app2')
|
自定义全局暴露
vue内部沙盒化,只会暴露常用Math和Date等全局对象
app.config.globalProperties.window = window
|
动态参数
值为null意为显式移除该绑定
<a :[attributeName]="url" @[eventName]="fn">...</a>
|
响应语法糖
实验性质:不要混用也不要在生产环境使用💩
$event变量
<button @click="warn('Form cannot be submitted yet.', $event)"> Submit </button>
<button @click="(event) => warn('Form cannot be submitted yet.', event)"> Submit </button>
|
checkbox自定义真假值
<input type="checkbox" v-model="toggle" true-value="yes" false-value="no" />
|
动态组件
<component :is="tabs[i]"></component>
|
进阶
watch vs watchEffect
import { watch, watchEffect } from 'vue'
watch(key, async (newVal) => { newVal && (user.value = await (fetch(`https://jsonplaceholder.typicode.com/todos/${key.value}`).then(res => res.json()))) })
watchEffect(async () => { key.value && (user.value = await (fetch(`https://jsonplaceholder.typicode.com/todos/${key.value}`).then(res => res.json()))) })
|
插槽
<Component> <template #name>具名插槽</template> <span v-slot="{message}">默认插槽 {{ message }}</span> </Component>
<slot name="name"></slot> <slot></slot>
<Component v-slot="{message}" /> <Component> <template #header="{message}"> {{ message }} </template> </Component> <slot message="插槽解构"></slot>
|
依赖注入
import { provide, readonly } from 'vue' provide(k, readonly('v'))
import { inject } from 'vue' const v = inject(k)
|
异步组件
import { defineAsyncComponent } from 'vue' const AsyncComp = defineAsyncComponent(() => import('./components/MyComponent.vue') )
|
编译器宏
编译器宏在setup中不需要导入
- defineExpose
- defineEmits
- defineProps
- defineModel
watchEffect
watchEffect(async () => { const response = await fetch( `https://jsonplaceholder.typicode.com/todos/${todoId.value}` ) data.value = await response.json() })
|
defineModel
<script setup> import { ref } from 'vue' import Child from './Child.vue'
const title = ref('') </script> <template> <MyComponent v-model:title="title" /> {{ title }} </template>
<script setup> const title = defineModel('title') </script> <template> <input v-model="title" /> </template>
|
defineCustomElement与shadow dom(原生)
const CustomElement = defineCustomElement({ props: { msg: String }, template: `<div>{{ msg }}</div>` })
customElements.define('mine-element', CustomElement)
|
指令hook
const myDirective = { created(el, binding, vnode, prevVnode) {}, beforeMount(el, binding, vnode, prevVnode) {}, mounted(el, binding, vnode, prevVnode) {}, beforeUpdate(el, binding, vnode, prevVnode) {}, updated(el, binding, vnode, prevVnode) {}, beforeUnmount(el, binding, vnode, prevVnode) {}, unmounted(el, binding, vnode, prevVnode) {} }
|
内置组件
Transition的6种状态
<Transition name="fade">...</Transition>
<style lang="scss" scoped> .fade-enter-active, .fade-leave-active { transition: opacity 0.5s ease; }
.fade-enter-from, .fade-leave-to { opacity: 0; } </style>
|
ts与组合式api
defineProps
<script lang="ts" setup>
const { name, age = 20 } = defineProps<{ name: string age?: number }>() </script>
<template> {{ name }} {{ age }} </template>
|