当前位置: 首页 > 知识库问答 >
问题:

vue3 - defineProps到底做了什么?

汝宏伯
2024-07-03

defineProps做了什么?

// Parent.vue
<script setup>
const data = ref(["peter", "tom"])
</script>
<template>
    <Child :data="data" />
</template>
// Child.vue
<script setup>
    const {data} = defineProps(["data"])
</script>
<template>
    <p v-for="item in data">{{item}}</p>
</template>

script setup文档

里面的代码会被编译成组件 setup() 函数的内容。这意味着与普通的 <script> 只在组件被首次引入的时候执行一次不同,<script setup> 中的代码会在每次组件实例被创建的时候执行

definePropsdefineEmits 都是只能在 <script setup> 中使用的编译器宏。他们不需要导入,且会随着 <script setup> 的处理过程一同被编译掉

这里的const {data} = defineProps(["data"])怎么处理?
我的理解它应该是会被提到setup函数之外,类似于下面这样

{
    prop: {
        "data": data
    }
    setup(prop){
        ....
    }
}

我不太理解当父组件修改data的时候,如果我在子组件的setup中使用data,子组件是怎么得到这个新的data的呢?setup它只执行了一次啊?

附:vue真是太难学了,搞不明白

共有2个答案

蓬弘
2024-07-03

这是 Vue 通过依赖收集自动帮你处理好的,在React中也是如此 �� 将 Props 传递给组件 – React 中文文档

  • #访问 Props - 组合式 API:setup() | Vue.js
  • #传递 props - 组件基础 | Vue.js
  • #响应式 props 解构 - 响应性语法糖 | Vue.js

至于为什么会出现 defineProps/defineEmits,是因为在 script:setup 中,我们并不能像在普通 setup 中一样写声明 propsemit:

export default {
  props: {
    title: String
  },
  emits: ['check'],
  setup(props) {
    console.log(props.title)
  }
}

你会发现你不知道如何去声明 propsemits,因为省略了 setup() 的入口缺少了上下文来源。所以出现了 defineProps()defineEmits() 两个宏。

  • #Setup 上下文 - 组合式 API:setup() | Vue.js

同理,后续又出现了 defineOptions()defineModel() 之类的各种新的宏,来方便我们在 script:setup 中方便的书写业务逻辑,也避免书写多个 sciprt 块这种很不优雅的方式。

  • <script setup> | Vue.js
章禄
2024-07-03

子组件:

// Child.vue
<script setup>
    const {data} = defineProps(["data"])
</script>
<template>
    <p v-for="item in data">{{item}}</p>
</template>

将被编译为:

import {
  renderList,
  Fragment,
  openBlock,
  createElementBlock,
  toDisplayString,
} from "vue";

const sfc = {
  __name: "Child1",
  __file: "src/Child1.vue",
  props: ["data"],
  setup(props, { expose }) {
    expose();

    return { __isScriptSetup: true };
  },
};

function render(ctx, cache, props, setup, data, options) {
  return (
    openBlock(true),
    createElementBlock(
      Fragment,
      null,
      renderList(props.data, (item) => {
        return (
          openBlock(),
          createElementBlock("p", null, toDisplayString(item), 1 /* TEXT */)
        );
      }),
      256 /* UNKEYED_FRAGMENT */
    )
  );
}

sfc.render = render;

export default sfc;

可以看到,组件包含一个 setup 函数和一个 render 函数,分别由 <script setup><template> 编译而来。

在一个组件的生命周期中,setup 函数仅运行一次;而 render 函数会在第一次渲染和每次组件更新时运行,参考:Vue - 生命周期图示。

父组件 ref 的更新,将触发父组件的更新。父组件更新过程中,将会把最新的 ref 的值传递给子组件,并触发子组件的更新。子组件的 render 函数将运行,并通过 props.data 获取最新值。

 类似资料:
  • 问题内容: 连接到MySQL数据库时,请执行以下步骤 实际上,我想知道语句的作用。 虽然此类不在mysql.jar中。它在哪里? 问题答案: 本类位于java.lang包,因此在分布用java,并自动导入到每个班级。 该方法所做的只是返回由类加载器加载的参数对象。然后,该方法返回该类的新实例。 因此,发生什么情况是您称之为 返回com.mysql.jdbc.Driver.class。然后,您调用该

  • 问题内容: 在Tour of Go网站的go 1.5发行之前的版本中,有一段代码看起来像这样。 输出看起来像这样: 令我困扰的是,将其删除后,该程序不再显示“世界”。 为什么呢?如何影响执行力? 问题答案: 注意: 从Go 1.5开始,将GOMAXPROCS设置为硬件内核数:golang.org/doc/go1.5#runtime,低于1.5之前的原始答案。 当您在未指定GOMAXPROCS环境变

  • 根据几个因素(包括OS/浏览器组合),WebDriver可能等待或不等待页面加载。在某些情况下,WebDriver可能会在页面完成加载或甚至开始加载之前返回控制 有人能解释一下在什么情况下WebDriver会在页面完成甚至开始加载之前返回控制吗?

  • 我有一个Spring Boot后端,我刚刚解决了从Angular frontend上传文件时的“ERR_CONNECTION_RESET”问题,方法是配置Tomcat属性。我想弄清楚它到底是做什么的。Tomcat文档对我来说并不明显: 对于中止的上载,Tomcat将吞下的最大请求主体字节数(不包括传输编码开销)。中止上载是指Tomcat知道请求正文将被忽略,但客户端仍然发送它。如果Tomcat没有

  • 问题内容: 我致力于将Google Analytics(分析)和GCM服务添加到当前应用中。在两种服务实施指南中,Google要求开发人员生成一个json文件:google- services.json并将其放在应用程序的根目录下。 我发现,即使我从应用程序中删除了该json文件,该服务仍然有效。 只想确定一下,该文件的真正用途是什么?它的用法是什么以及如何工作? 问题答案: 我对google-s

  • 问题内容: 解释了如何解决创建is 的问题。 本质上,有两种方法: 使用关键字: 使用关键字: 我正在尝试进行一些研究,以了解这两种方法之间的确切区别。该文档非常清楚有关使用: 为了在Objective-C中可访问和使用,Swift类必须是Objective-C类的后代,或者必须将其标记为。 但是,在任何地方我都找不到有关实际操作的信息。详细考虑整个概念,实际上并没有多大意义。我的理解是,这是Sw

  • 首先,我知道这个问题,但我对其中没有提供的细节感兴趣。 我看了一下m2eclipse的留档,发现它不令人满意地简洁。我能找到的唯一相关的部分是 或者,您可以从项目弹出菜单中运行“Maven/Update project configuration”操作,该菜单默认配置为运行“process resources”,也可以在相同的首选项页面上更改。 但我无法确定是否与相同。我在浏览时发现的所有其他来源

  • 问题内容: 这是我的代码: 这是我从解释器运行输出时的结果: 如果您注意到输出,则创建巨大的列表会消耗621.5 MB,而删除它只会释放152.6 MB。当我检查文档时,我发现以下语句: 因此,我猜想它并没有删除对象本身,而只是取消了绑定。 但是,它在解除绑定方面做了什么工作,从而释放了很大的空间(152.6 MB) 。有人可以痛苦地解释我在这里发生什么吗? 问题答案: Python是一种垃圾收集