vue3 基础-API-响应式 toRef, context

上篇讲了构造响应式变量 ref 和 reactive 函数, 其中 ref 针对基础类型, reactive 针对引用类型. 而 toRefs 可以将响应式变量进行结构后, 仍然具备响应式. 而本篇继续对其常用 API 进行扩展.

toRefs 的局限性

首先是关于 toRefs 在结构 reactive 对象时, 如果获取不到的情况, 就直接会报错啦.

<!DOCTYPE html>
<html lang="en">

<head>
  <title>toRefs 解构不存在的数据</title>
  <script src="https://unpkg.com/vue@3"></script>
</head>

<body>
  <div id="root"></div>
  <script>
    const app = Vue.createApp({
      template: `<div>{{name}}</div>`,

      setup(props, context) {

        const { reactive, toRefs } = Vue
        let data = reactive({ name: 'youge'})

        // 当解构 toRefs 对象中不存在的值时, 就会报错啦
        const { age } = toRefs(data)

        setTimeout(() => {
          age.value = 26
        }, 2000);

        return { name, age }
      }
    })
    const vm = app.mount('#root')

  </script>
</body>

</html>

toRef

它就可以给一个值, 让其不报错, 但是呢我感觉很鸡肋, 还是建议前后端传值要约定好.

<!DOCTYPE html>
<html lang="en">

<head>
  <title>toRef 解构不存在的数据时给默认值</title>
  <script src="https://unpkg.com/vue@3"></script>
</head>

<body>
  <div id="root"></div>
  <script>
    const app = Vue.createApp({
      template: `<div>{{name}}: {{age}}</div>`,

      setup(props, context) {

        const { reactive, toRef } = Vue
        let data = reactive({ name: 'youge'})

        // 当解构 toRef 对象中不存在的值时, 可以给个默认值
        const age = toRef(data, '18')
        const { name } = data

        setTimeout(() => {
          age.value = 26
        }, 2000);

        return { name, age }
      }
    })
    const vm = app.mount('#root')

  </script>
</body>

</html>

因此这个 toRef 总感觉怪怪的, 就再说, 也有应用场景吧, 视情况而定吧.

context
它是一个上下文的概念, 里面有三个东西: attrs, slots 和 emit

首先来看 attrs. 就父组件传递过来的数据, 当子组件不通过 props 接收数据时, 其会默认挂载到 attrs 上.

<!DOCTYPE html>
<html lang="en">

<head>
  <title>context-attrs</title>
  <script src="https://unpkg.com/vue@3"></script>
</head>

<body>
  <div id="root"></div>
  <script>
    const app = Vue.createApp({
      template: `<son name="youge">father</son>`,
    })

    app.component('son', {
      template: `<div @click="handleClick">son</div>`,
      setup (props, context) {
        const { h } = Vue
        const { attrs, slots, emit }  = context 
        // None-Props 会存在 context 的 attrs 中哦
        console.log(attrs.name)
        console.log(slots)

        // 通过 h 函数生成虚拟 dom 就可以直接展示啦
        // return () => h('div', {}, 'houyaya')

        // 直接展示父组件传来的内容, 也可通过 slots
        // return () => h('div', {}, slots.default())

        // emit 也是可以替换掉原来的 $emit 方法的啦
        function handleClick () {
          emit('change')
        }

        return { handleClick }
      }
    })

    const vm = app.mount('#root')

  </script>
</body>

</html>

所以结论就是 Composition API 是基本可以替换和完善掉原来的一些类似 $emit呀, slots, attrs 等的功能. 使其应用场景会更加广泛和具有低耦合, 高扩展性的特点, 还是非常好用的.

小结

  • vue3 的响应式变量是通过 ref, reactive, toRef 来封装的, 底层是 Proxy, ref 基于 reactive
  • ref 可将基础数据类型变成响应式, 如 number, string, boolean, undefined, null 等
  • reactive 可将引用数据类型变为响应式 (基础类型也行哈), 如 array, object, functions 等
  • toRefs 是在解构 reactive 的时候, 将其里面的 key 对应的值变成响应式变量
  • toRef 是对 toRefs 的一种当 key 不存在时可以给一个默认防止报错, 但不建议使用, 前后端应最好约定好接口
  • setup 函数中的 context 有三个东西 attrs, slots, emit 就基本可以替代掉原来的 $attrs 等各种操作
posted @ 2022-10-07 20:37  致于数据科学家的小陈  阅读(131)  评论(0编辑  收藏  举报