Vue Prop 默认值深入解析:工厂函数与 rawProps 的正确使用

在 Vue.js 中,prop 是组件接收外部数据的重要方式。我们常常为组件的 prop 设置默认值,确保在父组件没有传递值时,组件能正常工作。默认值可以是基本类型,也可以是对象、数组或函数。然而,很多开发者可能会在设置对象和函数类型的 prop 默认值时感到困惑。今天,我们就来深入探讨如何正确使用 Vue 中的 defaultrawProps,并通过实际案例让你更加清晰地理解这些概念。

1. 函数类型的 prop 默认值

首先,让我们看一下函数类型的 prop。在 Vue 中,如果你为某个 prop 设置了一个函数类型,并且没有传递该 prop,Vue 会使用一个默认值。但与对象和数组不同,函数类型的 default 不需要 是一个工厂函数,它是一个用来作为默认值的函数

示例:函数类型的 prop

xml 复制代码
<template>
  <div>
    <button @click="executeCallback">Execute Callback</button>
  </div>
</template>
​
<script>
export default {
  name: 'CallbackComponent',
  props: {
    callback: {
      type: Function,
      default() {
        console.log("11111"); // 打印默认函数的执行
        return (message) => `Default message: ${message}`;
      }
    }
  },
  methods: {
    executeCallback() {
      console.log(this.callback('Test message'));
    }
  }
};
</script>

解释:

  • callback 是一个函数类型的 prop
  • default 配置项提供了一个默认的点击事件处理函数。
  • default 中的 console.log("11111") 只会在父组件没有传递 callback 时执行。

父组件使用:

xml 复制代码
<template>
  <CallbackComponent />
</template>
​
<script>
import CallbackComponent from './CallbackComponent.vue';
​
export default {
  name: 'App',
  components: {
    CallbackComponent
  }
};
</script>
​

结果:

  • 如果父组件没有传递 callback,则 default 函数会被执行,控制台会打印 11111,并且 callback 会返回默认的消息。
  • 如果父组件传递了 callback,则 default 函数不会被执行。callback 会使用父组件传递的值,而不是默认函数。

注意:

  • default 函数只会在父组件没有传递 callback 时执行 ,并且你可以在 default 函数中打印日志或做其他的初始化操作。当父组件传递了 callback 时,default 函数的代码不会执行。

2. 对象和数组类型的 prop 默认值与 rawProps 的使用

当我们处理对象或数组类型的 prop 时,default 必须是一个工厂函数。这是因为对象和数组是引用类型,直接设置默认值可能导致多个组件实例共享同一个对象或数组。为了避免这种情况,Vue 强制要求我们通过工厂函数返回一个新的实例。

另外,Vue 允许在工厂函数中使用 rawProps,即接收到的原始 props,从而可以根据父组件传入的值动态设置默认值。

示例:使用 rawProps 设置对象类型的 prop 默认值

假设我们有一个 UserProfile 组件,接收一个 settings 对象类型的 prop,包含 themelanguage。我们希望根据父组件传入的自定义设置来动态设置默认值。

xml 复制代码
<template>
  <div>
    <h1>User Profile</h1>
    <p>Theme: {{ settings.theme }}</p>
    <p>Language: {{ settings.language }}</p>
  </div>
</template>
​
<script>
export default {
  name: 'UserProfile',
  props: {
    settings: {
      type: Object,
      default(rawProps) {
        // 默认的设置
        const defaultSettings = {
          theme: 'light',
          language: 'en'
        };
​
        // 如果父组件传入了 customSettings,使用它们覆盖默认值
        return rawProps.customSettings ? { ...defaultSettings, ...rawProps.customSettings } : defaultSettings;
      }
    }
  }
};
</script>

解释:

  • settings 是一个对象类型的 prop,我们希望它默认包含 themelanguage
  • default(rawProps) 是一个工厂函数,rawProps 是父组件传递的原始 props
  • 如果父组件传递了 customSettings,那么我们将用 customSettings 来覆盖默认设置。

父组件使用:

xml 复制代码
<template>
  <div>
    <UserProfile :settings="customSettings" />
  </div>
</template>
​
<script>
import UserProfile from './UserProfile.vue';
​
export default {
  name: 'App',
  components: {
    UserProfile
  },
  data() {
    return {
      customSettings: {
        theme: 'dark', // 自定义主题
        language: 'es' // 自定义语言
      }
    };
  }
};
</script>

结果:

  • 如果 customSettings 被传递到 UserProfile 中,settings 会使用 customSettings 中的 themelanguage(即 theme: 'dark', language: 'es')。
  • 如果没有传递 customSettings,则会使用默认值:theme: 'light', language: 'en'

记忆已更新

