Vue3学习笔记

9/2/2021笔记

#根据官网看vue3的变化

#Composition API

目的:把以前放在computedmethodswatch内的代码组合一起放在同一个地方,方便阅读与理解,以前是散装的,现在融合。

方法:setup

参数:

  1. props
  2. context

注意点:

  1. 没有this
  2. 只能访问组件内的props,通过参数获取

defineComponent: 定义Vue组件

内部可以使用的方法

  1. ref: 返回一个响应式且可变的ref对象,可以用于组件实例ref实例
  2. toRefs: 创建对prop的响应式引用
  3. computed: 计算属性
  4. reactive: 对象响应式,与传入的对象一致
<template>
  <button type="button" @click="addSize">count is: {{ count }}</button>
  <p>{{ size }}</p>
  <p>{{ allMsg }}</p>
  <p>{{ person.age }}</p>
</template>

<script lang="ts">
import { ref, defineComponent, onMounted, watch, toRefs, computed, reactive } from 'vue'
type Size = 'sm' | 'md' | 'lg'
export default defineComponent({
  props: {
    msg: {
      type: String,
      default: ''
    }
  },
  setup: (props, context) => {

    // 上下文中的三个属性
    console.log(context.attrs)
    console.log(context.slots)
    console.log(context.emit)
    
    // 响应式
    const { msg } = toRefs(props)
    const size = ref<Size>('md')
    const person = reactive({ age: 18 })
    const addSize = () => {
      size.value = 'lg'
    }

    const update = () => {
      size.value = 'sm'
      window.console.log(`prop msg: ${msg.value}`)
    }

    // vue2的mounted方法
    onMounted(update)

    // vue2的computed方法
    const allMsg = computed(() => size.value + msg.value);

    // vue2的watch方法
    watch(size, (newSize, oldSize) => {
      if (newSize === 'lg') {
        console.log(`new value is ${newSize}, old value is ${oldSize}`)
      }
    })

    return { size, addSize, allMsg, person }
  }
})
</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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

内部生命周期函数

  1. onBeforeMount
  2. onMounted
  3. onBeforeMount
  4. onBeforeUpdate
  5. onBeforeMount
  6. onUpdated
<script lang="ts">
import { defineComponent, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onMounted, onUnmounted, onUpdated } from 'vue'

export default defineComponent({
  setup: () => {
    onBeforeMount(() => {
      console.log('beforeMount')
    })

    onMounted(() => {
      console.log('mounted')
    })

    onBeforeUpdate(() => {
      console.log('beforeUpdate')
    })

    onUpdated(() => {
      console.log('update')
    })

    onBeforeUnmount(() => {
      console.log('beforeUnmounted')
    })

    onUnmounted(() => {
      console.log('unmounted')
    })
    return {  }
  }
})
</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

provide&inject

App.vue

<template>
  <HelloWorld />
</template>

<script lang="ts">
import { defineComponent, provide, reactive, ref } from 'vue'
import HelloWorld from './components/HelloWorld.vue'

export default defineComponent({
  name: 'App',
  components: {
    HelloWorld
  },
  setup() {
    const num = ref(0)
    const person = reactive({ age: 18 })
    const changePerson = () => {
      person.age = 19;
    }
    
    provide('num', num)
    provide('person', person)
    provide('changePerson', changePerson)
  }
})
</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

HelloWorld.vue

<template>
  <button @click="changePerson">test</button>
  <p>inject num is {{ num }}, inject person age is {{ person.age }}</p>
</template>

<script lang="ts">
import { defineComponent, inject } from 'vue'

export default defineComponent({
  setup: () => {
    const num = inject('num')
    const person = inject('person')
    const changePerson = inject('changePerson')
    return { num, person, changePerson }
  }
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

#ref实例

<template>
  <div ref="root">
    root node
  </div>
</template>

<script lang="ts">
import { defineComponent, onMounted, ref } from 'vue'

export default defineComponent({
  setup: () => {
    const root = ref(null)
    onMounted(() => {
      console.log(root.value)
    })
    return { root }
  }
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

ref+v-for

<template>
  <ul>
    <li v-for="(num, index) in nums" :key="num" :ref="el => numRef(el, index)">
      {{ num }}
    </li>
  </ul>
</template>

<script lang="ts">
import { defineComponent, onBeforeUpdate, reactive, ref } from 'vue'

export default defineComponent({
  setup: () => {
    const nums = reactive([1, 2, 3])
    let numRefs = ref<HTMLLIElement[]>([])
    const numRef = (el: HTMLLIElement, idx: number) => {
      numRefs.value[idx] = el
    }

    // 动态更新
    onBeforeUpdate(() => {
      numRefs.value = []
    })

    return { nums, numRefs, numRef }
  }
})
</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

watchEffect

<template>
  <div ref="root">
    root node
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, watchEffect } from 'vue'

export default defineComponent({
  setup: () => {
    const root = ref(null)

    // 监听
    watchEffect(() => {
      console.log(root.value)
    }, {
      flush: 'post' // 是否在更新之后运行watch,post在dom更新之后
    })
    return { root }
  }
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

teleport:允许开发者控制渲染的DOM节点

<template>
    <button @click="modalOpen = true">open</button>
    <teleport to="body">
        <div v-if="modalOpen">
            <div>模态框</div>
            <button @click="modalOpen = false">close</button>
        </div>
    </teleport>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue'

export default defineComponent({
    setup() {
        const modalOpen = ref(false);

        return {
            modalOpen
        }
    }
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Last Updated:5/25/2024, 2:23:06 AM