uniapp如何创建并使用组件?组件通过Props如何进行数据传递?

欢迎来到我的UniApp技术专栏!🎉 在这里,我将与大家分享关于UniApp开发的实用技巧、最佳实践和项目经验。

专栏特色:

📱 跨平台开发一站式解决方案
🚀 从入门到精通的完整学习路径
💡 实战项目经验分享
🔍 常见问题深度解析
无论你是刚接触UniApp的新手,还是有一定经验的开发者,都能在这里找到有价值的内容。我将持续更新最新技术动态和开发技巧,帮助大家提升开发效率,打造高质量的跨平台应用。

如果文章对你有帮助,别忘了点赞收藏🌟,也欢迎在评论区留言交流,我会及时回复大家的问题!

让我们一起探索UniApp的无限可能!💪

目录

一.创建组件

1.在项目根目录下,创建components文件夹

2.右击“components”目录,选择创建组件

3.在创建的UserInfo组件中,编写代码

二.使用组件

三.组件通过Props进行数据传递

1.在父组件中,传递数据

2.在子组件中,接收父组件传来的数据

3.案例代码

4.props校验和默认值的用法

5.传递一个对象

6.传递一个对象数组


一.创建组件

1.在项目根目录下,创建components文件夹

注意:文件夹名称一定不能错!

2.右击“components”目录,选择创建组件

3.在创建的UserInfo组件中,编写代码

二.使用组件

我们直接在index.vue中,使用组件名,作为一个标签即可访问自定义组件。

运行效果

以上是我们访问index.vue页面的样子,因为index.vue中使用了<UserInfo></UserInfo>组件。

三.组件通过Props进行数据传递

注意:一般我们使用Props,是从父组件传递数据给子组件(即:父亲给孩子分配资源)。

1.在父组件中,传递数据

如下图,在index.vue(父组件)中,我们向子组件UserInfo.vue传递了username(用户名)、avatar(头像)这两个数据。

2.在子组件中,接收父组件传来的数据

在子组件中,可以通过defineProps直接来接收父组件传来的数据。

 注意:父组件传来的数据,是只读的,也就是说,我们不能直接修改username、avatar,但是可以使用。

        此时我们可以定义一个props变量,来接收defineProps的值,然后就能使用了。

3.案例代码

父组件index.vue的代码

<template>
	<view class="content">
		<UserInfo username="casually" avatar="../../static/avatar1.png"></UserInfo>
		<UserInfo username="gem" avatar="../../static/avatar2.png"></UserInfo>
		<UserInfo :username="name" avatar="../../static/avatar3.png"></UserInfo>
	</view>
</template>

<script setup>
import {ref} from 'vue';
const name = ref("王五");
</script>

<style>
	
</style>

子组件UserInfo.vue的代码

<template>
	<view class="userinfo">
		<image :src="avatar"></image>
		<view>{{username}}</view>
	</view>
</template>

<script setup>
const props = defineProps(['username','avatar']);
console.log("父组件传来的用户名是:" + props.username);
console.log("父组件传来的头像url是:" + props.avatar);
</script>

<style lang="scss" scoped>
.userinfo{
	width:100%;
	height:200px;
	background:#ccc;
	display: flex;
	align-items: center;
	justify-content: center;
	flex-direction:column;
	image{
		width:100px;
		height:100px;
		border-radius: 50%;
	}
	.username{
		padding:10px 0;
		font-size: 20px;
	}
}
</style>

运行效果:访问index.vue页面的效果如下图所示

4.props校验和默认值的用法

当我们在父组件中,不传递部分数据,会出现如下情况:

解决方案:在子组件中,接收父组件的数据时,就设置每一个参数的类型和默认值,如下:

运行效果

5.传递一个对象

父组件

<template>
	<view class="content">
		<UserInfo :obj="userinfo"></UserInfo>
		<UserInfo></UserInfo>
	</view>
</template>

<script setup>
import {ref} from 'vue';
const userinfo = ref(
	{
		name:"张三",
		avatar:"../../static/avatar1.png"
	}
)
</script>

<style>
	
</style>

子组件

<template>
	<view class="userinfo">
		<image :src="obj.avatar"></image>
		<view>{{obj.name}}</view>
	</view>
</template>

<script setup>
//defineProps(["obj"])
defineProps({
	obj:{
		type:Object,
		default(){
			return {name:"匿名", avatar:"../../static/logo.png"}
		}
	}
})
</script>

<style lang="scss" scoped>
.userinfo{
	width:100%;
	height:200px;
	background:#ccc;
	display: flex;
	align-items: center;
	justify-content: center;
	flex-direction:column;
	image{
		width:100px;
		height:100px;
		border-radius: 50%;
	}
	.username{
		padding:10px 0;
		font-size: 20px;
	}
}
</style>

运行效果

6.传递一个对象数组

父组件

<template>
	<view class="content">
		<UserInfo v-for="item in userinfo" :obj="item"></UserInfo>
	</view>
</template>

<script setup>
import {ref} from 'vue';
const userinfo = ref([
	{name:"张三",avatar:"../../static/avatar1.png"},
	{name:"李四",avatar:"../../static/avatar2.png"},
	{name:"王五",avatar:"../../static/avatar3.png"},
]
)
</script>

<style>
	
</style>

子组件

<template>
	<view class="userinfo">
		<image :src="obj.avatar"></image>
		<view>{{obj.name}}</view>
	</view>
</template>

<script setup>
//defineProps(["obj"])
defineProps({
	obj:{
		type:Object,
		default(){
			return {name:"匿名", avatar:"../../static/logo.png"}
		}
	}
})
</script>

