使用vue代替django的模版。
# views.py
class ToolsView(View):
def get(self, request, *args, **kwargs):
return render(request, 'index.html')
class ExportView(View): # 下载文件
def post(self, request, *args, **kwargs):
data = request.POST.get('data')
response = HttpResponse(data)
response['Content-Type'] = 'application/octet-stream'
return response
前端 vue
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tools</title>
<link rel="stylesheet" type="text/css" href="{% static 'lib-master/theme-chalk/index.css' %}"/>
<style>
body {
margin: 0;
}
.input-div {
margin: 15px
}
.el-header, .el-footer {
background-color: #000000;
color: #ffffff;
text-align: center;
line-height: 60px;
}
.el-header h1 {
margin-top: 0;
height: 60px;
}
.el-aside {
color: red;
text-align: center;
height: 90vh;
}
.el-main {
color: #333;
text-align: center;
}
body > .el-container {
margin-bottom: 40px;
}
.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
line-height: 260px;
}
.el-container:nth-child(7) .el-aside {
line-height: 320px;
}
.show-area {
height: 70vh;
background-color: #f3f9f1;
overflow: scroll;
}
</style>
</head>
<body>
<div id="app"></div>
</body>
<template id='template'>npx prettier --write .
<el-container>
<el-header>
<h1>卖报歌</h1>
</el-header>
<el-container>
<el-aside width="200px">
<el-menu class="el-menu-vertical-demo">
<el-menu-item index="1" @click.native="chageAction('aaa')">
<i class="el-icon-s-order"></i>
<span slot="title">啦啦啦,啦啦啦</span>
</el-menu-item>
<el-menu-item index="2" @click.native="chageAction('bbb')">
<i class="el-icon-message-solid"></i>
<span slot="title">我是卖报的小行家</span>
</el-menu-item>
<el-submenu index="3">
<template slot="title">
<i class="el-icon-key"></i>
<span>风吹雨打都不怕</span>
</template>
<el-menu-item-group>
<el-menu-item index="3-1" @click.native="chageAction('ccc')">CCC</el-menu-item>
<el-menu-item index="3-2" @click.native="chageAction('ddd')">DDD</el-menu-item>
</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>
</el-aside>
<el-main>
<div class="input-div">
<el-input placeholder="请输入 IP address" v-model="ipAddress">
<el-button slot="append" icon="el-icon-search" @click.native="queryTarget"></el-button>
</el-input>
</div>
<div class="show-area">
<div>
[[ outPutData ]]
</div>
</div>
<div>
<el-button type="primary" round @click.native="exportData">导出</el-button>
</div>
</el-main>
</el-container>
</el-container>
</template>
<script src="{% static 'vue.min.js' %}"></script>
<script src="{% static 'lib-master/index.js' %}" type="text/javascript" charset="utf-8"></script>
<script src="{% static 'axios.min.js' %}" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
const app = new Vue({
el: '#app',
template: "#template",
data: {
ipAddress: '',
outPutData: '',
action: '',
},
delimiters: ["[[", "]]"], // 自定义分隔符号 !! 以区别于 {{ }},防止和django模版混淆
methods: {
chageAction(actionName) {
this.action = actionName
},
async queryTarget() { # 向后端发送 post 请求
try {
let params = new URLSearchParams(); # 这样参数才会附加到 request.POST中,否则参数会被放到 request.body中
params.append('ipAddress', this.ipAddress);
params.append('action', this.action);
const response = await axios.post(
'service/',
params
)
this.outPutData = response.data
} catch (error) {
this.outPutData = error.response.data || error.message
}
},
async exportData() { # 下载文件
try {
let params = new URLSearchParams();
params.append('data', JSON.stringify(this.outPutData));
const response = await axios.post(
'export/',
params
)
const ipAddress = this.ipAddress || 'IP'
const action = this.action || 'ACTION'
const date = new Date()
const year = date.getFullYear();
const month = date.getMonth();
const day = date.getDate();
const fileName = `${ipAddress}-${action}-${year}年-${month + 1}月-${day}日-result.txt`
await this.downloadFile(fileName, JSON.stringify(response.data))
} catch (error) {
this.outPutData = error.response.data || error.message
}
},
async downloadFile(fileName, content) { # 具体的下载代码
const blob = new Blob([content])
let dom = document.createElement('a');
let url = window.URL.createObjectURL(blob)
dom.href = url;
dom.download = decodeURI(fileName)
dom.style.display = 'none'
document.body.appendChild(dom)
dom.click()
dom.parentNode.removeChild(dom)
window.URL.revokeObjectURL(url)
}
}
})
</script>
</html>