欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > 组件十大传值

组件十大传值

2025/2/9 3:30:55 来源:https://blog.csdn.net/m0_72030584/article/details/144552505  浏览:    关键词:组件十大传值

一、defineProps 和 defineEmits

defineProps 用于定义子组件接收的 props,即父组件传递给子组件的数据。

  1. 接收父组件传递的数据:定义子组件可以接受的属性及其类型。
  2. 类型检查:确保传递的数据符合预期的类型。

defineEmits 用于定义子组件可以触发的事件,从而向父组件传递数据或通知父组件发生了某些操作。

  1. 触发事件:子组件可以通过触发事件来通知父组件。
  2. 传递数据:事件可以携带数据传递给父组件
//父组件:
<template><ChildComponent :message="parentMessage" @childEvent="handleChildEvent" />
</template><script setup>
import ChildComponent from './ChildComponent.vue';
import { ref } from 'vue';const parentMessage = ref('Hello from Parent');const handleChildEvent = (message) => {console.log('Received from child:', message);
};
</script>
//子组件
<template><div>{{ message }}<button @click="sendMessageToParent">Send Message to Parent</button></div>
</template><script setup>
import { defineProps, defineEmits } from 'vue';const props = defineProps({message: String,default:''
});const emit = defineEmits(['childEvent']);const sendMessageToParent = () => {emit('childEvent', 'Hello from Child');
};
</script>

二、v-model

双向数据绑定

// 父组件
<template><ChildComponent v-model="parentMessage" />
</template><script setup>
import ChildComponent from './ChildComponent.vue';
import { ref } from 'vue';const parentMessage = ref('Hello from Parent');
</script>
// 子组件
<template><input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</template><script setup>
import { defineProps, defineEmits } from 'vue';const props = defineProps({modelValue: String
});const emit = defineEmits(['update:modelValue']);
</script>

自定义 v-model 的 prop 和 event 名称

// 父组件
<template><ChildComponent v-model:title="parentTitle" />
</template><script setup>
import ChildComponent from './ChildComponent.vue';
import { ref } from 'vue';const parentTitle = ref('Hello from Parent');
</script>
// 子组件
<template><input :value="title" @input="$emit('update:title', $event.target.value)" />
</template><script setup>
import { defineProps, defineEmits } from 'vue';const props = defineProps({title: String
});const emit = defineEmits(['update:title']);
</script>

三、refs

直接访问子组件实例或 DOM 元素,即操作dom节点。

// 父组件
<template><ChildComponent ref="childRef" /><button @click="callChildMethod">Call Child Method</button>
</template><script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';const childRef = ref(null);const callChildMethod = () => {childRef.value.childMethod(); // Child method calledconsole.log(childRef.value.name) // panda
};
</script>
// 子组件
<template><div>Child Component</div>
</template><script setup>
const childMethod = () => {console.log('Child method called');
};
const name=ref('panda')
defineExpose({childMethod,name,
});
</script>

四、provide 和 inject

祖先组件向后代组件传递数据,适用于多层级组件之间共享数据传值,从而减少 props 钓鱼(prop drilling)的问题

<template><div><h1>父组件</h1><p>提供的消息: {{ parentMessage }}</p><IntermediateComponent /></div>
</template><script setup>
import { provide, ref } from 'vue';
import IntermediateComponent from './IntermediateComponent.vue';// 定义要提供的数据
const parentMessage = ref('Hello from Parent');// 使用 provide 提供数据
provide('parentMessage', parentMessage);
</script><style scoped>
/* 样式可以根据需要添加 */
</style>
//中间组件-子组件
<template><div><h2>中间层组件</h2><ChildComponent /></div>
</template><script setup>
import ChildComponent from './ChildComponent.vue';
</script><style scoped>
/* 样式可以根据需要添加 */
</style>
<template><div><h3>子组件</h3><p>接收到的消息: {{ receivedMessage }}</p></div>
</template><script setup>
import { inject } from 'vue';// 使用 inject 接收父组件提供的数据
const receivedMessage = inject('parentMessage');
</script><style scoped>
/* 样式可以根据需要添加 */
</style>

五、 路由传参

Query

通过 URL 查询参数传递数据

// 父组件
<template><router-link :to="{ name: 'Child', query: { message: 'Hello from Parent' } }">Go to Child</router-link>
</template>
// 子组件
<template><div>{{ message }}</div>
</template><script setup>
import { useRoute } from 'vue-router';const route = useRoute();
const message = route.query.message;
</script>

Params

通过 URL 参数传递数据

