const app = new Vue({})
Vue.use()
Vue.mixin()
Vue.component()
Vue.directive()
const app = Vue.createApp({})
app.use()
app.mixin()
app.component()
app.directive()




- v-enter --- v-enter-from
- v-leave-to --- vl-eave-to
- v-leave --- v-leave-from
- v-enter-to --- v-enter-to
options api 对应 react class componentcomposition api 对应 react hooks,setup 只会调用一次,hooks 可多次调用Proxy 代替 Object.definePropertyoptions api 中的 data methods computed… 可以发访问setup中的属性和方法setup中不能访问options api中的 data methods computed…render 函数)、两个参数:props:参数、context:上下文( attrs, slots, emit )setup(props, { attrs, slots, emit }) {
return {}
}
undefined ,通过 getCurrentInstance 获取实例import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
import {
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted
} from 'vue'
reference对象:创建一个包含响应式的引用对象,接受类型可以是基本类型,也可以是对象类型,除了 template 和reactive,需通过.value修改其值;Object.defineProperty,对象依赖于proxy;<template>
<p ref="elemRef">文字</p>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const elemRef = ref(null)
onMounted(() => {
console.log(elemRef.value)
})
</script>
reactive 的值会失去响应式import { ref, reactive } from 'vue'
const nameRef = ref('张三')
const state = reactive({
name: nameRef
})
</script>
ref类型并且两者保持引用关系;<script setup>
import { toRef, reactive } from 'vue'
const state = reactive({
age: 20,
name: '张三'
})
const ageRef = toRef(state, 'age')
</script>
ref,两者保持引用关系<script setup>
import { toRefs, reactive } from 'vue'
function useFeatureX() {
const state = reactive({
x: 1,
y: 2
})
return toRefs(state)
}
const { x, y } = useFeatureX()
</script>
<HelloWorld @onSayHello="sayHello" />
export default {
emits: ['onSayHello'],
setup(props, { emit }) {
emit('onSayHello', '内容')
}
}
<button @click="one($event) two($event)">click</button>
.valueimport { watch } from 'vue'
watch(
data, // 监听一个基本类型
// [data1,data2], // 监听多个 ref 基本属性
// objdata, // ref 引用类型
(newValue, oldValue) => {},
{ immediate: true } // 初始化监听
)
watch(
() => obj.xx, // 监听一个 reactive
// [ () => obj1.xx, () => obj2.xx ], // 监听多个 reactive
(newValue, oldValue) => {},
// { immediate: true , deep: true} // 引用类型设置深度监视
)
immediate:trueimport { watchEffect } from 'vue'
watchEffect(() => {
// ...
})
<my-input v-model="val" />
const val = ref('hello')
props: {
modelValue: String
},
const handler = (e: Event) => {
const targetValue = (e.target as HTMLInputElement).value
context.emit('update:modelValue', targetValue) // 相当于自定义modal $emit
}
<myComponent v-bind:age.sync="age"></myComponent>
<template>
<p>{{ age }}</p>
<user-info v-model:ageRef="age"></user-info>
</template>
<script>
import { reactive, toRefs } from 'vue'
import UserInfo from './UserInfo.vue'
export default {
name: 'VModel',
components: { UserInfo },
setup() {
const state = reactive({
age: '20'
})
return toRefs(state)
}
}
</script>
<template>
<input :value="ageRef" @input="$emit('update:ageRef', $event.target.value)" />
</template>
<script>
export default {
name: 'UserInfo',
props: {
ageRef: String
}
}
</script>
components:{
'my-component':() => import('./xx.vue')
}
import { defineAsyncComponent } from 'vue'
components:{
AsyncComponent: defineAsyncComponent(() => import('./xx.vue'))
}
直接将元素插入到某个节点之中
<teleport to="body">
...
</teleport>
用于实现异步,组件内部有两个插槽。
<Suspense>
<template>
<AsyncComponent/>
</template>
<template #fallback>
<span>loading...</span>
</template>
</Suspense>
before:
// 1
defineProps({
modelValue: {
type: Number,
required: true,
default: 0
}
})
// 2
defineProps(['modelValue'])
now:
const modelValue = defineModel<number>({ default: 0 })
before:
const emits = defineEmits<
SE<{
clickCount(num: number): void
}>
>()
const emits = defineEmits<{
(e: 'clickCount', num: number): void
}>()
now:
const emits = defineEmits<{
clickCount: [num: number]
}>()
<div>
<span>hello</span>
<span>{{ name }}</span>
<span :class="blue">张三</span>
<span :id="zhangsan">张三</span>
<span :id="lisi" :class="black">{{ obj.name }}</span>
</div>
import { createElementVNode as _createElementVNode, toDisplayString as _toDisplayString, normalizeClass as _normalizeClass, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createElementBlock("div", null, [
_createElementVNode("span", null, "hello"),
_createElementVNode("span", null, _toDisplayString(_ctx.name), 1 /* TEXT */),
_createElementVNode("span", {
class: _normalizeClass(_ctx.blue)
}, "张三", 2 /* CLASS */),
_createElementVNode("span", { id: _ctx.zhangsan }, "张三", 8 /* PROPS */, ["id"]),
_createElementVNode("span", {
id: _ctx.lisi,
class: _normalizeClass(_ctx.black)
}, _toDisplayString(_ctx.obj.name), 11 /* TEXT, CLASS, PROPS */, ["id"])
]))
}
以上TEXT 、PROPS 、CLASS 则为标记的不同类型,只会去比较有标记的区域,静态则不会进行对比。
