

vue3,vue组件,props给一个对象参数。vue组件间传参数,vue父组件给子组件传参数。组件参数类型。父组件调用子组件的方法。vue组件事件监听,给子组件传递方法,子组件调用父组件方法

组件可以使用props给组件传值,可以同时传递多个,可以是任意类型,比如字符串或者对象。
下面是个简单的例子:
<div id="components-demo">
<blog-post test="aaa" content="哈哈哈"></blog-post>
<blog-post test="hello component" content="嘿嘿嘿"></blog-post>
</div>
<script>
//向子组件传值
Vue.component('blog-post', {
props: ['test', "content"],
template: '<h3>{{ test }}:{{content}}</h3>'
})
var vm = new Vue({
el: '#components-demo'
});
</script>
效果如下:
在贴一个传多个props简单的例子,可以自己运行看看效果:
<div id="blog-post-demo">
<blog-post
v-for="post in posts"
v-bind:mykey="post.id"
v-bind:title="post.title"></blog-post>
</div>
<script>
//向子组件传值
Vue.component('blog-post', {
props: ['mykey', "title"],
template: '<h3>{{ mykey }}:{{title}}</h3>'
});
new Vue({
el: '#blog-post-demo',
data: {
posts: [
{ id: 1, title: 'My journey with Vue' },
{ id: 2, title: 'Blogging with Vue' },
{ id: 3, title: 'Why Vue is so fun' }
]
}
})
</script>
但是如果一个组件内部需要的参数很多,不可能去定义那么多的props参数,还要用那么多的v-bind去给props钟的参数赋值,这个时候就可以只给一个props参数,给一个对象,然后只需要给一个参数使用v-bind赋值即可。
<div id="blog-post-demo">
<blog-post v-for="article in myArticles" v-bind:article="article"></blog-post>
</div>
<script>
//向子组件传值
Vue.component('blog-post', {
props: ['article'],
template: '<div><h4>{{article.title}}</h4><div>{{article.content}}</div><div>作者:{{article.autor}}</div></div>'
});
new Vue({
el: '#blog-post-demo',
data: {
myArticles: [
{ content: "只要你敢,我会毫不犹豫地跟你走,不顾一切,带着一腔勇敢和爱,跟你走。可是啊,你还是不敢", title: '文章一', autor: "aa" },
{ content: "还是很喜欢你,性情善良,待人真诚,像日光洒满天地,温柔惬意", title: '文章二', autor: "xx" },
{ content: "想把每天发生的事都分享给你的人大概是真的真的很喜欢你吧", title: '文章三', autor: "jj" }
]
}
});
</script>
注意几点
- props: [‘article’] 也要设置一个参数,虽然可以是对象。但是也要提供
- 使用v-bind提供参数,比如这里的v-bind:article。 如果不提供参数模块里边是拿不到的
- 外面使用组件的时候提供值的名称和组件里边的无关,可以随便取,比如这里组件里边定义的props属性名叫article,但是外面我使用的是data使用的是myArticles
效果如下:
Vue组件传递参数的类型常用可选的有
'title':String,
'bool':Boolean,
'getFun':Function
普通类型:字符串(String)、数字(Number)、布尔值(Boolean)、空(Null)
引用类型:数组(Array)、对象(Object)
常用类型的定义示例:
// 组件参数
props: {
percentage: {
type: Number,
default: 0
},
title: {
type: String,
default: ''
},
show: {
type: Boolean,
default: false
},
// 列配置
columnsConfg: {
type: Array,
default: () => {
return []
},
},
// 数据项
rowdata: {
type: Array,
default: () => {
return []
},
// required: true
}
// 对象参数
datas: {
type: Object,
default: () => {
return {CompleteRate:50,PassRate:60,TrueRate:80}
},
}
},
常用类型的使用示例:
Boolean类型:
<MyGrid title="图表展示" :Showtitle="false" style="height:100%">
</MyGrid>
对象类型:
<DataChart :datas="datas" />
数据也是按照正常的方式提供即可
data() {
return {
datas:{CompleteRate: 60, PassRate: 70, TrueRate: 90},
}
},
字符串类型,int类型,数组类型
提供参数的时候具体加不加冒号,看着是直接给的还是通过数据绑定上去的
<ScrollTable rowStyle="content_tr_center" :runSpeed="teacherDataRunSpeed" :scrollContentHeight=310
:columnsConfg="teacherColumnsConfg" :rowdata="teacherRowdata">
</ScrollTable>
其中数组类型
提供的值也和正常绑定的一样的放到data里边就行,比如
data() {
return {
teacherColumnsConfg: [
{
label: "教员",
prop: "teacherName",
width: "90px",
},
{
label: "班级数",
prop: "classCount",
width: "90px",
},
{
label: "课程数",
prop: "courseCount",
width: "90px",
}
}
}
}
vue3里边父组件给子组件传参
传递:
<OceanFreightTableEdit title="海运费" :isCanEditOceanFreight="ruleForm.isCanEditOceanFreight" ref="OceanFreightTableEditRef"></OceanFreightTableEdit>
默认参数:
const props = defineProps({
schoolId: String,
taskIds: {
type: [] as any,
default:[]
},
IsQueryMySelf: {
type: Boolean,
default: false
},
})
接收
const props = defineProps({
title: String,
isCanEditOceanFreight: Boolean
})
取值:
<el-checkbox v-if="props.isCanEditOceanFreight" checked="true" disabled="true" v-model="isCanEdit" size="default" />
取值直接可以这样:props.isCanEditOceanFreight,props.title这种。
注意:父向子传参数的时候要注意时机问题哦,比如要传递的某个参数要从接口里边查询回来,然后组件的加载要比接口数据返回回来之前被加载了,这样传递到组件里边的参数永远都是默认的参数,不会是从接口回来的参数,所以这种情况就要进行处理,可以考虑等接口返回回来了在去加载组件,或者在子组件里边去监听一下父组件传递参数的值的变化也可以。
vue父组件调用子组件的方法
可以直接使用ref,在引用子组件的地方添加一个ref
<FeedbackDialog ref="feedbackDialog" />
然后通过ref的名字拿到子组件就可以调用子组件的方法了
this.$refs.feedbackDialog.openFeedbackDialog();
可以用来传递参数,或者需要一个字段双向绑定的时候可以参考使用这种方式
vue3父组件调用子组件的方法
子组件
在<script setup>
中子组件需要使用defineExpose暴露出来需要的方法,才能被父组件调用
// 子组件需要使用defineExpose暴露出来需要的方法,才能被父组件调用
defineExpose({ getTrainingSubProgramList })
父组件
<SubProgramPublic ref="subProgramPublicRef"></SubProgramPublic>
// 注意:这里的属性名必须跟子组件定义的 ref 值一模一样,否者会关联失效
const subProgramPublicRef = ref(null)
const subProgramSaveSuccess = ()=>{
// 调用子组件的方法
subProgramPublicRef.value.getTrainingSubProgramList()
}
vue组件事件监听,给组件传递方法。子组件事件触发父组件方法
封装的组件里边,使用$emit方法就行,规定一个方法名称
<div class="title_com_menu" v-if="ShowtitleMenu" @click="$emit('menuclick','可以传递需要的参数回去')">
<div class="title_com_menu_dot"></div>
<div class="title_com_menu_dot"></div>
<div class="title_com_menu_dot"></div>
</div>
然后使用的时候这样就行
<MyGrid style="height:100%" title="教学动态" :ShowtitleMenu="true" @menuclick="menuclick()"/>
<MyGrid style="height:100%" title="学习数据" :ShowtitleMenu="true" @menuclick="learnDataMore()"/>
内部当前不一定要在@click
中去触发,其他方式也可以,比如在表单填写好数据,进行数据验证成功后在调用引用组件时候定义的方法,相当于就类似一个回调函数的使用方式,但是用起来要灵活一些随时定义,随时使用
saveLoadPortCharges() {
var self = this
self.$refs['editFormRef'].validate((valid) => {
if (valid) {
console.log(self.editFromData)
// 通过emit调用引用组件时候定义的方法
self.$emit('insertData',self.editFromData)
}
})
}
但是要注意这种方式父子组件只能跨一级,不能跨两级,比如子组件调用爷爷组件就不行。
如果是跨越多级可以这样使用
my.$parent.$parent.changeLabroomTodayCount(res.data.todayCount)
跨几级就调用几次$parent
还可以使用EventBus等方式比如:https://blog.csdn.net/weixin_44867717/article/details/125632991
vue3子组件调用父组件方法
子组件:
<template>
<view class="container">
<view @click="handleClose">关闭</view>
</view>
</template>
const emit = defineEmits(['closePopup'])
const handleClose = () => {
emit('closePopup','参数')
}
父组件:
<uni-popup ref="classRankingPopup" type="bottom" @change="change">
<classSort :classRankData="state.classRankData" @closePopup="closeClassRankingPopup"></classSort>
</uni-popup>
如果是有多个方法就这样
子组件
<template>
<view class="popup-container">
<view class="titleWrap">
<view class="title">{{ title }}</view>
<view class="closeTag" @tap="handleClose">×</view>
</view>
<scroll-view scroll-y="true" style=" height: 666rpx;">
<view class="pc-content" >
<view class="pcc-item" @tap="choiseClass(item.id,item.className)" v-for="(item, index) in state.classList" :key="index">
{{item.className}}
</view>
</view>
</scroll-view>
</view>
</template>
// 触发closePopup事件(关闭事件)
const emit = defineEmits(['closePopup','choiseClass'])
const handleClose = () => {
emit('closePopup', '参数')
}
// 点击选择了班级,传递了班级id和班级名称
const choiseClass = (_classId:string,_className:string) => {
emit('choiseClass', _classId,_className)
}
父组件:
<uni-popup ref="choiseClassPopup" background-color="#fff" border-radius="60rpx 60rpx 0rpx 0rpx;" type="bottom"
@change="methods.change">
<choiseClass @closePopup="popupMethods.closeChoiseClassDetails" @choiseClass="methods.choiseClass"></choiseClass>
</uni-popup>
const methods = {
// 弹窗里边重新选择班级后的查询
choiseClass: function (_classId: string,_className:string) {
console.log("重新选择班级了",_classId)
// 关闭弹窗
popupMethods.closeChoiseClassDetails()
state.classId = _classId
state.className =_className
}
}
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)
饰心
哇 好神奇