vue通过js代码实例化组件

这篇具有很好参考价值的文章主要介绍了vue通过js代码实例化组件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最近在写项目的一些公共组件(一些选择器),很多个地方都需要用,所以在main.js全局声明了,但发现子页面调用还是有挺多的地方需写。

例如,要在template实例化组件,并用ref绑定,然后在js里的methods里写方法。

main.js 声明全局组件

vue通过js代码实例化组件

第一种方案

一开始想到的是用ref绑定组件,业务组件实例化公共组件,并赋予ref,然后通过这个ref绑定,直接调用公共组件的方法(为了一定能触发方法),例如  this.$refs.xxx.open()

如果用户在公共组件中,选择好数据操作完成后,公共组件触发emit方法,通过回调方法的方式通知业务组件,例如 this.$emit("getTableSelect",this.selection)

以下是相关代码:

公共组件

<template>
  <div>
    <el-dialog
      v-loading="loading"
      :before-close="cancel"
      :close-on-click-modal="false"
      :element-loading-text="loadingText"
      :visible="dialogVisible"
      append-to-body
      title="科目选择器"
      width="80%"
    >
      <el-form
        ref="queryForm"
        :inline="true"
        :model="queryParams"
        label-width="68px"
        size="small"
      >
        <el-form-item label="名称" prop="name">
          <el-input
            v-model="queryParams.name"
            clearable
            placeholder="请输入名称"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-select
            v-model="queryParams.status"
            clearable
            placeholder="请选择状态"
          >
            <el-option
              v-for="dict in dict.type.sys_normal_disable"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button
            icon="el-icon-search"
            size="mini"
            type="primary"
            @click="handleQuery"
            >搜索
          </el-button>
        </el-form-item>
      </el-form>

      <el-table
        v-loading="loading"
        :data="dataList"
        @row-dblclick="rowDblclick"
        @selection-change="handleSelectionChange"
      >
        <el-table-column align="center" type="selection" width="55" />
        <el-table-column align="center" label="科目id" prop="subjectId" />
        <el-table-column align="center" label="名称" prop="name" />
        <el-table-column align="center" label="介绍" prop="intro" />
        <el-table-column align="center" label="排序" prop="sort" />
        <el-table-column align="center" label="状态" prop="status">
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_normal_disable"
              :value="scope.row.status"
            />
          </template>
        </el-table-column>
        <el-table-column align="center" label="备注" prop="remark" />
      </el-table>
      <div slot="footer" style="text-align: center">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">关闭</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { listSubject } from "@/api/as/subject";

export default {
  name: "TableSelect",
  dicts: ["sys_normal_disable"],
  data() {
    return {
      loading: false,
      loadingText: "数据正在处理中...",
      dialogVisible: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        name: null,
        status: null,
      },
      // 总条数
      total: 0,
      //表格数据
      dataList: [],
      //被选择的行
      selection: [],
    };
  },

  methods: {
    /**
     * 打开窗口
     */
    open(name) {
      this.dialogVisible = true;
      this.queryParams.name = name;
      this.handleQuery();
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 查询科目列表 */
    getList() {
      this.loading = true;
      listSubject(this.queryParams).then((response) => {
        this.dataList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    //取消
    cancel() {
      this.dialogVisible = false;
      this.reset();
    },
    //确定
    submitForm(row) {
      if (row) {
        this.$emit("getTableSelect", row);
      } else if (this.selection.length > 0) {
        this.$emit("getTableSelect", this.selection);
      } else {
        this.$message.warning("请选择");
        return;
      }

      this.dialogVisible = false;
      this.reset();
    },
    //重置信息
    reset() {
      this.queryParams = {
        pageNum: 1,
        pageSize: 10,
        name: null,
        status: null,
      };
      this.dataList = [];
      this.selection = [];
    },
    //表格选择改变
    handleSelectionChange(selection) {
      this.selection = selection;
    },
    //双击
    rowDblclick(row) {
      this.submitForm(row);
    },
  },
};
</script>
<style lang="scss" scoped></style>

业务组件(简化)

<template>
  <div class="app-container">
    <el-input
      v-model="queryParams.name"
      clearable
      placeholder="回车搜索科目"
      @keyup.enter.native="handleTableSelect"
    />
    <table-select ref="tableSelect" @getTableSelect="getTableSelect" />
  </div>
</template>

<script>
export default {
  name: "Chapter",

  data() {
    return {
      // 遮罩层
      loading: true,
      // 查询参数
      queryParams: {
        name: null,
      },
    };
  },

  methods: {
    //去打开窗口选择
    handleTableSelect() {
      this.$refs.tableSelect.open(this.queryParams.name);
    },
    //获取选择的行
    getTableSelect(row) {
      this.queryParams.name = row.name;
    },
  },
};
</script>

效果图

vue通过js代码实例化组件

 

vue通过js代码实例化组件

 

vue通过js代码实例化组件

 

第一种方案,虽然可以使用,但业务组件若要使用,则需要正确在4个地方写上对应的代码

即,1.实例化公共组件,并写上ref和getTableSelect的事件监听,2.输入框写上回车事件,3.回车事件里触发公共组件的方法,4.写getTableSelect事件监听的方法。

vue通过js代码实例化组件

 

若别的小伙伴一不小心,忘记了其中一个地方(大多数都是实例化组件,或者没写getTableSelect事件监听的方法,我们程序员,ctrl+c,ctrl+v,漏拷贝一点点方法,很正常吧),则会需排查原因,相对繁琐。

后面我想了一下,再通过百度,写了第二种方案。

第二种方案

为了减少出现拷贝少问题,我把第3步和第4步合并了(3.回车事件里触发公共组件的方法,4.写getTableSelect事件监听的方法),用Promise。

以下是相关的改动

公共组件改动情况

vue通过js代码实例化组件

 

vue通过js代码实例化组件

 业务组件改动情况

 

vue通过js代码实例化组件

 这样做了之后,好处就是,触发的事件和接收结果的方法在一起了,减少出错的概率,代码也更加方便理解了。第二种方案,也是我一直用的方案,

但第二种方案,依旧要写3个地方,即1.实例化公共组件,并写上ref,2.输入框写上回车事件,3.回车事件里触发公共组件的方法并接收值,

这种情况下,还是有小伙伴会出现拷贝少的问题(没有实例化公共组件),我也曾想过,怎么去除这个实例化的代码,用js代码实例化组件,但受限于个人水平不够,我也没想到什么好的方法解决这个问题,所以这个问题就一直搁置了。

直到今天(2023-9-16),我心血来潮,想看看有没有办法解决没有实例化公共组件问题,经过长时间的百度,和查看vue官方文档,终于找到了一种可以在js代码上实例化组件的方案,也就是现在的第三种方案。

第三种方案

公共组件没有任何改变

新增一个公共的js方法

import Vue from "vue";

/**
 * 获取表格选择
 * @param name 搜索值
 */
export function getTableSelect(name) {
  //获取公共里的实例
  const MyComponent = Vue.component("TableSelect");
  let myComponent = new MyComponent();
  //挂载实例
  let jbxxModal = myComponent.$mount();

  return new Promise((resolve, reject) => {
    jbxxModal
      .open(name)
      .then((row) => {
        resolve(row);
      })
      .catch((res) => {
        reject(res);
      })
      .finally(() => {
        //销毁实例
        myComponent.$destroy();
      });
  });
}

 

main.js,新增以下代码

vue通过js代码实例化组件

 业务组件改动情况

vue通过js代码实例化组件

 通过第三种方案,别的小伙伴只需要调用公共的js方法即可,不需要实例化了组件了,大大的减少了出错的概率了,

现在只需要1.输入框写上回车事件,2.回车事件里触发公共组件的方法并接收值。

通过这次学习,提升了个人的一丢丢前端知识,记录存档,方便以后还知道怎么解决这个问题,也方便给别的小伙伴一些参考,

若该文章帮助到了你,请帮忙点一下赞好吗,若有更好的方案,可以评论告诉我,让我也学习一下。文章来源地址https://www.toymoban.com/news/detail-709796.html

到了这里,关于vue通过js代码实例化组件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 项目实例:H3C端口镜像 (镜像单目的端口 镜像多目的端口)

    一、项目实例 某局业务系统三级等保项目:配置只列出端口镜像部分,其他部分及设备(略) 1.1 边界部署两台防火墙做HA高可用 1.2 核心使用两台H3C交换机做堆叠,上联线路分别连接防火墙(主)、防火墙(备) 1.3 下联线路连接业务中心、安全监察中心 1.4 IDS入侵检测设备

    2023年04月22日
    浏览(20)
  • Vue前端的一些表格组件的思考

    当我们需要在前端中展示一些表格内容时,我们往往使用 Vue 的 table 来实现 当前实现如下: Vue Easytable 是一个基于Vue2的表格组件,支持单元格合并、单元格编辑、多表头固定、多列固定、列拖动、排序、自定义列、分页、单元格编辑、多选、条件过滤、footer 汇总等功能。

    2024年02月11日
    浏览(29)
  • vue获取组件实例

    选项式获取组件实例 在选项式中可以直接通过 this 来获取组件实例,通过 this 来访问实例对象的各种方法 组合式中获取组件实例 在组合式用,代码都写在setup函数中,无法通过 this 获取组件实例,需要通过 getCurrentInstance() 方法, getCurrentInstance() 获取的实例对象和选项式获取

    2024年02月07日
    浏览(22)
  • vue3获取子组件实例

     方法一,直接获取   getCurrentInstance

    2024年02月16日
    浏览(80)
  • 小白最近比较闲,于是整理了一些日常使用的VUE组件

        VUE中,给 Dom 元素动态添加样式。     比如判断通过页面传递过来的值和env文件中配置的值是否一致,来动态添加元素的类,同时类的样式在 Style 中已经写好。  此时动态类名需要在 Dom 元素加载完成前添加上,否则样式可能添加不上。  这种情况下可以在   computed

    2024年02月10日
    浏览(25)
  • 通过实例了解vue3.3更新的特征

    开场白 准备新新特征的环境 使用vite来学习vue3.3的新特征 插件 script setup + TypeScript 开发体验改善 解析导入的类型,并支持有限的复杂类型 需要注意的点 类型的扩展 需要注意的点 通用组件-组件可以接收泛型参数 多个泛型 defineEmits的优化--现在 defineEmits以前的写法 尾声

    2024年02月07日
    浏览(25)
  • Vue3 - Element Plus 表格组件 “手动“ 取消/选中勾选列,并同步更新表格复选框 UI 状态(el-table 表格组件中,通过代码手动控制某个列的选中与取消勾选,并且复选框跟着变)

    网上基本上都是全部取消勾选的教程,没有仅对单独列操作的教程。 本文 实现了在 vue3 + element plus 组件库中,对 “某一个” 或 “几个单独” 列进行勾选/取消(手动操作表格复选框),并且让表格复选框自动同步选中状态, 完美解决删除表格列勾选的数据后,选中和取消

    2024年02月03日
    浏览(58)
  • Vue获取子组件实例对象 ref 属性

    在 Vue 中推荐使用 ref 属性获取 DOM 元素,这种方式可以提高性能。 如果将 ref 属性使用在组件上,那么返回的就是这个组件的实例对象。 使用方式:`p ref=\\\"xxx\\\"` 或 `Banner ref=\\\"xxx\\\"` 。 获取方式:this.$refs.xxx 1.原生 JS 获取 DOM 元素 【不推荐】: 2. 通过 ref 属性获取 DOM 元素 【推荐

    2024年02月04日
    浏览(33)
  • Vue组件滚动加载、懒加载功能的实现,无限滚动加载组件实例演示

    效果图如下: 可以看到随着不断的滚动,页面组件的数量不断的加载。 其实加载的是后端返回的数据,因为涉及隐私,没有给显示出来。 利用懒加载,可以防止大量渲染造成卡顿降低用户体验。 页面的动态加载这块可以看上一篇文章: Vue 动态添加和删除组件的实现,子组

    2024年02月01日
    浏览(43)
  • 公司前端实习项目技术,可以借鉴一些组件设计思路及基本代码逻辑,应届生来!

    1.跳转 2.请求 1.mounted() 1.从登陆界面开始,通过Common.httpRequest()发送请求,经过Common.forward()跳转传参,在mounted或者created生命周期中通过common.getActivePageStack()获取到跳转所传参数,这样就可以根据id或者其他唯一数据发送请求查询所需数据 1.DialogInfo 1.用法 先引入组件 在

    2024年02月21日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包