vue3.x 组件数据传递 —— 父子传值 -- definePorps && defineEmits
以下示例:基于 Vue3 setup语法糖
// 在vue2.x中,vue 单向传值,组件通过v-bind来绑定数据,接收参数的组件使用props来接收; // 在vue3中,父组件通过v-bind来传值,子组件使用defineProps来接收 --(defineProps是全局编译器宏)—— 【因为script变为了setup函数,没有组件选项,使用defineProps来接收Props】 // defineProps 是一个方法,内部返回一个对象(所有挂载到该组件的props,不指定prop的属性值会放入attrs中) // 父子传递数据规律:父组件动态绑定单向传值v-bind;绑定响应子组件的事件使用 @ // emit 绑定的事件名 规范示例: // 父组件 @do-event="doEvent" // 子组件 声明emit事件名 'do-event'
// 父子组件通信 // 方式一:props && emits // 父组件 app.vue --基本字符类型直接传值,变量、复合类型使用v-bind绑定(缩写为“ :”符号) // props 如果是多单词组成,kebab-case (短横线分隔命名) 命名;如: <Demo :user-info="user.name"></Demo> <template> <div> <Demo :data="data" title="标题"></Demo> </div> </template> <script setup lang="ts"> // setup语法糖 import Demo from './components/Demo.vue'; // setup语法糖效率提升之一:子组件只需要导入,无需声明 --即 components:['Demo'] 被省略 import { reactive } from 'vue'; const data = reactive<number[]>([1,2,3]); </script> // 子组件 demo.vue <template> <div> <h2>{{title}}</h2> <h2>{{data}}</h2> <br/> <button @click="getProps">获取props</button> </div> </template> <script setup lang="ts"> // 直接在template使用,将从父组件传入的值,通过string[]类型作为入参,传入defineProps中 // defineProps(['title','data']); // 只读 // 如果script 里的方法要拿到 props 的值 let props = defineProps(['title','data']) const getProps = ()=>{ console.log(props.title); } </script>
点击 ‘获取porps’ 效果:
进阶一:使用TS类型注解
// 显性指定prop类型 // 使用TypeScript 类型注解 // app.vue <template> <div> <Demo :data="data" title="标题" :person="person"></Demo> </div> </template> <script setup lang="ts"> import Demo from './components/Demo.vue'; import { reactive } from 'vue'; // import { Person } from './assets/type_interface/type_info'; // 减少Person代码的优化项 interface Person { name: string, age: number } const data = reactive<number[]>([1,2,3]) const person = reactive<Person>({name:'tom',age: 12}); </script> // demo.vue <script setup lang="ts"> interface Person { // 接口类型,接收父组件传入的person并指定接收的类型 name: string, age: number } // 解析:接收具有类型断言的props,目的是保持严谨 // defindProps返回对象,因此<>中 使用 {key: value} // title? -- 指可选的参数,该参数可以不接收 let props = defineProps<{title?: string, data: number[],person: Person}>(); const getProps = ()=>{ console.log(props.title); } </script> <template> <div> <h2>{{title}}</h2> <h2>{{data}}</h2> <h2>{{person.name}}--{{person.age}}</h2> <br/> <button @click="getProps">获取props</button> </div> </template> /** person 是父组件传入的一个对象类型,这里使用interface接口定义的类型 -- 这里,可以发现父组件和子组件都有定义interface Person,所以我们就存在了优化点:减少重复代码。 -- 在app.vue中可以看到 // import { Person } from './assets/type_interface/type_info'; type_info.ts 中 interface Person { name: string, age: number } export type {Person} -- 当然如果只是快速验证可行性,可以person:object 用法 -- 这里有扩展知识点:关于interface 和 type; -- 可自查 */
进阶二:需要指定props的默认值 -- withDefaults 用法
// withDefaults API 可以让你在使用 TS 类型系统时,也可以指定 props 的默认值 // 参数1:props -- object类型 --通过defineProps传入props; // 参数2:defaultValues --object类型 // app.vue <template> <div> <Demo></Demo> // 这里未传值: </div> </template> <script setup lang="ts"> import Demo from './components/Demo.vue'; import { reactive } from 'vue'; interface Person { name: string, age: number } const data = reactive<number[]>([1,2,3]) const person = reactive<Person>({name:'tom',age: 10}); </script> // demo.vue <script setup lang="ts"> interface Person { name: string, age: number } let props = withDefaults(defineProps<{title?: string, data?: number[],person: Person}>(),{ title:'demo标题', // 基本字符类型直接写默认值 data:()=>[4,5,6], // 复合类型-数组 使用函数返回 person:()=>{return {name:'xxx',age:12}} // 复合类型-对象 使用 }) const getProps = ()=>{ console.log(props.title); } </script> <template> <div> <h2>{{title}}</h2> <h2>{{data}}</h2> <h2>{{person.name}}--{{person.age}}</h2> <br/> <button @click="getProps">获取props</button> </div> </template>
效果展示:— demo.vue 组件中的默认值

// 子组件传值 -- 使用 defineEmits 方法 --【vue3.1.3版本前,这个API 是defineEmit,最新版为复数形式 -- 即结尾有s 】 // app.vue <template> <div> <Demo @send-demo="getDemo"></Demo> // sendByDemo 为子组件声明的响应指令,getDemo为父组件接收数据的函数 </div> </template> <script setup lang="ts"> import Demo from './components/Demo.vue'; import { reactive } from 'vue'; let getDemo = (list: number[])=>{ // 接收子组件的传参 console.log(list); } </script> // demo.vue <script setup lang="ts"> import {reactive} from 'vue' const list = reactive<number[]>([1,2,3,]) let emit = defineEmits(['send-demo']) // 获取emit定义的分发事件名称,使用kebab-case const sendToApp = ()=>{ // 定义触发调用emit事件的方法 emit('send-demo',list) } </script> <template> <div> <button @click="sendToApp">发送值给父组件</button>// 触发sendToApp方法,从而调用emit </div> </template>
想买的东西很贵,想去的地方很远,喜欢的女孩很完美

浙公网安备 33010602011771号