• 终于搞懂了!原来vue3中template使用ref无需.value是因为这个


    前言

    众所周知,vue3的template中使用ref变量无需使用.value。还可以在事件处理器中进行赋值操作时,无需使用.value就可以直接修改ref变量的值,比如:。你猜vue是在编译时就已经在代码中生成了.value,还是运行时使用Proxy拦截的方式去实现的呢?注:本文中使用的vue版本为3.4.19

    关注公众号:【前端欧阳】,给自己一个进阶vue的机会

    看个demo

    看个简单的demo,代码如下:

    <template>
      <p>{{ msg }}p>
      <button @click="msg = 'Hello Vue3'">change msgbutton>
    template>
    
    <script setup lang="ts">
    import { ref } from "vue";
    
    const msg = ref("Hello World");
    
    console.log(msg.value);
    script>
    

    上面的代码很简单,在script中想要访问msg变量的值需要使用msg.value。但是在template中将msg变量渲染到p标签上面时就是直接使用{{ msg }},在click的事件处理器中给msg变量赋新的值时也没有使用到.value

    然后在浏览器中找到上面这个vue文件编译后的样子,在之前的文章中已经讲过很多次如何在浏览器中查看编译后的vue文件,这篇文章就不赘述了。编译后的代码如下:

    import {
      Fragment as _Fragment,
      createElementBlock as _createElementBlock,
      createElementVNode as _createElementVNode,
      defineComponent as _defineComponent,
      openBlock as _openBlock,
      toDisplayString as _toDisplayString,
      ref,
    } from "/node_modules/.vite/deps/vue.js?v=23bfe016";
    
    const _sfc_main = _defineComponent({
      __name: "index",
      setup() {
        const msg = ref("Hello World");
        console.log(msg.value);
        const __returned__ = { msg };
        return __returned__;
      },
    });
    
    function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
      return (
        _openBlock(),
        _createElementBlock(
          _Fragment,
          null,
          [
            _createElementVNode("p", null, _toDisplayString($setup.msg), 1),
            _createElementVNode(
              "button",
              {
                onClick:
                  _cache[0] ||
                  (_cache[0] = ($event) => ($setup.msg = "Hello Vue3")),
              },
              "change msg"
            ),
          ],
          64
        )
      );
    }
    _sfc_main.render = _sfc_render;
    export default _sfc_main;
    

    vue文件编译后的代码主要分为两块:_sfc_main_sfc_render

    • _sfc_main中主要是setup方法,这个是vue的