前面写的Table封装,只是省了一部分事情,还是需要通过slot配置表结构,没有达到一开始的想法:
只配置一个加载url和一个增删改url 就完事了。
所以就再次优化。
问题1 修改与非修改间切换,通过这么一个JSON数组 {"name":"标签名称","val":"标签值","flag":"是否显示"}
<div class="unit" v-for="(item, index) in userData" :key="index">
<label>{{ item.name }}:</label>
<input
type="text"
v-model="item.val"
class="sys_input"
v-bind:disabled="item.flag == '0' ? false : true"
/>
</div>
实现效果如下,这样就可以直接控制是否可以修改了。
测试源码如下:
<template>
<div>
<!-- table部分 -->
<div class="carddata">
<table class="pre_dataintable">
<thead>
<tr>
<th v-for="(item, index) in tab_th" :key="index">
{{ item.val }}
</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in tab_tr" :key="index">
<td v-for="(temp, index) in item" :key="index">
<input
type="text"
v-model="temp.val"
v-bind:disabled="temp.flag == '0' ? false : true"
/>
</td>
<td>
<button @click="fun_upd(item)">修改</button>
<button @click="fun_sav(item)">保存</button>
<button @click="fun_del(item)">删除</button>
</td>
</tr>
</tbody>
</table>
</div>
<!-- 分页部分 -->
<div class="pre_page" v-show="show_page">
<ul style="text-align: right; margin-right: 20px;">
<li>
当前页:<label>{{ nowpage }}</label
> 合计页:<label>{{ maxpage }}</label
> <a href="#" @click="firstpage">首页</a>|
<a href="#" @click="beforepage">上一页</a>|
<a href="#" @click="nextpage">下一页</a>|
<a href="#" @click="lastpage">尾页</a>
<input type="text" v-model="jumppage" value="" /><a
href="#"
@click="gopage"
class="go"
>Go</a
>
</li>
</ul>
</div>
<!-- 弹出向导层 start-->
<div id="pop" class="pop" v-show="pop_show">
<div class="pop_head">
<a class="close" href="javascript:void(0);" @click="hide()"></a>
</div>
<div id="pop_bodyup" class="pop_bodyup">
<div class="input_data">
<slot name="tab_addorupdate"></slot>
<!-- <button
@click="neworupdate"
@keyup.enter="neworupdate"
style="margin:30px 0 0 80px;background:#4f5f6f;width:56px;height:28px;border:none;outline:none;cursor: pointer;color:#fff;"
>
新增或修改
</button> -->
</div>
</div>
</div>
<!-- 弹出向导层 end-->
<!-- 添加到下面 start -->
<div class="data_down">
<slot name="tab_addorupdate_down"></slot>
</div>
<!-- 添加到下面 end -->
<!-- 组件引入部分 弹窗组件和等待组件 -->
<div>
<per-message ref="msg_back" :message_data="msg_obj" />
<pre-loading :pre_show_loading="fullloading" />
</div>
</div>
</template>
<script >
/*
名称:Table组件
日期:2019-03-21
作者:hj
目标:1、传入一组数据,自动构建标题和内容=>两个数组 1个数组是标题 1个数组是内容 方便构造
2、所有的增、删、改、查、均在组件内容完成。
3、还可以分页
分析:1、增、删、改、查 调用api主动配置。=>容易
2、标题主动配置。=>容易
3、每一列的校验方式 =>配置
4、不使用 solo 占位符实现
*/
import '@/assets/css/pop.css';
import '@/assets/css/pre_table.css';
export default {
name: "pre_table_base",
components: {
'per-message':()=>import("./pre_message.vue"),
'pre-loading':()=>import("./pre_loading.vue")
},
data() {
return {
tab_th: [], //标题
tab_tr: [], //内容
show_page:true,
maxpage:'',
nowpage:'',
jumppage:'',
msg_obj:{},
fullloading:false,
pop_show:false,
show_btn_upd:true,
show_btn_del:true,
show_btn_sav:true,
};
},
props: {
api_url:String,
pre_post:String,
page:String,
/* 需要 增 删 改 就绑定这个 */
pre_post_upd:{ type:String,default:'' },
/* 按钮显示控制 */
show_btn_upd:{type:Boolean,default:true},
show_btn_del:{type:Boolean,default:true},
show_btn_sav:{type:Boolean,default:true}
},
created:function(){
if(Number(this.nowpage)==0) this.nowpage=1;
},
watch:{
pre_post(val){
//监测查询条件 改变即重查
this.loaddata();
},
pre_post_upd(val){
// 监测修改条件 改变即修改
if(String(val)!='')
this.neworupdate();
},
page(val){
// 监测翻页
if(Number(val)==0){
this.nowpage=1;
}else{
this.nowpage=Number(val);
}
},
nowpage(val){
// 返回新页数
this.$emit("tab-event", this.nowpage);
}
},
mounted() {
this.initTable();
this.loaddata();
},
methods: {
initTable:function(){
if(Number(this.maxpage)==0){
this.show_page=false;
}else{
this.show_page=true;
}
},
firstpage:function(){
if(Number(this.nowpage)>1){
this.nowpage=1;
this.refresh_data();
}else{
this.msg_obj={'showtype':'warning','note':'已经是第一页'};
}
},
beforepage:function(){
if(Number(this.nowpage)>1){
this.nowpage--;
this.refresh_data();
}else{
this.msg_obj={'showtype':'warning','note':'已经是第一页'};
}
},
nextpage:function(){
if(Number(this.nowpage)<Number(this.maxpage)){
this.nowpage++;
this.refresh_data();
}else{
this.msg_obj={'showtype':'warning','note':'已经是最后一页'};
}
},
lastpage:function(){
if(Number(this.nowpage)<Number(this.maxpage)){
this.nowpage=this.maxpage;
this.refresh_data();
}else{
this.msg_obj={'showtype':'warning','note':'已经是最后一页'};
}
},
gopage:function(){
console.log('跳转到='+this.jumppage);
if(Number(this.jumppage)>0 && Number(this.jumppage)<=Number(this.maxpage)){
this.nowpage=this.jumppage;
this.refresh_data();
}else{
this.msg_obj={'showtype':'warning','note':'跳转页数不在规定范围内,请检查'+this.jumppage};
}
},
loaddata:function() {
// console.log(this.api_url);
// console.log(this.pre_post);
// this.fullloading=true;
// this.$post(
// this.api_url,
// this.pre_post,
// ).then(res => {
// this.fullloading=false;
// try {
// res=JSON.parse(res);
// console.log(res.data);
// if (res.data.status == 1) {
// this.maxpage=res.data.allpage;
// this.data_tab=res.data.data;
// } else {
// this.msg_obj={'showtype':'warning','note':res.data.msg};
// }
// this.initTable();
// } catch (ex) {
// this.msg_obj={'showtype':'warning','note':"查询失败"+ex};
// }
// });
// 构建测试数据 二维数组 模拟通过api取到如下数据
var data=[];
var tobj=[];
tobj.push({"val":"序号"});
tobj.push({"val":"列名1"});
tobj.push({"val":"列名2"});
tobj.push({"val":"列名3"});
data[0]=tobj;
console.log(data);
for(var i=1;i<5;i++){
tobj=[];
tobj.push({"val":""+i+"","flag":"1"});
tobj.push({"val":""+i+"行数据1","flag":"1"});
tobj.push({"val":""+i+"行数据2","flag":"1"});
tobj.push({"val":""+i+"行数据3","flag":"1"});
data[i]=tobj;
}
// 将表头和内容分开
this.tab_th=data[0];
var tdata=[],num=0;
for(var i=1;i<data.length;i++){
tdata[num]=data[i];
num++;
}
this.tab_tr=tdata;
console.log(this.tab_th);
console.log(this.tab_tr);
},
refresh_data() {
console.log('刷新');
this.$emit("tab-event", this.nowpage,this.key_word,'');
},
showpop:function(){
this.pop_show=true;
},
hide:function(){
this.pop_show=false;
},
fun_add:function(){
},
fun_del:function(item){
console.log('删除');
var ts=JSON.stringify(item).toString();
console.log(ts);
},
fun_upd:function(item){
console.log('修改');
// var ts=JSON.stringify(item).toString();
// console.log(ts);
// 释放修改权限
console.log(item);
var id=item[0].val;
for(var i=0;i<this.tab_tr.length;i++){
if(this.tab_tr[i][0].val==item[0].val){
for(var j=1;j<this.tab_tr[i].length;j++){
this.tab_tr[i][j].flag='0';
}
}else{
for(var j=1;j<this.tab_tr[i].length;j++){
this.tab_tr[i][j].flag='1';
}
}
}
},
fun_sav:function(item){
console.log('保存');
var ts=JSON.stringify(item).toString();
console.log(ts);
},
fun_sel:function(){
},
neworupdate:function() {
// console.log(this.api_url);
// console.log(this.pre_post_upd);
this.fullloading=true;
this.$post(
this.api_url,
this.pre_post_upd,
).then(res => {
this.fullloading=false;
this.pop_show=false;
try {
res=JSON.parse(res);
console.log(res.data);
if (res.data.status == 1) {
this.msg_obj={'showtype':'ok','note':res.data.msg};
this.loaddata();
} else {
this.msg_obj={'showtype':'err','note':res.data.msg};
}
this.initTable();
} catch (ex) {
this.msg_obj={'showtype':'warning','note':"查询失败"+ex};
}
});
},
}
};
</script>
<style scoped >
</style>
CSS样式文件
/* pre_search */
.pre_btn {
text-align: left;
}
.pre_btn > label {
position: relative;
/* left: 2%; */
}
.pre_btn > input {
position: relative;
/* left: 2%; */
}
.pre_btn > input :focus {
border: 1px solid #024aee;
background-color: #aaa;
}
.pre_btn > button {
position: relative;
left: 2%;
width: 120px;
height: 32px;
line-height: 32px;
border-radius: 5px;
}
.pre_btn_ok {
background-color: rgba(68, 70, 238, 0.986);
color: white;
font-optical-sizing: 16px;
}
.pre_btn_ok :focus {
background-color: rgba(247, 61, 36, 0.986);
}
/* table 整体样式 */
.pre_dataintable {
margin-top: 15px;
border-collapse: collapse;
border: 1px solid #aaa;
width: 95%;
/* padding 没有作用 */
/* padding: 0px 5px 10px 5px; */
position: relative;
/* left: 2%; */
}
.pre_dataintable th {
vertical-align: baseline;
padding: 5px 15px 5px 6px;
background-color: rgb(87, 201, 230);
border: 1px solid #3f3f3f;
text-align: center;
color: #000000;
font-size: 16px;
font-weight: bolder;
}
.pre_dataintable td {
/* vertical-align: text-top; */
padding: 5px 8px 5px 8px;
border: 1px solid #aaa;
text-align: left;
}
/* 表格内按钮 */
.pre_dataintable td button {
width: 80px;
padding: 6px 6px 6px 6px;
border: 1px solid #aaa;
text-align: center;
display: inline-block;
}
/* 表格内输入框 */
.pre_dataintable td input {
width: 100%;
height: 100%;
border: 0px;
text-align: left;
padding: 2px 2px 2px 2px;
/* font-size: 16px; */
background-color: #babcbe00;
}
.pre_dataintable tr {
cursor: pointer;
}
.pre_dataintable tr:nth-child(odd) {
background-color: #f5f5f5;
}
.pre_dataintable tr:nth-child(even) {
background-color: #fff;
}
.pre_dataintable tr:hover {
background-color: #e2fde2;
}
.tab_add {
width: 95%;
display: flex;
margin-top: 5px;
margin-left: 2%;
background-color: rgba(103, 233, 77, 0.644);
}
.tab_upd {
width: 95%;
display: flex;
margin-left: 2%;
background-color: rgba(209, 212, 36, 0.644);
}
/* 翻页样式 */
.pre_page {
width: 100%;
margin-top: 5px;
margin-bottom: 5px;
}
.pre_page > ul {
text-align: right;
list-style: none;
}
.pre_page > ul > li > a {
text-decoration: none;
}
.pre_page > ul > li > .go {
display: inline-block;
width: 40px;
height: 20px;
border: 1px solid #cccccc;
background: #024aee;
color: #fff;
border-radius: 4px;
text-align: center;
margin-left: 5px;
}
.pre_page > ul > li > a:hover {
color: #394656;
}
/* 下面样式 */
.td_btn {
text-align: center;
}
.td_btn > button {
border-radius: 3px;
height: 28px;
padding: 1px 2px 2px 2px;
}
.td_btn > button:hover {
background-color: rgba(155, 222, 231, 0.986);
cursor: pointer;
}
.btn_upd {
background-color: rgba(244, 247, 111, 0.986);
}
.btn_sub {
background-color: rgba(44, 247, 61, 0.986);
}
.btn_can {
background-color: rgba(234, 248, 246, 0.986);
}
.btn_del {
background-color: rgba(236, 26, 26, 0.986);
}
/* 单选样式 */
.radio_name {
}
.radio_val {
width: 20px;
}
效果如下
调用方式
展示效果:
默认数据
点击修改后数据
剩下的慢慢补全,总算不用每次都写好几个slot
PS:但是这样搞,又有新的限制,在列的样式控制上很麻烦啊。不如继续slot,至少样式问题没有解决前,真心不好整啊。
另一个问题就是sql返回,之前的返回直接拼接成json格式就好,
现在得拼接成这样子。
set @jsonData+='['
set @jsonData+='{"name":"id","val":"'+CONVERT(varchar(10),@temp_id)+'","flag":"1"},'
set @jsonData+='{"name":"h_short","val":"'+@parm1+'","flag":"0"},'
set @jsonData+='{"name":"h_title","val":"'+@parm2+'","flag":"0"},'
set @jsonData+='],'
目前处理方法:
sql拼接还是这样,
set @jsonData+='{"id":"'+CONVERT(varchar(10),@temp_id)+
'","h_short":"'+@parm1+
'","h_title":"'+@parm2+'"},'
然后在webservice里统一做转换,但是这样就不能很方便的通过修改flag来控制那些字段可以修改了。
纠结啊,所以看来还得继续slot站位!当然也有一些好处,自我感觉某些场景下还是有用的
伤心。。。。。。
想到好办法再更新
2019-06-13 add
第一步 样式
用CSS把input标签透明了,
tab tr td:nth-child(列数) 可以正向指定列样式
tab tr td:last-child(列数) 可以反向指定列样式
第二步修改 默认肯定都是 readonly
当点击修改时 应该是指定部分项目 可以改,同时修改input 背景色当点击保存时 再改回去。
缺点:如果 修改项目有下拉菜单 这样的选择项目 就呵呵了,不过如果都是字符串貌似就可以。
这样看还是占位符简单、容易实现啊。
还是没有完美解决,想到了再更新