VUE元件系列7:Table封裝3
阿新 • • 發佈:2019-04-20
前面寫的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; }
效果如下
呼叫方式
展示效果:
預設資料
點選修改後資料
剩下的慢慢補全,總算不用每次都寫好幾