好的,你的理解是对的。在 Vue 中,当父组件传递了 callback 的值时,default 函数不会被执行,因为 Vue 会使用父组件传递的 callback 值。而如果父组件没有传递该 prop,Vue 就会执行 default 中定义的默认函数。

我已经将这个说明加入到博客中,下面是更新后的博客内容:


Vue Prop 默认值深入解析:工厂函数与 rawProps 的正确使用

在 Vue.js 中,prop 是组件接收外部数据的重要方式。我们常常为组件的 prop 设置默认值,确保在父组件没有传递值时,组件能正常工作。默认值可以是基本类型,也可以是对象、数组或函数。然而,很多开发者可能会在设置对象和函数类型的 prop 默认值时感到困惑。今天,我们就来深入探讨如何正确使用 Vue 中的 defaultrawProps,并通过实际案例让你更加清晰地理解这些概念。

1. 函数类型的 prop 默认值

首先,让我们看一下函数类型的 prop。在 Vue 中,如果你为某个 prop 设置了一个函数类型,并且没有传递该 prop,Vue 会使用一个默认值。但与对象和数组不同,函数类型的 default 不需要是一个工厂函数。

示例:函数类型的 prop

xml 复制代码
vue复制代码<template>
  <div>
    <button @click="executeCallback">Execute Callback</button>
  </div>
</template>
​
<script>
export default {
  name: 'CallbackComponent',
  props: {
    callback: {
      type: Function,
      default(message) {
        console.log("11111"); // 打印默认函数的执行
        return `Default message: ${message}`;
      }
    }
  },
  methods: {
    executeCallback() {
      console.log(this.callback('Test message'));
    }
  }
};
</script>

解释:

  • callback 是一个函数类型的 prop
  • default 配置项提供了一个默认的点击事件处理函数。
  • default 中的 console.log("11111") 只会在父组件没有传递 callback 时执行。

父组件使用:

xml 复制代码
<template>
  <CallbackComponent />
</template>
​
<script>
import CallbackComponent from './CallbackComponent.vue';
​
export default {
  name: 'App',
  components: {
    CallbackComponent
  }
};
</script>

结果:

  • 如果父组件没有传递 callback,则 default 函数会被执行,控制台会打印 11111,并且 callback 会返回默认的消息。
  • 如果父组件传递了 callback,则 default 函数不会被执行。callback 会使用父组件传递的值,而不是默认函数。

注意:

  • default 函数只会在父组件没有传递 callback 时执行 ,并且你可以在 default 函数中打印日志或做其他的初始化操作。当父组件传递了 callback 时,default 函数的代码不会执行。

2. 对象和数组类型的 prop 默认值与 rawProps 的使用

当我们处理对象或数组类型的 prop 时,default 必须是一个工厂函数。这是因为对象和数组是引用类型,直接设置默认值可能导致多个组件实例共享同一个对象或数组。为了避免这种情况,Vue 强制要求我们通过工厂函数返回一个新的实例。

另外,Vue 允许在工厂函数中使用 rawProps,即接收到的原始 props,从而可以根据父组件传入的值动态设置默认值。

示例:使用 rawProps 设置对象类型的 prop 默认值

假设我们有一个 UserProfile 组件,接收一个 settings 对象类型的 prop,包含 themelanguage。我们希望根据父组件传入的自定义设置来动态设置默认值。

xml 复制代码
vue复制代码<template>
  <div>
    <h1>User Profile</h1>
    <p>Theme: {{ settings.theme }}</p>
    <p>Language: {{ settings.language }}</p>
  </div>
</template>
​
<script>
export default {
  name: 'UserProfile',
  props: {
    settings: {
      type: Object,
      default(rawProps) {
        // 默认的设置
        const defaultSettings = {
          theme: 'light',
          language: 'en'
        };
​
        // 如果父组件传入了 customSettings,使用它们覆盖默认值
        return rawProps.customSettings ? { ...defaultSettings, ...rawProps.customSettings } : defaultSettings;
      }
    }
  }
};
</script>

解释:

  • settings 是一个对象类型的 prop,我们希望它默认包含 themelanguage
  • default(rawProps) 是一个工厂函数,rawProps 是父组件传递的原始 props
  • 如果父组件传递了 customSettings,那么我们将用 customSettings 来覆盖默认设置。

父组件使用:

xml 复制代码
vue复制代码<template>
  <div>
    <UserProfile :settings="customSettings" />
  </div>
</template>
​
<script>
import UserProfile from './UserProfile.vue';
​
export default {
  name: 'App',
  components: {
    UserProfile
  },
  data() {
    return {
      customSettings: {
        theme: 'dark', // 自定义主题
        language: 'es' // 自定义语言
      }
    };
  }
};
</script>

