最近在寫項(xiàng)目的一些公共組件(一些選擇器),很多個(gè)地方都需要用,所以在main.js全局聲明了,但發(fā)現(xiàn)子頁(yè)面調(diào)用還是有挺多的地方需寫。
例如,要在template實(shí)例化組件,并用ref綁定,然后在js里的methods里寫方法。
main.js 聲明全局組件
第一種方案
一開始想到的是用ref綁定組件,業(yè)務(wù)組件實(shí)例化公共組件,并賦予ref,然后通過(guò)這個(gè)ref綁定,直接調(diào)用公共組件的方法(為了一定能觸發(fā)方法),例如? this.$refs.xxx.open()
如果用戶在公共組件中,選擇好數(shù)據(jù)操作完成后,公共組件觸發(fā)emit方法,通過(guò)回調(diào)方法的方式通知業(yè)務(wù)組件,例如?this.$emit("getTableSelect",this.selection)
以下是相關(guān)代碼:
公共組件
<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="請(qǐng)輸入名稱" @keyup.enter.native="handleQuery" /> </el-form-item> <el-form-item label="狀態(tài)" prop="status"> <el-select v-model="queryParams.status" clearable placeholder="請(qǐng)選擇狀態(tài)" > <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="狀態(tài)" 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">關(guān)閉</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: "數(shù)據(jù)正在處理中...", dialogVisible: false, // 查詢參數(shù) queryParams: { pageNum: 1, pageSize: 10, name: null, status: null, }, // 總條數(shù) total: 0, //表格數(shù)據(jù) 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("請(qǐng)選擇"); 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>
業(yè)務(wù)組件(簡(jiǎn)化)
<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, // 查詢參數(shù) queryParams: { name: null, }, }; }, methods: { //去打開窗口選擇 handleTableSelect() { this.$refs.tableSelect.open(this.queryParams.name); }, //獲取選擇的行 getTableSelect(row) { this.queryParams.name = row.name; }, }, }; </script>
效果圖
?
?
?
第一種方案,雖然可以使用,但業(yè)務(wù)組件若要使用,則需要正確在4個(gè)地方寫上對(duì)應(yīng)的代碼
即,1.實(shí)例化公共組件,并寫上ref和getTableSelect的事件監(jiān)聽,2.輸入框?qū)懮匣剀囀录?.回車事件里觸發(fā)公共組件的方法,4.寫getTableSelect事件監(jiān)聽的方法。
?
若別的小伙伴一不小心,忘記了其中一個(gè)地方(大多數(shù)都是實(shí)例化組件,或者沒寫getTableSelect事件監(jiān)聽的方法,我們程序員,ctrl+c,ctrl+v,漏拷貝一點(diǎn)點(diǎn)方法,很正常吧),則會(huì)需排查原因,相對(duì)繁瑣。
后面我想了一下,再通過(guò)百度,寫了第二種方案。
第二種方案
為了減少出現(xiàn)拷貝少問(wèn)題,我把第3步和第4步合并了(3.回車事件里觸發(fā)公共組件的方法,4.寫getTableSelect事件監(jiān)聽的方法),用Promise。
以下是相關(guān)的改動(dòng)
公共組件改動(dòng)情況
?
?業(yè)務(wù)組件改動(dòng)情況
?
?這樣做了之后,好處就是,觸發(fā)的事件和接收結(jié)果的方法在一起了,減少出錯(cuò)的概率,代碼也更加方便理解了。第二種方案,也是我一直用的方案,
但第二種方案,依舊要寫3個(gè)地方,即1.實(shí)例化公共組件,并寫上ref,2.輸入框?qū)懮匣剀囀录?.回車事件里觸發(fā)公共組件的方法并接收值,
這種情況下,還是有小伙伴會(huì)出現(xiàn)拷貝少的問(wèn)題(沒有實(shí)例化公共組件),我也曾想過(guò),怎么去除這個(gè)實(shí)例化的代碼,用js代碼實(shí)例化組件,但受限于個(gè)人水平不夠,我也沒想到什么好的方法解決這個(gè)問(wèn)題,所以這個(gè)問(wèn)題就一直擱置了。
直到今天(2023-9-16),我心血來(lái)潮,想看看有沒有辦法解決沒有實(shí)例化公共組件問(wèn)題,經(jīng)過(guò)長(zhǎng)時(shí)間的百度,和查看vue官方文檔,終于找到了一種可以在js代碼上實(shí)例化組件的方案,也就是現(xiàn)在的第三種方案。
第三種方案
公共組件沒有任何改變
新增一個(gè)公共的js方法
import Vue from "vue";
/**
* 獲取表格選擇
* @param name 搜索值
*/
export function getTableSelect(name) {
//獲取公共里的實(shí)例
const MyComponent = Vue.component("TableSelect");
let myComponent = new MyComponent();
//掛載實(shí)例
let jbxxModal = myComponent.$mount();
return new Promise((resolve, reject) => {
jbxxModal
.open(name)
.then((row) => {
resolve(row);
})
.catch((res) => {
reject(res);
})
.finally(() => {
//銷毀實(shí)例
myComponent.$destroy();
});
});
}
?
main.js,新增以下代碼
?業(yè)務(wù)組件改動(dòng)情況
?通過(guò)第三種方案,別的小伙伴只需要調(diào)用公共的js方法即可,不需要實(shí)例化了組件了,大大的減少了出錯(cuò)的概率了,
現(xiàn)在只需要1.輸入框?qū)懮匣剀囀录?.回車事件里觸發(fā)公共組件的方法并接收值。
通過(guò)這次學(xué)習(xí),提升了個(gè)人的一丟丟前端知識(shí),記錄存檔,方便以后還知道怎么解決這個(gè)問(wèn)題,也方便給別的小伙伴一些參考,文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-709796.html
若該文章幫助到了你,請(qǐng)幫忙點(diǎn)一下贊好嗎,若有更好的方案,可以評(píng)論告訴我,讓我也學(xué)習(xí)一下。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-709796.html
到了這里,關(guān)于vue通過(guò)js代碼實(shí)例化組件的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!