vue+iview 实现可编辑表格的示例代码

先简单说明一下,这个Demo引入的vue,iview的方式是标签引入的,没有用到webpack之类的构建工具...

毕竟公司还在用angularjs+jq.

这也是我第一次写文章,大家看看思路就行了,要是有大佬指点指点就更好了

话不多说,先来个效果图

我们再看下极为简单的目录结构

IViewEditTable    ## vue+iview 实现的可编辑表格
└── index.html    ## 首页
└── js
 └── editTable.js   ## 首页JS
└── ivew      ## iview相关
└── vue
 ├── axios.min.js   ## axios (ajax)
 ├── util.js    ## 与业务无关的纯工具函数包
 └── vue.min.js   ## vue (2.x)

首页html:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <title>可编辑表格</title>
 <link href="iview/iview.css" rel="external nofollow" rel="stylesheet" />
</head>
<body style="background-color: #f0f3f4;">
 <div id="editTableCtrl">
 <i-table :loading="loading" border :data="dataList" :columns="columnsList" stripe size="small"></i-table>
 </div>
 <script src="vue/axios.min.js"></script>
 <script src="vue/vue.min.js"></script>
 <script src="iview/iview.min.js"></script>
 <script src="vue/util.js"></script>
 <script src="js/editTable.js"></script>
</body>
</html>

首页没什么说的,都是基本的架子. 这是需要渲染的数据及其说明:

{
 "Status": 1,
 "Total": 233,
 "Items": [{
 "ID": 1,
 "PID": 3,
 "PRJCODE": "2018-001",           //项目编号 不可编辑
 "PRJNAME": "淡化海水配套泵站",         //项目名称 文本输入框
 "PRJTYPE": "基础设施",           //项目类型 下拉选项
 "JSUNIT": "投资公司",           //建设单位 文本输入框
 "FLOW_TYPE_CODE":"A02",           //流程分类 下拉选项,与数据库以code形式交互
 "DATE_START": "2018-12-1",          //开工时间 日期选择
 "DATE_END": "2019-12-1",          //竣工时间 日期选择
 "CONTENT": "建设淡化海水配套泵站一座,占地面积约8500平方米", //建设内容 多行输入框
 "INVEST_ALL": "1000"           //总投资 数字输入框
 }]
}

还有editTable.js的基本架子,$http是我为了方便在utils最后一行加入的 (angularjs用多了,习惯用\$http)

Vue.prototype.utils = utils
window.$http = axios

editTable.js :

var vm = new Vue({
 el: '#editTableCtrl',
 data: function() {
 return {
  loading: true,
  //表格的数据源
  dataList: [],
  // 列
  columnsList: [],
  // 增加编辑状态, 保存状态, 用于操作数据 避免干扰原数据渲染
  cloneDataList: []
 }
 },
 methods: {
 getData: function() {
  var self = this;
  self.loading = true;
  $http.get('json/editTable.txt').then(function(res) {
  self.dataList = res.data.Items;
  self.loading = false;
  });
 },
 },
 created: function() {
 this.getData();
 }
});

我们再来按照iview的规则编写渲染的列:

//...

   /**
    * @name columnsList (浏览器 渲染的列)
    * @author catkin
    * @see https://www.iviewui.com/components/table
    * @param
    * {
    * titleHtml : 渲染带有html的表头 列: '资金<em class="blue" style="color:red">来源</em>'
    * editable : true,可编辑的列 必须有字段
    * option  : 渲染的下拉框列表,如果需要与数据库交互的值与显示的值不同,须使用[{value:'value',label:'label'}]的形式,下面有例子
    * date   : 渲染成data类型 ,可选参数:
    *       date | daterange: yyyy-MM-dd (默认)
    *       datetime | datetimerange: yyyy-MM-dd HH:mm:ss
    *       year: yyyy
    *       month: yyyy-MM
    * input   : 渲染input类型 ,可选参数为html5所有类型 (额外增加 textarea 属性), 默认text
    * handle  : 数组类型, 渲染操作方式,目前只支持 'edit', 'delete'
    * }
    * @version 0.0.1
    */

