你知道Vue3中用Vue2(data)和Vue3(setup)写法定义一个相同数据最后返回结果是啥吗?

6,377 阅读1分钟

前言

今天给大家讲解一下vue3中使用vue3写法和vue2写法分别定义相同变量,页面会显示什么 样的结果?

Vue3

学过vue3大家都知道,vue3中改变了传统的vue2的Options API的写法改用了composition API的写法,但是vue3中依然还支持vue2的语法,所以我们vue3中可以使用下面两种语法

// vue2的Options API写法
data() {
        return {
          number: 0
        }
      },
// vue3的composition API写法
setup() {
        const info = Vue.reactive({
          name: "jack"
        })

        return {
          info
        }
      },

demo

为了探究同时定义同一变量页面显示究竟是data中的数据还是setup中的数据

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="app"></div>
  <template id="my-app">
    <div>
     {{message}}
    </div>
  </template>
  <script src="../../dist/vue.global.js"></script>
  <script>
    Vue.createApp({
      template: '#my-app',
      data() {
        return {
          message: "jack"
        }
      },
      setup() {
        const message = Vue.ref("rose")
        return {
          message
        }
      },
    }).mount('#app')
  </script>
</body>
</html>

页面打印结果

image.png 所以我们都数据是来自setup里面的。

template里的代码其实不是我们最终代码,而是从我们reder函数编译出来的一大堆内容,所以我们div里面的message其实本质是从_ctx里面取的。

image.png 本着究其根本的理念,我们来到vue3的源码中

image.png 部分源码

if (key[0] !== '$') {
      const n = accessCache![key]
      if (n !== undefined) {
        switch (n) {
          case AccessTypes.SETUP:
            return setupState[key]
          case AccessTypes.DATA:
            return data[key]
          case AccessTypes.CONTEXT:
            return ctx[key]
          case AccessTypes.PROPS:
            return props![key]
        }
      } else if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
        accessCache![key] = AccessTypes.SETUP
        return setupState[key]
      } else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
        accessCache![key] = AccessTypes.DATA
        return data[key]
      } else if (
        (normalizedProps = instance.propsOptions[0]) &&
        hasOwn(normalizedProps, key)
      ) {
        accessCache![key] = AccessTypes.PROPS
        return props![key]
      } else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
        accessCache![key] = AccessTypes.CONTEXT
        return ctx[key]
      } else if (!__FEATURE_OPTIONS_API__ || shouldCacheAccess) {
        accessCache![key] = AccessTypes.OTHER
      }
    }

总结

所以其实就是源码中的if的逻辑判断顺序不一样,所以我们的取值顺序不同,所以我们只有了解了真相才能真正的去记住

欢迎各位掘友来此学习,大家相互学习相互成长