// 1interface Config {name: string;}props: {config: Object as PropType<Config>,required: true}// 2 readonlyconst PropType = {msg: string,age: {type: Number,required: true}} as constexport default defineComponent({name: '',props: PropType})
// 需要加上 eslint 忽略const image = require("./assets/logo.png") // eslint-disable-line
const numRef = ref(1)setInterval(() => {numRef.value += 1})// setup 只会执行一次, 此处 num 不会新增const num = numRef.valuesetup(){// 注意,应该写在这const num = numRef.valuereturn () => {h('div', num)}}
const yourRef = ref({})onMounted(() => {yourRef.value.doValidate()})<JSONSchemaForm contextRef={yourRef} />
css in js :vue-jss
<script setup lang="ts">import { defineEmits, defineProps, watchEffect } from 'vue'const props = defineProps<{ msg: string }>()const emit = defineEmits<{(e: 'change', id: number): void(e: 'update', value: string): void}>()watchEffect(() => console.log(props.msg))</script>
// context.tsexport const uniqueKey = Symbol()// 父组件<script setup lang="ts">import { provide, reactive } from 'vue'const data = reactive({ data: { a: 1 } })provide(uniqueKey, data)</script>// 子组件<script setup lang="ts">import { inject, watchEffect } from 'vue'const data = inject(uniqueKey)watchEffect(() => {// 此时 data 是响应式的,可以监听到console.log(data)})</script>
setup () {const context: { a: number; } | undefined = {a: 1}if(!context) {throw Error('should not be undefined')}return () => (<div>1</div>)}
// ctx 在生产环境里拿不到const { ctx } = getCurrentInstance()// 可以const { proxy } = getCurrentInstance()
// 纯函数function sum(a: number, b: number) {return a + b}sum(1, 2)// 接收 Ref 作为函数参数,返回响应式结果function sum1(a: Ref<number>, b: Ref<number>) {return computed(() => a.value + b.value)}const a = ref(1)const b = ref(2)const c = sum1(a, b)c.value // 3// 同时传入 ref 和 number 类型function sum2(a: Ref<number> | number, b: Ref<number> | number) {return computed(() => unref(a) + unref(b))}const a = ref(1)const c = sum2(a, 5)c.value // 6
// 例子import { computed, unref, Ref } from 'vue'// 类型type MaybeRef<T> = Ref<T> | Texport function useTimeAgo(time: MaybeRef<Date | number | string>,) {return computed(() => someFormating(unref(time)))}
import { useTitle } from '@vueuse/core'const title = useTitle()title.value = 'Hello World'// 网页的标题随 Ref 改变// -----------------------------import { ref, computed } from 'vue'import { useTitle } from '@vueuse/core'const name = ref('Hello')const title = computed(() => {return `${name.value} - World`})useTitle(title) // Hello - Worldname.value = 'Hi' // Hi - World
const foo = ref(1) // Ref<1>const bar = ref(foo) // Ref<1>foo === bar // truefunction useFoo(foo: Ref<string> | string) {// 不需要额外操作const bar = isRef(foo) ? foo : ref(foo)// 与上面的代码等效const bar = ref(foo)/* ... */}
这个技巧在编写不确定参数类型的函数时十分有用。
import { ref, reactive } from 'vue'function useMouse() {return {x: ref(0),y: ref(0)}}const { x, y } = useMouse()// reactive 包装const mouse = reactive(useMouse())mouse.x === x.value // true
可以直接使用 ES6 解构其中的 Ref 使用根据使用方式,当想要自动解包的功能时,可以使用 reactive 将其转换为对象
// context.tsimport { InjectionKey } from 'vue'export interface UserInfo {id: numbername: string}export const injectKeyUser: InjectionKey<UserInfo> = Symbol()// parent.vueimport { provide } from 'vue'import { injectKeyUser } from './context'export default {setup() {provide(injectKeyUser, {id: '7', // 类型错误name: 'Anthony'})}}// child.vueimport { inject } from 'vue'import { injectKeyUser } from './context'export default {setup() {const user = inject(injectKeyUser)// UserInfo | undefinedif (user)console.log(user.name) // Anthony}}
// shared.tsimport { reactive } from 'vue'export const state = reactive({foo: 1,bar: 'Hello'})// A.vueimport { state } from './shared.ts'state.foo += 1// B.vueimport { state } from './shared.ts'console.log(state.foo) // 2
不兼容 SSR
export default defineComponent({setup(props) {const value = useVModel(props, 'value')return { value }}})<template><input v-model="value" /></template>
// Vue2.xVue.prototype.$api = axiosVue.prototype.$eventBus = eventBus// Vue3.xapp.config.globalProperties.$api = axiosapp.config.globalProperties.$eventBus = eventBus// 使用<script setup lang="ts">import { ref, onMounted, getCurrentInstance } from "vue";onMounted(() => {const instance = <any>getCurrentInstance();const { $api, $eventBus } = instance.appContext.config.globalProperties;// do something})
// main.tsapp.config.errorHandler = (err, vm, info) => {console.log('[全局异常]', err, vm, info)}
控制台输出直观 ref 方法:
这里还有另一种方式,就是在控制台的设置面板中开启 「Enable custom formatters」选项。
这时候你会发现,控制台输出的 ref的格式发生变化了:
