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

作者站长头像
站长
· 阅读数 31

VUE3 + element-plus,子组件向父组件发送消息(调用父组件函数没有反应),this.$emit方法,请大佬们帮俺看看,谢谢VUE3 + element-plus, this.$emit失效,为什么?VUE3 + element-plus, this.$emit失效,为什么?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] = true
for (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>

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

回复
1个回答
avatar
test
2024-06-20

你理解错了,子组件想调用父组件的函数一般有两个方法,一种是把函数当成一个 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>
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容