columnsList: [{
  width: 80,
  type: 'index',
  title: '序号',
  align: 'center'
}, {
  align: 'center',
  title: '项目编号',
  key: 'PRJCODE'
}, {
  align: 'center',
  title: '项目名称',
  titleHtml: '项目名称 <i class="ivu-icon ivu-icon-edit"></i>',
  key: 'PRJNAME',
  editable: true
}, {
  align: 'center',
  title: '项目分类',
  titleHtml: '项目分类 <i class="ivu-icon ivu-icon-edit"></i>',
  key: 'PRJTYPE',
  option: ['产业项目', '基础设施', '民生项目', '住宅项目'],
  editable: true
}, {
  align: 'center',
  title: '建设单位',
  titleHtml: '建设单位 <i class="ivu-icon ivu-icon-edit"></i>',
  key: 'JSUNIT',
  editable: true
}, {
  align: 'center',
  title: '流程分类',
  titleHtml: '流程分类 <i class="ivu-icon ivu-icon-edit"></i>',
  key: 'FLOW_TYPE_CODE',
  option: [{
   value: 'A01',
   label: '建筑-出让'
  }, {
   value: 'A02',
   label: '建筑-划拨'
  }, {
   value: 'B01',
   label: '市政-绿化'
  }, {
   value: 'B02',
   label: '市政-管线'
  }],
  editable: true
}, {
  align: 'center',
  title: '开工时间',
  titleHtml: '开工时间 <i class="ivu-icon ivu-icon-edit"></i>',
  key: 'DATE_START',
  //这里在后面处理的时候会分割成['month','yyyy-MM']的数组,分别代表iview的DatePicker组件选择日期的格式与数据库传过来时页面显示的格式
  date: 'month_yyyy-MM',
  editable: true
}, {
  align: 'center',
  title: '竣工时间',
  titleHtml: '竣工时间 <i class="ivu-icon ivu-icon-edit"></i>',
  key: 'DATE_END',
  date: 'month_yyyy-MM',
  editable: true
}, {
  align: 'center',
  title: '建设内容',
  titleHtml: '建设内容 <i class="ivu-icon ivu-icon-edit"></i>',
  key: 'CONTENT',
  input: 'textarea',
  editable: true
}, {
  align: 'center',
  title: '总投资(万元)',
  titleHtml: '总投资<br />(万元) <i class="ivu-icon ivu-icon-edit"></i>',
  key: 'INVEST_ALL',
  input: 'number',
  editable: true
}, {
  title: '操作',
  align: 'center',
  width: 150,
  key: 'handle',
  handle: ['edit', 'delete']
}]

//...

此时页面应该已经可以渲染出表格了

既然要编辑数据,并且我的需求是整行整行的编辑,而编辑的同时就会同步更新数据,那么问题来了
vue中, 数据更新,视图会随之更新. 想象一下,我在输入框中属于一个值,触发了数据更新,接着又触发了视图更新,那么我每次输入时,这个input都会失焦,毫无用户体验. 所以我们把可编辑的动态内容用cloneDataList渲染,静态显示的用dataList渲染

//...
self.dataList = res.data.Items;
// 简单的深拷贝,虽然map会返回新数组,但是数组元素也是引用类型,不能直接改,所以先深拷贝一份
self.cloneDataList = JSON.parse(JSON.stringify(self.dataList)).map(function(item) {
 // 给每行添加一个编辑状态 与 保存状态, 默认都是false
 item.editting = false;
 item.saving = false;
 return item;
});
//...

接下来,我们要根据columnsList做一次循环判断,根据相应的key写出不同的render函数

