VUE3 + element-plus,子组件向父组件发送消息(调用父组件函数没有反应),this.$emit方法,请大佬们帮俺看看,谢谢
全部的代码
<template> <!-- <el-text class="mx-1">条件 {{": "}}</el-text>--> <div style="margin-bottom: 10px" v-if="dynamicTags.length !=0"> <el-text tag="b"> 条件:</el-text> <el-tag v-for="tag in dynamicTags" :key="tag" :size="'default'" :hit="true" closable :disable-transitions="false" @close="handleClose(tag)" style="margin-left: 10px" effect="dark" round > {{ tag }} </el-tag> </div> <div> <el-table :data="tableData" style="width: 100%" max-height="500" border stripe highlight-current-row @header-click="headClick" @selection-change="handleSelectionChange" > <el-table-column v-for="[p,f] in props" :prop="p" :label="p" :fixed="f" :width="150" :align="'center'" :sortable="true" :min-width="100" > <template #header> <newnew v-if="click_value==p" :column="p" :column_filter_type="'scope'" :select_items="select_item"></newnew> </template> </el-table-column> <el-table-column label="Info" width="150" :align="'center'"> <template #default="scope"> <el-button type="primary" size="small" @click="more_about(scope.$index)" >ShowMore </el-button > </template> </el-table-column> <el-table-column type="selection" width="55" :fixed="'right'"/> </el-table> <el-pagination style="margin-top : 10px; text-align:center" v-model:current-page="currentPage3" v-model:page-size="pageSize3" :small=true :background=true layout="total, prev, pager, next, jumper" :total="100" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> </div></template><script lang="ts" setup>import {get_filter_type, legal_judge, zip} from '../../api/utils'import {nextTick, ref} from 'vue'import {ElMessage, ElMessageBox, ElInput} from 'element-plus'import type {Action} from 'element-plus'import {getTableData, getTableProps} from "../../api/test-data"import customHeader from "./customHeader.vue";import newnew from "./newnew.vue"let click_value = ref("")let pageSize3 = ref(20)let currentPage3 = ref(1)function handleSizeChange(value) { // 页面大小改变 console.log("handleSizeChange " + value)}function handleCurrentChange(value) { // 当前页码改变 console.log("handleCurrentChange " + value)}function log() { console.log("stop")}const row_labels = getTableProps()const tableData = getTableData()const fixed = Array(row_labels.length)fixed[0] = truefor (let i = 1; i < row_labels.length; i++) { fixed[i] = false}const props = zip(row_labels, fixed)const inputValue = ref('')const dynamicTags = ref(['Tag 1', 'Tag 2', 'Tag 3'])const inputVisible = ref(false)const InputRef = ref<InstanceType<typeof ElInput>>()const select_item = [[0, '0'], [1, '1']]const handleClose = (tag) => { dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1) console.log(`delete tag: ${tag}`)}function headClick(column, event) { console.log(`${column.label}`) click_value.value = column.label}function handleSelectionChange(value) { console.log("handleSelectionChange" + value)}function conditionUpdate(data) { /** * @param data {column, column_filter_type, condition} * des: 用户传来筛选条件来更新表格 */ let {column, column_filter_type, condition} = data let filter_type = get_filter_type() if (column_filter_type === filter_type['text']) { } if (column_filter_type === filter_type['scope']) { } if (column_filter_type === filter_type['date']) { } if (column_filter_type === filter_type['select']) { } console.log("conditionUpdate " + data)}
<template> <div @click.stop style="display: inline-block "> <el-popover placement="bottom" title="查询条件" trigger="hover" width="300" :visible=open_flag ref="popoverRef" > <template #reference> <span @click="open_flag=true">{{ column }}</span> </template> <!-- text 文本简略搜索--> <div v-if="column_filter_type === filter_type['text']"> <el-input style="width: 200px" v-model="this.condition.value_start" placeholder="请输入查询内容" > </el-input> </div> <!-- scope 范围 数值类型--> <div v-else-if="column_filter_type === filter_type['scope']"> <el-input style="width: 120px" v-model="this.condition.value_start" placeholder="条件1" ></el-input> - <el-input style="width: 120px" v-model.trim="condition.value_end" placeholder="条件2" ></el-input> </div> <!-- date 日期--> <div v-else-if="column_filter_type === filter_type['date']"> <el-date-picker style="width: 120px; margin-top: 10px;margin-right: 10px" v-model="condition.value_start" type="date" clearable placeholder="开始时间" value-format="YYYY-MM-DD" ></el-date-picker> <el-date-picker style="width: 120px; margin-top: 10px;" v-model="condition.value_end" type="date" clearable placeholder="结束时间" value-format="YYYY-MM-DD" ></el-date-picker> </div> <!-- select 选择框--> <div v-else-if="column_filter_type===filter_type['select']"> <el-select v-model="condition.value_start" placeholder="请选择" style="width: 100%" clearable > <el-option v-for="[value, index] in select_items" :key="index" :label="value" :value="value" > </el-option> </el-select> </div> <div v-else> <el-text type="warning" tag="b">此数据类型暂不支持查询</el-text> </div> <br> <div style="text-align: right; margin-left: 20px"> <el-button text @click="open_flag=false">cancel</el-button> <el-button type="primary" @click="confirm">confirm</el-button> </div> </el-popover> </div></template><script>import {ref} from "vue";import {get_filter_type, legal_judge} from "../../api/utils.ts";export default { name: "newnew", props: ["column", "column_filter_type", "select_items"], data() { return { open_flag: ref(true), condition: { value_start: "", value_end: "" }, filter_type: get_filter_type() } }, methods: { confirm() { this.open_flag = false if (this.column_filter_type === this.filter_type['text']) { if (!legal_judge('text', this.condition)) { return this.$message.warning("请正确筛选条件"); } } else if (this.column_filter_type === this.filter_type['scope']) { if (!legal_judge('scope', this.condition)) { return this.$message.warning("请正确筛选条件"); } } else if (this.column_filter_type === this.filter_type['date']) { if (!legal_judge('date', this.condition)) { return this.$message.warning("请正确筛选条件"); } } else if (this.column_filter_type === this.filter_type['select']) { if (!legal_judge('select', this.condition)) { return this.$message.warning("请正确筛选条件"); } } else { return null } console.log(this.condition.value_start) console.log(this.condition.value_end) this.$emit("conditionUpdate", { column: this.column, column_filter_type: this.column_filter_type, condition: this.condition }) }, }}</script>
百度了好久都怎么管用的,刚学不太懂
你理解错了,子组件想调用父组件的函数一般有两个方法,一种是把函数当成一个 props 传入
// 父组件<newnew ... :update="conditionUpdate"/>// 子组件<script> props: [..., 'update'], ... methods: { confirm() { this.update(xxx) } } </script>
或者是子组件去触发注册的事件,比如你的子组件触发了一个 update
事件,父组件在触发 update
的时候调用这个方法
// 父组件<newnew ... @update="conditionUpdate"/>// 子组件<script> props: [..., 'update'], ... methods: { confirm() { this.emit('update', xxx) // 子组件在这里触发了 update 事件,就调用了 update 事件绑定的函数 conditionUpdate } } </script>
从你给出的代码和描述来看,你在使用 Vue 3 和 Element Plus 时遇到了 this.$emit
失效的问题。this.$emit
通常用于子组件向父组件发送消息。首先,我们需要确认几个可能的问题来源:
this.$emit('conditionUpdate', data)
,那么在父组件中,你应该有一个类似于 @condition-update="handleConditionUpdate"
的监听器。setup
函数中的 emit
:在 Vue 3 中,this
不再是可用的,所以你不能使用 this.$emit
。相反,你应该在 setup
函数的参数中接收 emit
。例如:<script lang="ts" setup>// ... 其他代码 ...const emit = defineEmits(['conditionUpdate']);// ... 其他代码 ...function handleClose(tag) { dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1) console.log(`delete tag: ${tag}`) emit('conditionUpdate', { /* 你的数据 */ });}// ... 其他代码 ...</script>
props
和 emits
选项:在子组件的定义中,确保你声明了 emits
选项,这样 Vue 就知道这个组件会发出哪些事件。<script>export default { name: "newnew", props: ["column", "column_filter_type", "select_items"], emits: ['conditionUpdate'], // 这里声明 // ... 其他代码 ...}</script>
如果以上都没有问题,那么可能需要进一步检查你的代码以找出具体的问题所在。你可以尝试简化代码,逐步排除可能的问题,或者考虑创建一个最小化的可复现问题的示例,这样更容易找到问题的根源。
element-plus 官网里面的 Layout 布局中的示例,官方文档中添加类名 class="grid-content ep-bg-purple-dark" 有相应的样式 为什么在自己的代码中使用这些类名没有相关的样式? 希望有相关的样式
使用 vite 打包组件库,在新的项目中使用时报错 下面是打包后的产物 pe 和 dn 找不到导致项目启动时就报错, 手动再新起一个别名时会结局此问题 vite.config.ts 配置如下 请问这个问题该怎么解决
设置element plus table上的header-cell-class-name为什么没有生效? 在webstorm中这个样式呈现灰色,说明它没有被使用。从页面显示上发现这个样式也没有生效,但是我将这段代码复制到element plus playground却生效了,这是为什么?该怎么解决?
系统使用了element-plus按需载入的方式 我需要在一个组件内动态加载某些组件 这个loader方法一直无法正确渲染相应组件,例如type传入“ELInput”时系统会报个警告 尝试过import('element-plus/lib/components/ElInput')这种写法页不行,报错:[plugin:vite:import-analysis] No known conditions
请问大佬们,如何点击左侧的el-side的菜单,右侧el-main就生成对应的路由标签栏el-tag,每个标签对应一个路由页面,点击该标签可以进入该路由页面???
下面这段代码来自于element-plus官网,有几点我不明白。 1.这里为什么用setTimeout?有必要吗?它是在失焦的时候才会触发验证 2.这里的ruleFormRef.value.validateField('checkPass')有必要吗?在失焦之后,checkpass字段不也会触发验证吗?如果设置change时校验,这还是有用的。 3.这里的rules有必要为响应式数据吗? 全部代码