<style lang="scss" scoped>
.userinfo{
	width:100%;
	height:200px;
	background:#ccc;
	display: flex;
	align-items: center;
	justify-content: center;
	flex-direction:column;
	image{
		width:100px;
		height:100px;
		border-radius: 50%;
	}
	.username{
		padding:10px 0;
		font-size: 20px;
	}
}
</style>

运行效果

以上就是本篇文章的全部内容,喜欢的话可以留个免费的关注呦~

<think>嗯,用户想知道在UniApp中如何通过组件传递对象类型的数据。首先,我需要回忆一下UniApp组件通信方法,特别是涉及到对象的情况。根据之前的引用资料,父组件向子组件传参通常使用props,而子组件向父组件则是通过事件触发。不过传递对象的话,可能会有一些需要注意的地方。 首先,父传子的话,应该在子组件中定义props,类型设置为Object。用户可能需要示例代码,比如父组件如何绑定对象数据到子组件,子组件如何接收和使用。需要确保props在子组件中正确声明,且对象是响应式的,可能涉及到深拷贝的问题,因为直接传递对象的话,子组件修改可能会影响父组件数据,这点需要提醒用户注意。 然后是子传父的情况,子组件通过$emit触发事件,传递对象参数。这里需要给出一个示例,展示子组件如何发送对象,父组件如何监听事件接收数据。另外,用户可能还需要知道跨层级或兄弟组件之间的通信,这时候可能需要使用Vuex或者全局事件总线。不过根据提供的引用,用户可能更倾向于直接的父子组件传参方法,所以应该先重点讲解props和事件传递,再提到Vuex作为补充。 还要检查是否有其他传参方法适用,比如uni.navigateTo的URL传参,但对象数据可能比较复杂,需要序列化和反序列化,比如使用JSON.stringify和JSON.parse,这时候要注意URL长度的限制,不适合传递过大的对象。这点需要提醒用户,避免在传递数据时出现问题。 另外,用户提供的引用资料中提到,子组件可以通过this.$parent访问父组件实例,但这种方法可能不推荐,因为它增加了组件间的耦合性。所以应该建议优先使用props和事件,而不是直接访问父实例。 最后,确保给出的示例代码符合UniApp的语法规范,比如使用Vue的组件结构,正确使用this.$emit,以及props的定义。同时,提醒用户关于数据响应式的问题,如果父组件传递的对象在子组件中被修改,是否希望父组件数据同步更新,这时候可能需要使用深拷贝或者Vue的响应式方法,如使用Vue.set等。 总结一下,回答的结构应该是先介绍父传子的props方法,给出示例;然后子传父的事件方法,示例;接着提到复杂情况下的Vuex使用,以及URL传参的注意事项。最后提醒响应式数据处理的要点,生成相关问题。</think>### UniApp组件传递对象数据的方法 在UniApp中,组件传递对象数据主要通过以下方式实现: --- #### 一、父组件向子组件传递对象(Props) 1. **子组件定义Props** 子组件中通过`props`声明接收对象类型的参数,需指定`type: Object`: ```javascript // 子组件 child-component.vue export default { props: { userInfo: { type: Object, default: () => ({}) // 默认值为空对象 } }, mounted() { console.log('接收的对象数据:', this.userInfo); // 验证数据接收 } } ``` 2. **父组件传递对象** 父组件通过属性绑定的方式传递对象(需添加`:`表示动态绑定): ```html <!--组件 parent.vue --> <template> <child-component :user-info="parentUserData" /> </template> <script> export default { data() { return { parentUserData: { name: '张三', age: 25 } } } } </script> ``` **注意**:对象传递为引用类型,子组件修改可能影响父组件数据。若需完全隔离,可使用深拷贝[^3]。 --- #### 二、子组件向父组件传递对象(自定义事件) 1. **子组件触发事件** 通过`this.$emit`发送事件携带对象参数: ```javascript // 子组件 child-component.vue methods: { sendData() { const data = { status: 'success', code: 200 }; this.$emit('update-data', data); // 事件名 + 参数 } } ``` 2. **父组件监听事件** 父组件通过`@事件名`接收数据: ```html <!--组件 parent.vue --> <template> <child-component @update-data="handleData" /> </template> <script> export default { methods: { handleData(data) { console.log('接收的子组件数据:', data); // {status: 'success', code: 200} } } } </script> ``` --- #### 三、跨组件传递对象(全局状态管理) 对于非父子关系的组件,建议使用**Vuex**: 1. 定义全局状态: ```javascript // store/index.js export default new Vuex.Store({ state: { sharedObject: { key: 'value' } }, mutations: { updateObject(state, payload) { state.sharedObject = payload; } } }); ``` 2. 组件中通过`this.$store`调用: ```javascript // 任意组件 this.$store.commit('updateObject', { newKey: 'newValue' }); ``` --- #### 四、页面间传递对象(URL传参) 通过`uni.navigateTo`传递时需序列化对象: ```javascript // 发送页面 const obj = { id: 1, type: 'test' }; uni.navigateTo({ url: `/pages/detail?data=${encodeURIComponent(JSON.stringify(obj))}` }); // 接收页面 onLoad(options) { const data = JSON.parse(decodeURIComponent(options.data)); } ``` **注意**:URL参数长度有限制,大对象建议用全局变量或Vuex[^2]。 --- ### 关键问题总结 1. **响应式问题** 若需父子组件数据联动,可直接修改对象属性(需确保父组件数据为响应式)。若需完全独立,应使用`JSON.parse(JSON.stringify(obj))`深拷贝。 2. **性能优化** 复杂对象建议通过Vuex共享,避免多次传递---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值