Vue基础
Chapter 1
-
通过响应式定义的变量
reactive(obj)
和ref
一样拥有深层响应式,所以当改变reactive(obj).obj
里面的对象也会发生改变。但是reactive
只能包装引用类型的变量,而ref
可以包装任何类型但是在没自动解包的情况下需要.value
来访问ref
值 -
reactive
的变量如果解构的话,变量不具有响应式。(const { num } = reactive({ num: 0 })
),即使num
发生变化,也无效 -
将
ref
赋值在reactive
中,如果reactive
是对象类型,那么ref
将自动解包,而无需.value
,并且reactive
改变改值时,对应的ref
也会自动更新。-
<script setup> import { ref, reactive } from 'vue'; const num = ref(0) const obj = reactive({ num }) </script> <template> <button v-on:click="obj.num += 1"> <!-- 对应的 ref: num 也会加一 --> {{num}} </button> </template>
-
-
将
ref
赋值给reactve
中,但是reactive
是数组类型,那么ref
将不会自动解包,需要通过.value
来获取,并且修改reactive
的值也不会再将ref
值更新-
<script setup> import { ref, reactive } from 'vue'' const num = ref(0) const obj = reactive([num.value]) </script> <template> <button v-on:click="obj[0] += 1"> <!-- num 将不会更新 --> {{num}} <!-- obj.num 将不会更新 --> {{obj[0]}} </button> </template>
-
-
生命周期:vue会首先执行setup进行初始化,然后初始化API,之后进行初次渲染创建DOM和插入
onMounted
。渲染完成后再次期间如果状态发生变化则进入onUpdate
状态,更新后会进入updated
状态。当要卸载组件时会执行beforeUnmounted
和unmounted
-
给DOM添加
ref
属性时,vue初次执行时,获取的的ref
会是null
,因为setup中的变量初始化是在DOM渲染插入之前的。如果想明确获取指定DOM,需要使用onMounted(() => console.log(ref.value))
在挂载后在执行获取该ref
- 也可以直接在DOM上来操作
ref
属性的函数,<div :ref="(e) => ref.value = e.target"></div>
,当DOM移除时ref
也将变为null
- 使用
watch
来获取到DOM,但是watch
会在DOM更新之前执行。使用需要使用watch(() => ref.value.focus(), { flush: 'post' })
来指定在DOM更新之后在执行,也可以使用watchPostEffect
- 也可以直接在DOM上来操作
-
在Vue3.5之前不同的是:
props
解构,3.5前解构的变量不具有响应式,而3.5后解构的变量都具有响应式 -
对于变量以及属性都是相同命名时,可以像JS那样省略书写,
<div :item></div>
-
通过想要过一个按钮来实现组件的切换可以使用Vue自带组件
component
来实现,但是切换后,之前的组件都将被卸载,也就是再次切换回来之前的ref
状态会被重新初始化,可以通过Vue内置组件<KeepAlive>
来实现保存不销毁-
<script setup> import { ref } from 'vue' import Hello from './Hello.vue' import World from './World.vue' const key = ref('Hello') const tabs = { Hello, World } </script> <template> <button @click="key = 'Hello'">Hello</button> <button @click="key = 'World'">World</button> <KeepAlive :max="2"> <component :is="tabs[key]" /> </KeepAlive> </template>
-
-
在Vue中也可以给自定义组件添加
v-model
属性,在该组件下使用defineModel
来获取-
// 父组件 <script setup> import Child from './Child.vue' const text = ref('') </script> <template> <Child v-model:main.capitalize="text" /> </template> // 子组件 Child.vue <script setup> import { defineModel } from 'vue' const [model, modifiers] = defineModel('main', { get(value) { if (modifiers.capitalize) { return value.charAt(0).toUpperCase() + value.slice(1) } return value; }, set(value) {} }) </script> <template> <input v-model="model" /> </template>
-
-
为Vue注入TS
-
ref
和reactive
可以使用ref<number>(0)
/const obj: { num: number } = reactive({ num: 0 })
-
defineProps(['num'])
defineProps<{ num?: number }>()
defineProps({ num: { type: Number, required: false } })
-
defineEmits(['change'])
defineEmits<{ (e: 'change', id: number): void }>()
defineEmits({ change: (id: number) => {} })
-
provide('name', 'su')
和inject<string>('name')
-
computed<number>(() => 1)
-
<script setup> import Child from './Child.vue' // InstanceType 为内部自带无需引入 type ChildType = InstanceType<typeof Child> </script>
-
useTemplateRef<HTMLDivElement>('div')
-
-
v-if
和v-show
区别- 相同点:都是通过布尔值来显示DOM
- 不同点:
- 无论布尔值是真或者假,
v-show
都会初始创建DOM,而v-if
如果初始值为false
,则初始不渲染该DOM v-show
不能运用在template
上和自定义组件上,而v-if
都可以v-show
适用于频繁切换的DOM,初始化成本比较高。v-if
使用于不经常切换的DOM,初始化成本比较低v-show
的隐藏类似于CSS的display: none;
,而v-if
则是将整个DOM销毁,所以频繁切换时使用v-if
开销会比较大
- 无论布尔值是真或者假,