当前位置: 首页 > 知识库问答 >
问题:

javascript - VUE3 + element-plus, this.$emit失效,为什么?

郏志诚
2024-03-19

VUE3 + element-plus,子组件向父组件发送消息(调用父组件函数没有反应),this.$emit方法,请大佬们帮俺看看,谢谢
image.png
image.png
image.png
全部的代码

<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>

百度了好久都怎么管用的,刚学不太懂

共有2个答案

呼延俊风
2024-03-19

你理解错了,子组件想调用父组件的函数一般有两个方法,一种是把函数当成一个 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>
齐嘉庆
2024-03-19

从你给出的代码和描述来看,你在使用 Vue 3 和 Element Plus 时遇到了 this.$emit 失效的问题。this.$emit 通常用于子组件向父组件发送消息。首先,我们需要确认几个可能的问题来源:

  1. 拼写和大小写:确保你正确拼写了事件名称,并且大小写是正确的。
  2. 事件监听:在父组件中,确保你正确监听了子组件发出的事件。例如,如果你在子组件中使用了 this.$emit('conditionUpdate', data),那么在父组件中,你应该有一个类似于 @condition-update="handleConditionUpdate" 的监听器。
  3. 组件的引用:确保你正确引用了子组件,并且子组件已经被正确注册和导入。
  4. 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>
  1. propsemits 选项:在子组件的定义中,确保你声明了 emits 选项,这样 Vue 就知道这个组件会发出哪些事件。
<script>export default {  name: "newnew",  props: ["column", "column_filter_type", "select_items"],  emits: ['conditionUpdate'], // 这里声明  // ... 其他代码 ...}</script>
  1. Vue 版本和 Element Plus 版本:确保你使用的 Vue 和 Element Plus 的版本是兼容的。

如果以上都没有问题,那么可能需要进一步检查你的代码以找出具体的问题所在。你可以尝试简化代码,逐步排除可能的问题,或者考虑创建一个最小化的可复现问题的示例,这样更容易找到问题的根源。

 类似资料:
  • 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有必要为响应式数据吗? 全部代码