//全局添加
//根据value值找出数组中的对象元素
function findObjectInOption(value) {
 return function(item) {
 return item.value === value;
 }
}
//动态添加编辑按钮
var editButton = function(vm, h, currentRow, index) {
 return h('Button', {
 props: {
  size: 'small',
  type: currentRow.editting ? 'success' : 'primary',
  loading: currentRow.saving
 },
 style: {
  margin: '0 5px'
 },
 on: {
  click: function() {
  // 点击按钮时改变当前行的编辑状态, 当数据被更新时,render函数会再次执行,详情参考https://cn.vuejs.org/v2/api/#render
  // handleBackdata是用来删除当前行的editting属性与saving属性
  var tempData = vm.handleBackdata(currentRow)
  if (!currentRow.editting) {
   currentRow.editting = true;
  } else {
   // 这里也是简单的点击编辑后的数据与原始数据做对比,一致则不做操作,其实更好的应该遍历所有属性并判断
   if (JSON.stringify(tempData) == JSON.stringify(vm.dataList[index])) {
   console.log('未更改');
   return currentRow.editting = false;
   }
   vm.saveData(currentRow, index)
   currentRow.saving = true;
  }
  }
 }
 }, currentRow.editting ? '保存' : '编辑');
};
//动态添加 删除 按钮
var deleteButton = function(vm, h, currentRow, index) {
 return h('Poptip', {
  props: {
  confirm: true,
  title: currentRow.WRAPDATASTATUS != '删除' ? '您确定要删除这条数据吗?' : '您确定要对条数据撤销删除吗?',
  transfer: true,
  placement: 'left'
  },
  on: {
  'on-ok': function() {
   vm.deleteData(currentRow, index)
  }
  }
 },
 [
  h('Button', {
  style: {
   color: '#ed3f14',
   fontSize: '18px',
   padding: '2px 7px 0',
   border: 'none',
   outline: 'none',
   focus: {
   '-webkit-box-shadow': 'none',
   'box-shadow': 'none'
   }
  },
  domProps: {
   title: '删除'
  },
  props: {
   size: 'small',
   type: 'ghost',
   icon: 'android-delete',
   placement: 'left'
  }
  })
 ]);
};

//methods中添加
init: function() {
 console.log('init');
 var self = this;
 self.columnsList.forEach(function(item) {
 // 使用$set 可以触发视图更新
 // 如果含有titleHtml属性 将其值填入表头
 if (item.titleHtml) {
  self.$set(item, 'renderHeader', function(h, params) {
  return h('span', {
   domProps: {
   innerHTML: params.column.titleHtml
   }
  });
  });
 }
 // 如果含有操作属性 添加相应按钮
 if (item.handle) {
  item.render = function(h, param) {
  var currentRow = self.cloneDataList[param.index];
  var children = [];
  item.handle.forEach(function(item) {
   if (item === 'edit') {
   children.push(editButton(self, h, currentRow, param.index));
   } else if (item === 'delete') {
   children.push(deleteButton(self, h, currentRow, param.index));
   }
  });
  return h('div', children);
  };
 }
 //如果含有editable属性并且为true
 if (item.editable) {
  item.render = function(h, params) {
  var currentRow = self.cloneDataList[params.index];
  // 非编辑状态
  if (!currentRow.editting) {
   // 日期类型单独 渲染(利用工具暴力的formatDate格式化日期)
   if (item.date) {
   return h('span', self.utils.formatDate(currentRow[item.key], item.date.split('_')[1]))
   }
   // 下拉类型中value与label不一致时单独渲染
   if (item.option && self.utils.isArray(item.option)) {
   // 我这里为了简单的判断了第一个元素为object的情况,其实最好用every来判断所有元素
   if (typeof item.option[0] === 'object') {
    return h('span', item.option.find(findObjectInOption(currentRow[item.key])).label);
   }
   }
   return h('span', currentRow[item.key]);
  } else {
  // 编辑状态
   //如果含有option属性
   if (item.option && self.utils.isArray(item.option)) {
   return h('Select', {
    props: {
    // ***重点***: 这里要写currentRow[params.column.key],绑定的是cloneDataList里的数据
    value: currentRow[params.column.key]
    },
    on: {
    'on-change': function(value) {
     self.$set(currentRow, params.column.key, value)
    }
    }
   }, item.option.map(function(item) {
    return h('Option', {
    props: {
     value: item.value || item,
     label: item.label || item
    }
    }, item.label || item);
   }));
   } else if (item.date) {
   //如果含有date属性
   return h('DatePicker', {
    props: {
    type: item.date.split('_')[0] || 'date',
    clearable: false,
    value: currentRow[params.column.key]
    },
    on: {
    'on-change': function(value) {
     self.$set(currentRow, params.column.key, value)
    }
    }
   });
   } else {
   // 默认input
   return h('Input', {
    props: {
    // type类型也是自定的属性
    type: item.input || 'text',
    // rows只有在input 为textarea时才会起作用
    rows: 3,
    value: currentRow[params.column.key]
    },
    on: {
    'on-change'(event) {
     self.$set(currentRow, params.column.key, event.target.value)
    }
    }
   });
   }
  }
  };
 }
 });
},
// 还原数据,用来与原始数据作对比的
handleBackdata: function(object) {
 var clonedData = JSON.parse(JSON.stringify(object));
 delete clonedData.editting;
 delete clonedData.saving;
 return clonedData;
}