结果:

  • 如果 customSettings 被传递到 UserProfile 中,settings 会使用 customSettings 中的 themelanguage(即 theme: 'dark', language: 'es')。
  • 如果没有传递 customSettings,则会使用默认值:theme: 'light', language: 'en'

3. 函数类型的 prop 校验与传参

对于函数类型的 prop,除了设置默认值外,我们还可能需要对其返回值进行校验,确保它符合特定的规范。同时,函数类型的 prop 有时也需要传递参数。在这种情况下,Vue 提供了 validator 来帮助我们验证函数返回值的正确性。

3.1 函数返回值的校验

我们可以使用 validator 函数来校验函数类型 prop 的返回值,确保它返回的值符合预期的类型或格式。

示例:校验函数返回值

假设我们有一个 callback 函数类型的 prop,我们希望确保它返回的结果是一个字符串。

xml 复制代码
<template>
  <div>
    <button @click="executeCallback">Execute Callback</button>
  </div>
</template>
​
<script>
export default {
  name: 'CallbackComponent',
  props: {
    callback: {
      type: Function,
      default() {
        return () => 'Default callback result';
      },
      validator(value) {
        // 校验返回值类型为字符串
        const result = value();
        if (typeof result !== 'string') {
          console.error('Callback must return a string!');
          return false;
        }
        return true;
      }
    }
  },
  methods: {
    executeCallback() {
      console.log(this.callback());
    }
  }
};
</script>

解释:

  • callback 是一个函数类型的 prop
  • default 提供了一个默认的函数,如果父组件没有传递 callback,则使用此函数。
  • validator 函数用于校验函数的返回值,确保返回值是一个字符串。如果不是,控制台会输出错误信息。

父组件使用:

xml 复制代码
<template>
  <CallbackComponent :callback="myCallback" />
</template>
​
<script>
import CallbackComponent from './CallbackComponent.vue';
​
export default {
  name: 'App',
  components: {
    CallbackComponent
  },
  methods: {
    myCallback() {
      return 'Hello from callback';
    }
  }
};
</script>

如果 myCallback 返回的不是字符串,validator 会阻止组件的使用,并在控制台中显示错误信息。

3.2 函数类型的 prop 传参

如果你希望给函数类型的 prop 传递参数,我们可以直接在调用时传递参数,或者将参数绑定到函数内部。

示例:函数类型的 prop 传参

xml 复制代码
<template>
  <div>
    <button @click="executeCallback('Hello')">Execute Callback</button>
  </div>
</template>
​
<script>
export default {
  name: 'CallbackComponent',
  props: {
    callback: {
      type: Function,
      default(message) {
        return `Default message: ${message}`;
      }
    }
  },
  methods: {
    executeCallback(message) {
      console.log(this.callback(message)); // 传递参数
    }
  }
};
</script>

解释:

  • callback 是一个接受参数的函数类型的 prop
  • default 提供了一个接受 message 参数的默认函数。
  • executeCallback 方法中,我们调用 callback 并传递一个参数。

父组件使用:

xml 复制代码
<template>
  <CallbackComponent :callback="myCallback" />
</template>
​
<script>
import CallbackComponent from './CallbackComponent.vue';
​
export default {
  name: 'App',
  components: {
    CallbackComponent
  },
  methods: {
    myCallback(message) {
      return `Custom message: ${message}`;
    }
  }
};
</script>

这里,我们传递的 message 参数将被传递到 myCallback 函数中,返回一个自定义的消息

相关推荐
nihao5611 小时前
Vue 百度地图 搜索框+点击地图获取坐标
vue.js·百度
武昌库里写JAVA5 小时前
Golang设计模式目录
数据结构·vue.js·spring boot·算法·课程设计
customer086 小时前
【开源免费】基于SpringBoot+Vue.JS海滨学院班级回忆录系统(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·maven·intellij-idea
疯狂小料6 小时前
一文理解Vue.js 与 Vue Router:构建现代单页面应用
前端·javascript·vue.js
明月看潮生8 小时前
青少年编程与数学 02-006 前端开发框架VUE 05课题、使用模板
前端·javascript·vue.js·青少年编程·编程与数学
cxsj9998 小时前
Uncaught ReferenceError: __VUE_HMR_RUNTIME__ is not defined
前端·javascript·vue.js
椰云拿铁x9 小时前
【小程序开发】- 小程序版本迭代指南(版本发布教程)
vue.js·git·微信·微信小程序·小程序·vue
Jiaberrr9 小时前
页面转 PDF 功能的实现思路与使用方法
前端·javascript·vue.js·微信小程序·pdf·uniapp
三天不学习10 小时前
Vue Router v3.x 路由进阶【路由篇】
前端·vue.js·路由·router·vue router
ryipei10 小时前
把vue项目或者vue组件发布成npm包或者打包成lib库文件本地使用
前端·vue.js·npm