vue中extend,vue.extend的用法
本文主要介绍如何巧妙地使用Vue.extend继承组件实现el-table的双击编辑,而不是使用v-if和v-else的相关信息。通过示例代码详细介绍,有需要的朋友可以参考一下。
目录
问题描述效果图code ideas code ideas中的三个问题问题1:如何创建一个el-input标签?问题23:El-input标签和span标签的来回替换恢复了完整的代码目录结构。用于继承的el-input组件和用于继承的span组件被统一继承,并且data.js文件被公开。继承的three.vue组件用于总结。
问题描述
有一个简单的表格,产品需要双击才能编辑。
看了网上的帖子,大部分都有dom的两个部分,一个是输入框,用来填写编辑状态;另一个是普通标签,用来呈现单元格的文本内容,不需要编辑。添加一个带有v-if和v-else的标志来控制编辑状态或显示状态。大致的代码如下:
El-表格-列
align=居中
Label= name
模板槽-范围=“范围”
!- isClick是标识状态。当状态为编辑中时,将显示输入框。当状态为“渲染中”时,将显示文本内容-
El-input v-if= scope . row . is click v-model= scope . row . name @ blur= blur fn(scope . row)/El-input
span @ click= click cell(scope . row) v-else { { scope . row . name } }/span
/模板
/El-表格-列
这种方法有其适用的场景,但是每个el-table-column都必须添加el-input和span,以及v-if和v-else。让我们尝试动态添加el-input,也就是点击那个单元格,将el-input添加到那个单元格使其可编辑,然后在适当的时候移除它。这样,当列很多的时候,就不需要添加很多v-ifs和v-else了。先来看效果图。
效果图
代码思路
第一步:双击el-table绑定的event @cell-dblclick=dblclick ,然后双击事件的回调函数,知道是哪一行,哪一列,单元格dom,点击事件。DBLClick(行、列、单元格、事件){.},这是饿了么官方提供的。没什么好说的。第二步:重点来了。步骤2.1:单元格双击事件后,我们先创建一个el-input标签,然后用被点击单元格的值作为这个el-input接收的参数props,这样el-input就会显示这个单元格的值。问题一:如何创建一个el-input标签?,客官稍等。下面将回答步骤2.2:用原始单元跨度标签替换创建的el输入标签。这样,你可以看到单元格变成了一个输入框。问题二:如何把新创建的el-input标签,替换原有的span标签,客官,稍等,下面会回答步骤2.3。当用户编辑完毕,点击别的地方,也就是输入框失去焦点的时候,去掉el-input输入框的标签,恢复默认的span标签(当然,失去焦点的时候会发出数据修改的请求)。问题三:如何移除el-input标签,并恢复原有的span标签,客官,稍等,下面会给出答案。在这种情况下,每次双击进行输入。
代码思路中的三个问题解答
问题一:如何创建一个el-input标签?
我们知道,如果要创建一个原生输入标签并指定一个值,它是相对简单和直接的:
let=document . createelement( input )//创建输入标记
Input.value=猴王//为输入标记赋值
document . body . Append child(input)//将输入标记附加到文档体
但是el-input标签不能用上面的方法创建,因为document.createElement()方法可以创建el-input标签,但是dom不知道这个el-input标签,所以页面没有改变。毕竟饿了么el-input也让输入标签变成了二次元包。
所以,这里我们可以使用Vue.extend()方法去继承一个组件并暴露出去,而继承的这个组件中又有一个input标签,所以那个需要使用,那里就可以引入并new出来一个el-input了。关于Vue.extend()的定义,这里就不赘述了。详见官方文件。笔者之前也写过一篇Vue.extend文章,门户是https://www.jb51.net/article/251484.htm.
首先搞一个.vue文件,用于继承
//input.vue文件
模板
div class=cell
el输入
ref=elInputRef
size=mini
垂直模型. trim=单元格值
/el-input
/div
/模板
道具:{
单元格值:{
类型:字符串数字,
默认值: ,
},
}
然后定义一个data.js文件,继承input.vue文件,并暴露
//data.js
从“Vue”导入Vue;
从导入定义的输入。/input . vue ;
//vue继承了这个输入组件,相当于一个构造函数。
const inputC=vue . extend(defined input);
//暴露,需要引入的地方
导出默认值{
输入,
}
页面中引入并使用
//page.vue
从“”导入extendComponents。/three c/data ;//1.介绍
新扩展组件。Inputc ({//2。实例化
属性数据:{
//使用propsData对象传递参数,props中可以接收子组件。
CellValue: cellValue,//传递单元格的值
},
}).$ mount(cell . children[0]);//3.增加
PropsData对象用来给继承的组件传递参数,也可以传递一个函数,这样继承的组件就可以通过这个函数通知外部使用的组件。有关详细信息,请参见下面的完整代码。
问题二三:el-input标签和span标签的来回替换恢复
使用$mount方法来回替换它。$mount可以在父dom元素后面追加一个子dom元素,相当于appendChild。
那么这里就需要有一个替换的机会,就是当实例化组件中的el-input失去焦点时,通知外部使用的组件,这样就可以外部使用了。是的,将函数传递给propsData中的继承组件,例如:
//外部组件交付
新的extendComponents.inputC({
属性数据:{
CellValue: cellValue,//传递单元格的值
Saverowdata:这个。saverowdata,//为通知传递回调函数,可以在继承组件中触发。
},
}).$ mount(cell . children[0]);
saveRowData(params){
Console.log(已收到继承组件消息的通知,参数为:,params)
}
//内部组件失去焦点时通知
el输入
ref=elInputRef
size=mini
垂直模型. trim=单元格值
@blur=blurFn
/el-input
道具:{
单元格值:{
类型:字符串数字,
默认值: ,
},
Savedata: function,//external,传入一个函数,当这个el-input失去焦点时,通过这个函数通知外部。
}
blurFn() {
//失去焦点,然后抛出并通知外部
this.saveRowData({
单元格值:this.cellValue,
//其他参数
});
},
所以当内层失去焦点的时候,可以通知外层进行替换,也就是把单元格dom再次挂载为$mount,用span替换el-input。为了进一步理解,我们还可以在这里使用span的继承方法,它是由new实例化的。有关详细信息,请参见下面的完整代码。
完整代码
目录结构
三c
- data.js
- input.vue
- span.vue
三. vue
用于继承的el-input组件
输入. vue
模板
div class=cell
el输入
ref=elInputRef
size=mini
垂直模型. trim=单元格值
@blur=blurFn
/el-input
/div
/模板
脚本
导出默认值{
道具:{
单元格值:{
类型:字符串数字,
默认值: ,
},
Savedata: function,//external,传入一个函数,当这个el-input失去焦点时,通过这个函数通知外部。
CellDom: Node,//单元格Dom
Row: Object,//单元格所在行的数据
属性:字符串,//单元格的键
},
已安装(){
//用户双击后,让其处于获得焦点的状态。
这个。$ refs . elinputref . focus();
},
方法:{
blurFn() {
//失去焦点,然后抛出并通知外部
this.saveRowData({
单元格值:this.cellValue,
cellDom: this.cellDom,
row: this.row,
属性:this.property,
});
},
},
};
/脚本
风格。单元格{
宽度:100%;
身高:100%;
显示器:flex
justify-content:居中;
对齐-项目:居中;
框大小:边框-框;
填充:0 8px
}
/风格
用于继承的span组件
span.vue
模板
span class=单元格“{ cellValue }}/span
/模板
脚本
导出默认值{
道具:{
单元格值:{
类型:字符串数字,
默认值: ,
},
},
};
/脚本
统一继承并暴露data.js文件
从“Vue”导入Vue;
从导入定义的输入。/input . vue ;
从导入定义的Span。/span . vue ;
const inputC=vue . extend(defined input);
const spanC=vue . extend(defined span);
导出默认值{
输入,
spanC,
}
使用继承的three.vue组件
模板
div id=应用程序
el表
@cell-dblclick=dblclick
:cell-class-name=cellClassName
身高=480
:data=tableData
边界
El-table-column align= center type= index label= serial number width= 50
/El-表格-列
El-table-column align= center prop= name label= name width= 100
/El-表格-列
El-table-column align= center prop= age label= age width= 100
/El-表格-列
El-table-column align= center prop= home label= homeland
/El-表格-列
/el-table
/div
/模板
脚本
//引入继承的组件对象,并在其上使用inputC构造函数或spanC构造函数生成组件dom。
从“”导入extendComponents。/three c/data ;
导出默认值{
data() {
返回{
表格数据:[
{
名字:“美猴王”,
年龄:500,
家:‘花果山水帘洞’,
},
{
姓名:猪八戒,
年龄:88,
家:‘高老庄’,
},
{
姓名:“沙和尚”,
年龄:1000,
家:‘通天河’,
},
],
/**
*保存一个旧值,以检查它是否已被更改或修改。
* */
oldCellValue: null,
};
},
方法:{
cellClassName({ row,column,rowIndex,columnIndex }) {
row.index=rowIndex//自定义指定一个索引,可以在下面使用。
},
dblclick(行、列、单元格、事件){
//1.不能编辑任何列单元格,但可以编辑其他列单元格。
If (column.label==序列号){
这个。$message({
类型:警告,
消息:“无法编辑序列号列”,
});
返回;
}
//2.保存旧单元格值的副本
this . oldcellvalue=row[column . property];
//3.然后将单元格的值作为参数传递给实例化的输入组件。
设cell value=row[column . property];
//4.实例化组件后,用参数将其挂载到相应的位置。
新的extendComponents.inputC({
属性数据:{
//使用propsData对象传递参数,props中可以接收子组件。
CellValue: cellValue,//传递单元格的值
Saverowdata: this.saverowdata,//回调函数用于保存行数据,可以在组件中触发。
CellDom: cell,//传递这个Dom元素
Row: row,//传递双击行的数据。
Property: column.property,//传递双击哪个字段。
},
}).$ mount(cell . children[0]);//5.$mount方法,用于在dom上挂载一个dom
},
/**
*当失去焦点时,有以下操作
* 1.检查新值是否等于原始值。如果是,说明用户没有修改过,所以不会发送请求。如果没有,发送请求并更新tableData数据。
* 2.然后用$mount方法在页面上挂载一个新的span标签dom,也就是原样恢复,span标签就实例化了。
* */
saveRowData(params) {
Console.log(由继承的子组件传递的数据,params);
//1.查看用户是否修改了它
if(params . cell value==this . old cell value){
Console.log(不修改数据,不需要请求);
}否则{
params . row[params . property]=params . cell value;
//这里模拟发送请求,得到最新的表体数据后,更新tableData。
setTimeout(()={
//修改该数组项的why值。
这个。$set(this.tableData,params.row.index,params . row);
}, 300);
}
//2.有两种方法可以将dom节点恢复原样。
/**
*方法一:使用官方推荐的$mount挂载在一个节点上,top也是这样。
* */
新的extendComponents.spanC({
属性数据:{
单元格值:params.cellValue,
},
}).$ mount(params . celldom . children[0]);
/**
*方法二:用native js清空原来的节点内容,然后添加子元素。
* */
//let span=document . createelement( span );//创建一个范围标签
//span . innerhtml=params . cell value;//指定范围标签内容的值
//span . class list . add( cell );//将类作为单元格添加到span标记中
//params . celldom . innerhtml=“”;//清空刚刚操作的输入标签的内容。
//params . celldom . appendchild(span);//追加span标签并按原样恢复。
},
},
};
/脚本
style lang=less 范围
#app {
宽度:100%;
身高:100vh
框大小:边框-框;
填充:50px
}
/风格
总结
使用Vue.extend()方法,可以继承一些组件,甚至是一些复杂的组件,在实际的业务场景中会被熟练运用。具体业务场景具体分析。
另外,上面的代码是对el-input的继承。其实我们也可以做el-select的传承。思路和上面类似,这样你可以双击表格中的一个单元格,选择并更改对应的下拉框,来更改el-table的单元格值。例如,如果有一个性别列,它是下拉框的形式。道友可以按照这个思路传播。
关于如何熟练使用Vue.extend继承组件实现el-table的双击编辑(不使用v-if和v-else)的这篇文章到此为止。更多关于如何用Vue.extend实现el-table的双击编辑,请搜索我们之前的文章或者继续浏览下面的相关文章。希望你以后能支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。