vue 点击查看详情在该行后追加一个tr显示详情
vue 点击 查看详情 在该行后追加一个 tr 显示详情
效果(点击查看详情,在这个tr下显示出来详细信息):
显示详细信息:
数据结构:
data() { return { packages: [], currentActive:-1,
file:{} } },
html部分:
注意使用<template>
虚元素将两行tr
包裹起来。
<table class="table table-bordered table-hover"> <thead> <tr> <th>#</th> <th>版本号</th> <th>文件个数</th> <th>总共大小</th> <th>发布时间</th> <th>状态</th> <th>操作</th> </tr> </thead> <tbody> <template v-for="(package, index) in packages">
<tr :class="{info: index == currentActive, success: index == 0 && package.status == 1}"> <td>{{index + 1}}</td> <td>{{package.name}}</td> <td>{{package.total}}</td> <td>{{package.total_size}}</td> <td>{{package.publish_time}}</td> <td> <span v-if="package.status == 1">最新发布</span> </td> <td> <button class="btn btn-danger btn-xs" role="button" @click="doDelete(package, index)">删除</button> <button class="btn btn-success btn-xs" role="button" @click="doPublish(package)">发布</button> <button class="btn btn-primary btn-xs" role="button" @click="loadDetail(package, index)">查看详情 <span class="caret"></span></button> </td> </tr>
<tr v-show="index == currentActive"> <td colspan="7"> <div class="panel panel-primary"> <div class="panel-heading">详细信息 <button type="button" @click="currentActive = -1" class="close"><span aria-hidden="true">×</span></button> </div> <div class="panel-body"> <table class="table table-bordered table-hover" v-if="package.upgrades && Object.keys(package.upgrades).length"> <thead> <tr> <th>#</th> <td>文件名称</td> <td>版本号</td> <td>下载路径</td> <td>操作</td> </tr> </thead> <tbody> <tr v-for="(upgrade, index) in package.upgrades"> <td>{{index + 1}}</td> <td>{{upgrade.name}}</td> <td>{{upgrade.version_name}}</td> <td>{{upgrade.download_path}}</td> <td> <button class="btn btn-danger btn-xs" role="button" @click="doDeleteUpgrade(package, upgrade, index)">删除</button> </td> </tr> </tbody> </table> <form class="form-inline pull-right"> <div class="form-group"> <a href="javascript:;" class="file">选择文件 <input type="file" v-on:change="file_change" accept=".apk"> </a> <span class="text-info">{{file.name ? file.name : '未选择任何文件' }}</span> </div> <button type="button" @click="submit(package)" class="btn btn-primary btn-sm">确认上传</button> </form> </div> </div> </td> </tr> </template> </tbody> <tfoot> <tr> <td colspan="7">总计:{{packages.length}} 条记录</td> </tr> </tfoot> </table>
packages数据格式:
[ { "id": 11, "name": "KTC-E6800-V001", "uploader": 1, "total_size": "577.33KB", "status": "1", "publish_time": "2018-03-15 10:36:52", "type": "0", "created_at": "2018-03-15 10:36:20", "updated_at": "2018-03-15 10:36:52", "total": 2, "upgrades": [ { "id": 47, "path": "5aa9dc340c95b.apk", "name": "HsWebSocket.apk", "package_name": "com.android.finger", "package_id": 11, "version_name": "KTC-E6800-V001", "version_code": "1", "md5": "df02eaf0cdf35ab6aae44eddce3e492e", "file_size": 295591, "state": "1", "publish_time": "2018-03-15 10:36:52", "type": "0", "uploader": 1, "desc": null, "created_at": "2018-03-15 10:36:36", "updated_at": "2018-03-15 10:36:52", "download_path": "http://www.vue.com/storage/5aa9dc340c95b.apk", "model": null }, { "id": 48, "path": "5aa9dc3d7a1ac.apk", "name": "HsWebSocket.apk", "package_name": "com.android.finger", "package_id": 11, "version_name": "KTC-E6800-V001", "version_code": "1", "md5": "df02eaf0cdf35ab6aae44eddce3e492e", "file_size": 295591, "state": "1", "publish_time": "2018-03-15 10:36:53", "type": "0", "uploader": 1, "desc": null, "created_at": "2018-03-15 10:36:45", "updated_at": "2018-03-15 10:36:53", "download_path": "http://www.vue.com/storage/5aa9dc3d7a1ac.apk", "model": null } ] }, { "id": 9, "name": "K438-v001", "uploader": 1, "total_size": "0.00B", "status": "0", "publish_time": null, "type": "0", "created_at": "2018-03-15 10:19:39", "updated_at": "2018-03-15 10:36:52", "total": 0, "upgrades": [] }, { "id": 10, "name": "K438", "uploader": 1, "total_size": "0.00B", "status": "0", "publish_time": null, "type": "0", "created_at": "2018-03-15 10:19:44", "updated_at": "2018-03-15 10:36:52", "total": 0, "upgrades": [] } ]
javascript部分:
<script> export default { data() { return { packages: [], currentActive:-1, file:{}, } }, mounted() { this.load_data() }, methods: { load_data () { var ax = axios.get('packages'), me = this; ax.then((response) => { me.packages = response.data }) }, doDelete (item, index) { let me = this; me.$reused.del('packages/' + item.id, () => { me.packages.splice(index, 1); me.$reused._alertSuccess(); }, item.path); }, doDeleteUpgrade (package_, upgrade, index){ let me = this; me.$reused.del('upgrade/' + upgrade.id, () => { package_.upgrades.splice(index, 1); me.$reused._alertSuccess(); me.file = {}; }, upgrade.path); }, doPublish (pack, index) { let ax = axios.put(`packages/${pack.id}/publish`), me = this; console.log(ax); ax.then((response) => { me.load_data() me.$reused._alertSuccess(); }); }, loadDetail (item, index){ if(this.currentActive == index){ this.currentActive = -1; }else{ this.currentActive = index; } }, file_change (e) { this.file = e.target.files[0]; }, submit (item) { let me = this, data = new FormData(); data.append('file', me.file); data.append('key', 'news'); data.append('package_id', item.id); axios.post('upgrade', data) .then(function (response) { item.upgrades.push(response.data) me.$reused._alertSuccess(); me.file = {}; }); } } } </script>