vue3 的一些知识点

9/13/2021 Vue

# vue3+ts 的 PropType 类型验证

官网链接 (opens new window)

  1. 引入
import { PropType } from 'vue'
1
  1. 定义接口
interface oneOptions {
    label: string
    value: number | string
    [key: string]: any
}
1
2
3
4
5
  1. 属性验证
props: {
    options: {
        type: Object as PropType<oneOptions>,
        default: () => {
            return []
        },
        required: true,
    },
}
1
2
3
4
5
6
7
8
9

# vue3 使用 ref 获取 dom 元素

<template>
    <div ref="myRef">ref的内容</div>
    <el-form :model="form" label-width="100px" ref="ruleForm">
        ...
    </el-form>
    <el-button @click="handleSubmit">提交</el-button>
</template>
<script lang="ts">
    import { defineComponent, ref, onMounted, reactive } from 'vue'
    export default defineComponent({
        setup() {
            const myRef = ref<HTMLElement>()
            const form = reactive({})
            const ruleForm = ref<HTMLElement>()
            onMounted(() => {
                console.log('myRef', myRef.value)
                // 因为获取到的dom可能是undefined,所以获取属性时加个?[可选链操作符],表示myRef.value存在的时候才获取clientHeight属性
                console.log('height', myRef.value?.clientHeight)
            })
            // 提交前进行表单校验
            const handleSubmit = () => {
                ruleForm.value.validate((valid: boolean) => {
                    if (valid) {
                    } else {
                        return false
                    }
                })
            }
            return {
                myRef,
                form,
                ruleForm,
            }
        },
    })
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

# Suspense(不确定的)

  • 作用 使应用在等待异步组件渲染时候,渲染一些其他内容,可以创建一个平滑的用户体验

  • 使用 子组件

<template>
    <h2>AsyncComp22</h2>
    <p>{{ msg }}</p>
</template>

<script lang="ts">
    export default {
        name: 'AsyncComp',
        setup() {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve({
                        msg: 'april',
                    })
                }, 2000)
            })
        },
    }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

父组件

<template>
    <Suspense>
        <!-- v-slot:defaul可以简写成#defaul -->
        <template v-slot:default>
            <AsyncComp />
        </template>

        <template v-slot:fallback>
            <h1>LOADING...</h1>
        </template>
    </Suspense>
</template>

<script lang="ts">
    import { defineAsyncComponent } from 'vue'
    const AsyncComp = defineAsyncComponent(() => import('./AsyncComp.vue'))
    export default {
        setup() {
            return {}
        },

        components: {
            AsyncComp,
        },
    }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

效果图

效果图

# 使用 reactive 包裹数组如何正确赋值

const arr = reactive([])
const getData = () => {
    const res = [1, 2, 3, 4, 5]
    // 方法一:失败,直接赋值丢失了响应性
    // arr = res
    // 方法二:失败,直接赋值丢失了响应性
    // arr.concat(res)
    // 方法3 可以,麻烦,且时间复杂度增高
    res.forEach((e) => {
        arr.push(e)
    })
}
1
2
3
4
5
6
7
8
9
10
11
12

可以正确赋值的方法,推荐第一种

const state = reactive({
    arr: [],
})

state.arr = [1, 2, 3]
1
2
3
4
5
const state = ref([])

state.value = [1, 2, 3]
1
2
3
const state = ref([])

state.value = [1, 2, 3]
1
2
3
arr.length = 0 // 清空原数组
arr.push(...res) // 解构然后push进去
1
2

# 嵌套组件通信

  • 父组件向子孙组件传递数据
// 父组件
import { provide } from 'vue'
const state = reactive({
    appId: '123',
})
provide('currentAppId', state.appId)

// 子孙组件获取
import { inject } from 'vue'
const appId = inject('currentAppId')
1
2
3
4
5
6
7
8
9
10
  • 子孙事件向父组件传值
  1. 导入 provide 和 inject 到爷爷组件和孙子组件中

  2. 爷爷组件中,通过 provide 声明函数,并要有形参用来接收孙组件传来的实参

const getChildData = (value) => {
    console.log('孙子组件传递数据', value)
}
provide('test', getChildData)
1
2
3
4
  1. 孙子组件中,获取并调用该函数传递数据
const test = inject('test') as Function
    const handleSendData = () => {
        test(200)
}
1
2
3
4
上次更新: 2/16/2022, 8:31:13 PM