到这里完成已经差不多了,补上保存数据与删除数据的函数

// 保存数据
saveData: function(currentRow, index) {
 var self = this;
 // 修改当前的原始数据, 就不需要再从服务端获取了
 this.$set(this.dataList, index, this.handleBackdata(currentRow))
 // 需要保存的数据
 // 模拟ajax
 setTimeout(function() {
 充值编辑与保存状态
 currentRow.saving = false;
 currentRow.editting = false;
 self.$Message.success('保存完成');
 console.log(self.dataList);
 }, 1000)
},
// 删除数据
deleteData: function(currentRow, index) {
 var self = this;
 console.log(currentRow.ID);
 setTimeout(function() {
 self.$delete(self.dataList, index)
 self.$delete(self.cloneDataList, index)
 vm.$Message.success('删除成功');
 }, 1000)
},

完整的editTable.js代码

// 根据数据中下拉的值找到对应的对象
function findObjectInOption(name) {
 return function(item) {
 return item.value === name;
 }
}
var editButton = function(vm, h, currentRow, index) {
 return h('Button', {
 props: {
  size: 'small',
  type: currentRow.editting ? 'success' : 'primary',
  loading: currentRow.saving
 },
 style: {
  margin: '0 5px'
 },
 on: {
  click: function() {
   // 点击按钮时改变当前行的编辑状态,当数据被更新时,render函数会再次执行,详情参考https://cn.vuejs.org/v2/api/#render
   // handleBackdata是用来删除当前行的editting属性与saving属性
   var tempData = vm.handleBackdata(currentRow)
   if (!currentRow.editting) {
   currentRow.editting = true;
   } else {
   // 这里也是简单的点击编辑后的数据与原始数据做对比,一致则不做操作,其实更好的应该遍历所有属性并判断
   if (JSON.stringify(tempData) == JSON.stringify(vm.dataList[index])) {
    console.log('未更改');
    return currentRow.editting = false;
   }
   vm.saveData(currentRow, index)
   currentRow.saving = true;
   }
  }
 }
 }, currentRow.editting ? '保存' : '编辑');
};
//动态添加 删除 按钮
var deleteButton = function(vm, h, currentRow, index) {
 return h('Poptip', {
  props: {
  confirm: true,
  title: currentRow.WRAPDATASTATUS != '删除' ? '您确定要删除这条数据吗?' : '您确定要对条数据撤销删除吗?',
  transfer: true,
  placement: 'left'
  },
  on: {
  'on-ok': function() {
   vm.deleteData(currentRow, index)
  }
  }
 },
 [
  h('Button', {
  style: {
   color: '#ed3f14',
   fontSize: '18px',
   padding: '2px 7px 0',
   border: 'none',
   outline: 'none',
   focus: {
   '-webkit-box-shadow': 'none',
   'box-shadow': 'none'
   }
  },
  domProps: {
   title: '删除'
  },
  props: {
   size: 'small',
   type: 'ghost',
   icon: 'android-delete',
   placement: 'left'
  }
  })
 ]);
};
var vm = new Vue({
 el: '#editTableCtrl',
 data: function() {
 return {
  loading: true,
  //表格的数据源
  dataList: [],
  /**
  * @name columnsList (浏览器 渲染的列)
  * @author ch
  * @see https://www.iviewui.com/components/table
  * @param
  * {
  * titleHtml : 渲染带有html的表头 列: '资金<em class="blue" style="color:red">来源</em>'
  * editable : true,可编辑的列 必须有字段
  * option : 渲染的下拉框列表
  * date  : 渲染成data类型 ,可选参数:
  *    date | daterange: yyyy-MM-dd (默认)
  *    datetime | datetimerange: yyyy-MM-dd HH:mm:ss
  *    year: yyyy
  *    month: yyyy-MM
  * input  : 渲染input类型 ,可选参数为html5所有类型 (额外增加 textarea 属性), 默认text
  * handle : 数组类型, 渲染操作方式,目前只支持 'edit', 'delete'
  * }
  * @version 0.0.1
  */
  columnsList: [{
  width: 80,
  type: 'index',
  title: '序号',
  align: 'center'
  }, {
  align: 'center',
  title: '项目编号',
  key: 'PRJCODE'
  }, {
  align: 'center',
  title: '项目名称',
  titleHtml: '项目名称 <i class="ivu-icon ivu-icon-edit"></i>',
  key: 'PRJNAME',
  editable: true
  }, {
  align: 'center',
  title: '项目分类',
  titleHtml: '项目分类 <i class="ivu-icon ivu-icon-edit"></i>',
  key: 'PRJTYPE',
  option: ['产业项目', '基础设施', '民生项目', '住宅项目'],
  editable: true
  }, {
  align: 'center',
  title: '建设单位',
  titleHtml: '建设单位 <i class="ivu-icon ivu-icon-edit"></i>',
  key: 'JSUNIT',
  editable: true
  }, {
  align: 'center',
  title: '流程分类',
  titleHtml: '流程分类 <i class="ivu-icon ivu-icon-edit"></i>',
  key: 'FLOW_TYPE_CODE',
  option: [{
   value: 'A01',
   label: '建筑-出让'
  }, {
   value: 'A02',
   label: '建筑-划拨'
  }, {
   value: 'B01',
   label: '市政-绿化'
  }, {
   value: 'B02',
   label: '市政-管线'
  }],
  editable: true
  }, {
  align: 'center',
  title: '开工时间',
  titleHtml: '开工时间 <i class="ivu-icon ivu-icon-edit"></i>',
  key: 'DATE_START',
  //这里在后面处理的时候会分割成['month','yyyy-MM']的数组,分别代表iview的DatePicker组件选择日期的格式与数据库传过来时页面显示的格式
  date: 'month_yyyy-MM',
  editable: true
  }, {
  align: 'center',
  title: '竣工时间',
  titleHtml: '竣工时间 <i class="ivu-icon ivu-icon-edit"></i>',
  key: 'DATE_END',
  date: 'month_yyyy-MM',
  editable: true
  }, {
  align: 'center',
  title: '建设内容',
  titleHtml: '建设内容 <i class="ivu-icon ivu-icon-edit"></i>',
  key: 'CONTENT',
  input: 'textarea',
  editable: true
  }, {
  align: 'center',
  title: '总投资(万元)',
  titleHtml: '总投资<br />(万元) <i class="ivu-icon ivu-icon-edit"></i>',
  key: 'INVEST_ALL',
  input: 'number',
  editable: true
  }, {
  title: '操作',
  align: 'center',
  width: 150,
  key: 'handle',
  handle: ['edit', 'delete']
  }],
  // 增加编辑状态, 保存状态, 用于操作数据 避免干扰原数据渲染
  cloneDataList: []
 }
 },
 methods: {
 getData: function() {
  var self = this;
  self.loading = true;
  $http.get('json/editTable.txt').then(function(res) {
  // 给每行添加一个编辑状态 与 保存状态
  self.dataList = res.data.Items;
  self.cloneDataList = JSON.parse(JSON.stringify(self.dataList)).map(function(item) {
   item.editting = false;
   item.saving = false;
   return item;
  });
  self.loading = false;
  });
 },
 //初始化数据
 //methods中添加
 init: function() {
  console.log('init');
  var self = this;
  self.columnsList.forEach(function(item) {
  // 使用$set 可以触发视图更新
  // 如果含有titleHtml属性 将其值填入表头
  if (item.titleHtml) {
   self.$set(item, 'renderHeader', function(h, params) {
   return h('span', {
    domProps: {
    innerHTML: params.column.titleHtml
    }
   });
   });
  }
  // 如果含有操作属性 添加相应按钮
  if (item.handle) {
   item.render = function(h, param) {
   var currentRow = self.cloneDataList[param.index];
   var children = [];
   item.handle.forEach(function(item) {
    if (item === 'edit') {
    children.push(editButton(self, h, currentRow, param.index));
    } else if (item === 'delete') {
    children.push(deleteButton(self, h, currentRow, param.index));
    }
   });
   return h('div', children);
   };
  }
  //如果含有editable属性并且为true
  if (item.editable) {
   item.render = function(h, params) {
   var currentRow = self.cloneDataList[params.index];
   // 非编辑状态
   if (!currentRow.editting) {
    // 日期类型单独 渲染(利用工具暴力的formatDate格式化日期)
    if (item.date) {
    return h('span', self.utils.formatDate(currentRow[item.key], item.date.split('_')[1]))
    }
    // 下拉类型中value与label不一致时单独渲染
    if (item.option && self.utils.isArray(item.option)) {
    // 我这里为了简单的判断了第一个元素为object的情况,其实最好用every来判断所有元素
    if (typeof item.option[0] === 'object') {
     return h('span', item.option.find(findObjectInOption(currentRow[item.key])).label);
    }
    }
    return h('span', currentRow[item.key]);
   } else {
    // 编辑状态
    //如果含有option属性
    if (item.option && self.utils.isArray(item.option)) {
    return h('Select', {
     props: {
     // ***重点***: 这里要写currentRow[params.column.key],绑定的是cloneDataList里的数据
     value: currentRow[params.column.key]
     },
     on: {
     'on-change': function(value) {
      self.$set(currentRow, params.column.key, value)
     }
     }
    }, item.option.map(function(item) {
     return h('Option', {
     props: {
      value: item.value || item,
      label: item.label || item
     }
     }, item.label || item);
    }));
    } else if (item.date) {
    //如果含有date属性
    return h('DatePicker', {
     props: {
     type: item.date.split('_')[0] || 'date',
     clearable: false,
     value: currentRow[params.column.key]
     },
     on: {
     'on-change': function(value) {
      self.$set(currentRow, params.column.key, value)
     }
     }
    });
    } else {
    // 默认input
    return h('Input', {
     props: {
     // type类型也是自定的属性
     type: item.input || 'text',
     // rows只有在input 为textarea时才会起作用
     rows: 3,
     value: currentRow[params.column.key]
     },
     on: {
     'on-change'(event) {
      self.$set(currentRow, params.column.key, event.target.value)
     }
     }
    });
    }
   }
   };
  }
  });
 },
 saveData: function(currentRow, index) {
  var self = this;
  // 修改当前的原始数据, 就不需要再从服务端获取了
  this.$set(this.dataList, index, this.handleBackdata(currentRow))
  // 需要保存的数据
  // 模拟ajax
  setTimeout(function() {
  // 重置编辑与保存状态
  currentRow.saving = false;
  currentRow.editting = false;
  self.$Message.success('保存完成');
  console.log(self.dataList);
  }, 1000)
 },
 // 删除数据
 deleteData: function(currentRow, index) {
  var self = this;
  console.log(currentRow.ID);
  setTimeout(function() {
  self.$delete(self.dataList, index)
  self.$delete(self.cloneDataList, index)
  vm.$Message.success('删除成功');
  }, 1000)
 },
 // 还原数据,用来与原始数据作对比的
 handleBackdata: function(object) {
  var clonedData = JSON.parse(JSON.stringify(object));
  delete clonedData.editting;
  delete clonedData.saving;
  return clonedData;
 }
 },
 created: function() {
 this.getData();
 this.init();
 }
});