// 父组件
<template><router-link :to="{ name: 'Child', params: { id: 123 } }">Go to Child</router-link>
</template>
//子组件
<template><div>ID: {{ id }}</div>
</template><script setup>
import { useRoute } from 'vue-router';const route = useRoute();
const id = route.params.id;
</script>

State

通过路由状态传递数据

//父组件
<template><router-link :to="{ name: 'Child', state: { message: 'Hello from Parent' } }">Go to Child</router-link>
</template>
// 子组件
<template><div>{{ message }}</div>
</template><script setup>
import { useRoute } from 'vue-router';const route = useRoute();
const message = route.state?.message || '';
</script>

六、Pinia

vue3状态管理

// Pinia Store
import { defineStore } from 'pinia';export const useMainStore = defineStore('main', {state: () => ({message: 'Hello from Pinia'}),actions: {updateMessage(newMessage) {this.message = newMessage;}}
});
// 父组件
<template><div>{{ message }}</div><button @click="updateMessage">Update Message</button>
</template><script setup>
import { useMainStore } from '../stores/main';const store = useMainStore();const message = store.message;const updateMessage = () => {store.updateMessage('Updated Message');
};
</script>

七、 浏览器缓存localStorage 或 sessionStorage

// 父组件
<template><div>{{ cachedMessage }}</div><input v-model="cachedMessage" @input="saveMessage" />
</template><script setup>
import { ref, onMounted } from 'vue';const cachedMessage = ref(localStorage.getItem('message') || '');const saveMessage = () => {localStorage.setItem('message', cachedMessage.value);
};onMounted(() => {cachedMessage.value = localStorage.getItem('message') || '';
});
</script>

八、 window 对象全局挂载

// 父组件
<template><div>{{ globalMessage }}</div><input v-model="globalMessage" @input="updateGlobalMessage" />
</template><script setup>
import { ref, onMounted } from 'vue';const globalMessage = ref(window.globalMessage || '');const updateGlobalMessage = () => {window.globalMessage = globalMessage.value;
};onMounted(() => {globalMessage.value = window.globalMessage || '';
});
</script>

九、兄弟组件传值 (mitt)

// 安装 mitt
npm install mitt
// 创建事件总线
// eventBus.js
import mitt from 'mitt';export const emitter = mitt();
// 兄弟A
<template><button @click="sendMessageToSibling">Send Message to Sibling</button>
</template><script setup>
import { emitter } from '../eventBus';const sendMessageToSibling = () => {emitter.emit('siblingEvent', 'Hello from Sibling A');
};
</script>
// 兄弟B
<template><div>{{ message }}</div>
</template><script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { emitter } from '../eventBus';const message = ref('');const handleMessage = (msg) => {message.value = msg;
};onMounted(() => {emitter.on('siblingEvent', handleMessage);
});onUnmounted(() => {emitter.off('siblingEvent', handleMessage);
});
</script>

十、$attrs

  1. 透传属性: 将父组件传递的所有非 prop 属性自动应用到子组件的根元素或其他指定元素上。
  2. 样式和类: 传递 class 和 style 属性,以便子组件能够继承父组件的样式。
  3. 事件监听器: 传递事件监听器,使得子组件能够响应父组件传递的事件。
// 父组件
<template><ChildComponent class="parent-class" style="color: red;" custom-attr="custom-value" @click="handleClick" />
</template><script setup>
import ChildComponent from './ChildComponent.vue';const handleClick = () => {console.log('Clicked on ChildComponent');
};
</script>
// 子组件
<template><div v-bind="$attrs">Child Component</div>
</template><script setup>
// 子组件不需要显式声明父组件传递的属性
</script><style scoped>
.parent-class {background-color: yellow;
}
</style>

默认情况下,Vue 会将 $attrs 应用到子组件的根元素上。如果你不希望这样做,可以通过设置 inheritAttrs: false 来禁用这个行为。

// 子组件
<template><div><span v-bind="$attrs">Child Component</span></div>
</template><script setup>
// 禁用自动应用 $attrs 到根元素
defineOptions({inheritAttrs: false
});
</script>

如果想访问$attrs对象

// 子组件
<template><div><span v-bind="filteredAttrs">Child Component</span></div>
</template><script setup>
import { useAttrs, computed } from 'vue';const attrs = useAttrs();const filteredAttrs = computed(() => {// 过滤掉不需要的属性return Object.fromEntries(Object.entries(attrs).filter(([key]) => !['custom-attr'].includes(key)));
});
</script>

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com