总结

两三天的时间搞的这些,刚开始也是各种懵逼.期间也试过用插槽来实现,但还是没有这个方法来的清晰(队友都能看懂), 总的来说就是在columnsList自定义一些属性,后面根据这些属性,在render函数里return不同的值,思路还是很简单的.

第一次写文章,并且我也是vue初学者,写的凑合看吧 ^_^ ,欢迎留言指正

本demo 连同之前学习vue时写的demo一起放在的我的github上,欢迎star...

github: https://github.com/catkinmu/vue.js-practice/tree/master/IViewEditTable

参考

vue: render文档
iview
iview admin1.x 版本

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • VUE+Element UI实现简单的表格行内编辑效果的示例的代码

    原理是通过Css控制绑定的输入控件与显示值,在选中行样式下对控件进行隐藏或显示 效果示例地址 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <!-- 引入样式 --> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-default/index.c

  • 对Vue table 动态表格td可编辑的方法详解

    项目中需求用到可编辑表格 下图这种 ↓ element UI 组件table表格中 增加template 模版 翻入input 根据业务逻辑增加全局变量 isEdit 是否变化. <el-table-column label="名称" width="140"> <template scope="scope"> <el-input v-if="scope.row.isEdit && scope

  • vuejs+element UI点击编辑表格某一行时获取内容填入表单的示例

    如果是已经有点经验的同学,可以直接看下面这个函数,应该就能明白怎么回事,新手可以看下面的详细教程. 函数: handleEdit: function (index, row) { this.editFormVisible = true; this.editForm = Object.assign({}, row); } 详细教程: 1.首先,做一个表格,用于显示信息:代码如下: <el-table :data="users" highlight-current-row v-loa

  • Vue封装的可编辑表格插件方法

    可任意合并表头,实现单元格编辑. 页面效果如图: 页面使用如下: <template> <div> <v-table :datat = "tableData" :thlabel="thlabel" :isEdit="true"> </v-table> </div> </template> <script> export default{ data(){ retur

  • vue+element实现表格新增、编辑、删除功能

    几天前,需要做一个需求:新增一个xml文件时,添加数量不确定.属性相同的xml标签,想了想可以用表格做啊,属性相同,使用统一的表头,下面的属性值只是进行增删改不就行了,就类似于mysql给表里填数据一样. 可是目前似乎还没有表格的直接增删改一行的操作,那要怎么实现呢?于是,通过上网以及自己的思考,终于实现了,代码.思路以及效果图如下: 1 html部分: <el-button type="success" @click="addRow(tableData)"&

  • vue+element-ui实现表格编辑的三种实现方式

    1.表格内部显示和编辑切换 这种方式就是利用两个标签显示隐藏来实现,我们这里用input和span,正常用span将数据显示,点击编辑时,将span隐藏,显示input进行编辑.选中当前行我们可以通过slot-scope中的index去实现,在控制显示隐藏的属性上绑定index就可以选中当前行了,如showEdit[index]. 页面结构代码: <el-table :data="tableData" tooltip-effect="dark" style=&

  • vue+iview 实现可编辑表格的示例代码

    先简单说明一下,这个Demo引入的vue,iview的方式是标签引入的,没有用到webpack之类的构建工具... 毕竟公司还在用angularjs+jq. 这也是我第一次写文章,大家看看思路就行了,要是有大佬指点指点就更好了 话不多说,先来个效果图 我们再看下极为简单的目录结构 IViewEditTable ## vue+iview 实现的可编辑表格 └── index.html ## 首页 └── js └── editTable.js ## 首页JS └── ivew ## iview相关

  • vue+iview写个弹框的示例代码

    iView 是一套基于Vue.js的开源UI组件库,主要服务于PC界面的中后台产品. 1.iView的特性 1) 高质量.功能丰富 2) 友好的API ,自由灵活地使用空间 3) 细致.漂亮的 UI 4) 事无巨细的文档 5) 可自定义主题 2.iView的安装: 1) 使用npm: npm install --save iview 2) CDN引入: <link rel="stylesheet" href="css/iview.css" rel="

  • vue实现导航菜单和编辑文本的示例代码

    导航菜单实例 <div id="main"> <!-- 激活的菜单样式为 active 类 --> <!-- 为了阻止链接在点击时跳转,我们使用了 "prevent" 修饰符 (preventDefault 的简称). --> <nav v-bind:class="active" v-on:click.prevent> <!-- 当菜单上的链接被点击时,我们调用了 makeActive 方法,

  • Element实现动态表格的示例代码

    目录 [代码背景] [代码实现] #1# -> 代码复用的基础是你需要一个可复用的组件 #2# -> 在展示页面使用动态表格组件 #3# -> 如何给动态表格根据需求动态添加序号列/索引列 [代码背景] 有这样一个业务需求场景,有大概十几张表归属于某个类别,用户希望在同一个页面,通过选择不同的查询指标展示不同的表格,这些表的表头样式类似但是又不完全相同,怎么做呢? 到目前为止所有基于Element UI的表格样式都是直接在页面写死的,像官方这样: <el-table :data=&

  • vue组件中使用iframe元素的示例代码

    本文介绍了vue组件中使用iframe元素的示例代码,分享给大家,具体如下: 需要在本页面中展示vue组件中的超链接,地址栏不改变的方法: <template> <div class="accept-container"> <div class="go-back" v-show="goBackState" @click="goBack">GoBack</div> <ul&g

  • 使用Vue调取接口,并渲染数据的示例代码

    刚接触vue.js框架的时候,很伤脑筋.今天整理一下post/get两种方式,简单的调取数据库数据,并进行渲染,希望帮助大家! 首先,在HTML页面引入: //引入vue.js文件 <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script> 引入vue-resource.min.js文件,就可以引入接口方法了 <script src="https://cdn.st

  • Vue+mui实现图片的本地缓存示例代码

    下面一段代码给大家分享基于Vue+mui实现图片的本地缓存,具体代码如下所示: const menu = { state: { products: {}, GLOBAL_CONFIG:GLOBAL_CONFIG['GLOBAL_CONFIG'] }, mutations: { get_product: function (state, products) { //商品列表 state.products = products; for(let i = 0; i < state.products.l

  • vue 2.0 购物车小球抛物线的示例代码

    本文介绍了vue 2.0 购物车小球抛物线的示例代码,分享给大家,具体如下: 备注:此项目模仿 饿了吗.我用的是最新的Vue, 视频上的一些写法已经被废弃了. 布局代码 <div class="ball-container"> <transition name="drop" v-for="ball in balls" @before-enter="beforeDrop" @enter="droppi

  • vue+element 实现商城主题开发的示例代码

    本文介绍了vue+element 实现商城主题开发的示例代码,分享给大家,具体如下: <template> <div> <div class="set-phone"> <el-form :model="theme" :rules="rules" ref="ruleForm" class="demo-ruleForm"> <el-form-item lab

随机推荐