vue 前端页面开发经验记录

本博文记录了在vue项目开发中的一些经验,具体包含:class动态绑定、子页面刷新、注入函数到子页面、数据加载效果、单击后编辑、文件上传、数据分页、表单提交等的使用记录。

1、class动态绑定

根据变量的值绑定不同的class样式,这里ftype的值可为full_label、zero_label、has_label三种class样式名

        <div class="folderImg" :class="ftype" @click="to_url('showimglist',fd.name)"><i class="el-icon-folder-opened avatar-uploader-icon">i>div>

对应的class设置有

.full_label {background-image: url(../../assets/full_label.png);background-repeat:no-repeat;background-size:100% 100%;-moz-background-size:100% 100%;
}.zero_label {background-image: url(../../assets/zero_label.png);background-repeat:no-repeat;background-size:100% 100%;-moz-background-size:100% 100%;
}.has_label {background-image: url(../../assets/has_label.png);background-repeat:no-repeat;background-size:100% 100%;-moz-background-size:100% 100%;
}

2、子页面刷新 | 注入函数到子页面

通过v-if的方式设置子页面不可见,然后在this.$nextTick设置子页面可见,从而实现对子页面的刷新。然后将封装为reload函数,并注入函数到子页面,在子页面调用即可。
具体参考:https://www.jb51.net/article/260561.htm

<template><div id="app"><router-view v-if="isRouterAlive">router-view>div>
template>
<script>
import axios from 'axios'
export default {name: 'App',provide () { //设置被注入到子页面的函数return {reload: this.reload,}},data () {return {isRouterAlive: true,}},methods: {reload () {this.isRouterAlive = falsethis.$nextTick(function () {this.isRouterAlive = true})},}
}
script>

子页面的js中设置inject即可在子页面刷新内容

//子页面<script>   export default {name: 'showanalysis',inject: ['reload'], //接收父页面注入的内容}script>

3、数据加载效果

用于服务器返回结果中的过程界面(当前端调用后台接口时触发该效果,获取到结果后取消显示)

具体参考 https://element.faas.ele.me/#/zh-CN/component/loading#loading-jia-zai
在这里插入图片描述
具体用例如下,在元素中添加v-loading属性绑定变量loading,默认为false不显示效果;当触发其他耗时操作时,修改loading为true,显示加载中效果;当操作完成时,修改loading为false。

<template><div class="demo-image"v-loading="loading"element-loading-text="等待服务器处理中"element-loading-spinner="el-icon-loading"element-loading-background="rgba(0, 0, 0, 0.8)">div>
template><script>export default {name: 'showdatafolder',data() {return {loading: false,}},}
}
script>

4、宽高百分比

使用vh,vw来控制元素相对于屏幕的宽高百分比。vh和wh是视口单位,是相对长度单位。wh是相对于视口的宽度,“1vw”等于视口宽度的“1%”;而vh是相对于视口的高度,“1vh”等于视口高度的“1%”

具体参考:https://www.php.cn/faq/489349.html

5、单击后编辑

text类控件在单击后转换为input控件,在失去焦点后又变换text类空间。
以下为el-button控件与el-input控件的结合,当点击el-button后,与之对应的el-input展示,当el-input失去焦点后又显示为el-button。

<el-inputclass="input-new-tag"v-if="inputVisible"v-model="inputValue"ref="saveTagInput"  #为控件取了一个名字size="small"@keyup.enter.native="handleInputConfirm"@blur="handleInputConfirm"
>
el-input>
<el-button v-else class="button-new-tag" size="small" @click="showInput">+ New Tagel-button><script>export default {data() {return {dynamicTags: ['标签一', '标签二', '标签三'],inputVisible: false,inputValue: ''};},methods: {showInput() {this.inputVisible = true;this.$nextTick(_ => {this.$refs.saveTagInput.$refs.input.focus();//设置指定控件获取输入焦点});},handleInputConfirm() {let inputValue = this.inputValue;if (inputValue) {this.dynamicTags.push(inputValue);}this.inputVisible = false;this.inputValue = '';}}}
script>

关键解析:
1、通过v-if='inputVisible' , v-else,绑定变量inputVisible设置el-button与与el-input的显示切换
2、为el-input控件设置ref,既为控件取名字。当点击button时,触发showInput事件,设置el-input可见,并获取输入焦点
3、通过设置el-input的@blur与@keyup.enter.native属性,对输入完成后的操作进行监听,并设置inputVisible = false 输入框不可见,inputValue = '' 输入框的值为空`

代码参考自:https://element.faas.ele.me/#/zh-CN/component/tag

单击前效果

在这里插入图片描述
控件输入时效果
在这里插入图片描述

6、文件上传

这里仅实现最简单的文件上传方式,多文件上传(实质为多次调用文件上传接口)请参考 https://element.faas.ele.me/#/zh-CN/component/upload

html页面

设置action为null,主要是在:before-upload所绑定的函数中实现文件上传

      <el-upload class="upload-demo" drag action="null" :before-upload="beforeAvatarUpload"><i class="el-icon-upload">i><div class="el-upload__text">将pt文件拖到此处,或<em>点击上传em>div><div class="el-upload__tip" slot="tip">只能上传pt文件,且不超过500kbdiv>el-upload>

js实现

在beforeAvatarUpload函数中,可以对文件后缀、文件size进行判断,最后使用axios创建post请求将文件提交到后端

    beforeAvatarUpload(file) {import axios from 'axios'const isAllow = file.name.indexOf('.pt') > 0 || file.name.indexOf('.PT') > 0;const isLt200M = file.size / 1024 / 1024 / 200;if (!isAllow) {this.$message.error("只允许上传pt文件!");return false} else if (!isLt200M) {this.$message.error('上传模型大小不能超过 200MB!');return false} else {//手动进行文件上传let formData = new FormData();formData.append("file", file);axios({url: "/api/uploader",//上传文件接口method: "post",headers: {"Content-Type": "multipart/form-data",},data: formData,}).then((res) => {this.$message({title: '结果提示',message: res.data.msg,type: 'success'});this.reload();});}return false},

后端代码

后端基于flask实现

@app.route('/uploader',methods=['GET','POST'])
def uploader():if request.method == 'POST':f = request.files['file']#跟表单里file中的name要一样spath=os.path.join(runDir, f.filename)print(spath)f.save(spath)json={'code':0,'msg':'文件上传成功!'}return jsonify(json) else:return 'please uplaod file use post method!'

更多内容参考 https://element.faas.ele.me/#/zh-CN/component/upload

7、数据分页

在element-ui中详细介绍了分页控件的用法,但并未配合任何具体案例介绍。https://element.faas.ele.me/#/zh-CN/component/pagination

html页面

第一个部件为grid-content,里面v-for循环对应变量img_list,用于显示分页的具体内容
第二部分为el-pagination控件,对应具体的分页控件。可以通过修改layout对应的text,实现对分页部件内容的位置控制

<template><div class="demo-image"><el-row><div class="grid-content"><div class="block" v-for="d in img_list" :key="d"><div class="demo-image__preview"><el-image style="width: 200px; height: 200px" :src="d" :preview-src-list="img_list">el-image><div class="bottom clearfix"><el-button type="text" class="button" @click="to_url('labelimg',{'currentImage':d})">标注el-button><el-button type="text" class="button" @click="delete_img(d)">删除el-button>div>div>div>div>el-row><el-row><el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="0":page-sizes="[6, 8, 10, 12, 15, 18]" :page-size="default_page_size"layout="total, sizes, prev, pager, next, jumper" :total="all_img_list.length">el-pagination>el-row>div>
template>

js实现

主要涉及的变量有all_img_list | 所有的数据、img_list | 当前分页的数据、default_page_size | 每一页的数据量、default_page | 当前页。
在页面初始化的时候,既mounted函数中获取全部数据设置到all_img_list中,并根据default_page_size、default_page截取当前页内容设置到img_list中。

<script>
import axios from 'axios'
export default {name: 'showimglist',data() {return {all_img_list: [],img_list: [],default_page_size: 10,default_page: 1,}},mounted() {if(this.$route.query.dname){localStorage.setItem('dname', this.$route.query.dname);}let dname = localStorage.getItem('dname');//this.$route.params.dname;this.dname=dname;if (dname) {let formData = new FormData();formData.append("dname", dname);axios({url: '/api/datamanage_get_imglist',//上传文件接口method: "post",headers: {"Content-Type": "multipart/form-data",},data: formData,}).then((res) => {this.all_img_list = res.data;this.img_list = this.all_img_list.slice(0, this.default_page_size)});}},methods: {handleSizeChange(val) {this.default_page_size = val;this.img_list = this.all_img_list.slice((this.default_page - 1) * this.default_page_size, this.default_page * this.default_page_size);},handleCurrentChange(val) {this.default_page = valthis.img_list = this.all_img_list.slice((this.default_page - 1) * this.default_page_size, this.default_page * this.default_page_size);},}
}
script>

以上代码中,handleSizeChange用于监听分页数量的改变,handleCurrentChange用于检测页码数的改变

后端实现

这里的分页本质上与后端没有任何关系,每次分页时并未向后端请求对应页码的数据,仅在已有数据中进行截取。
当总数据较多时,可以在handleSizeChange与handleCurrentChange中实时从后端获取数据。

最终实现的页面效果如下
在这里插入图片描述

8、表单提交

表单实现

以下表单所绑定的为json对象:model="ruleForm",故此v-model="ruleForm.name"其el-form-item所绑定的为ruleForm.name,同时还:rules="rules"绑定了验证规则rules,ref="ruleForm" 表单被命名为ruleForm。
由submitForm事件提交表单

  <el-form :model="ruleForm" :rules="rules" ref="ruleForm"  style="padding: 30px;width:400px;background-color: bisque;" label-width="100px" class="demo-ruleForm"><el-form-item label="用户名" prop="name"><el-input v-model="ruleForm.name">el-input>el-form-item><el-form-item label="密码" prop="pwd"><el-input type="password" v-model="ruleForm.pwd">el-input>el-form-item><el-form-item><el-button type="primary" @click="submitForm('ruleForm')">立即登录el-button><el-button @click="resetForm('ruleForm')">重置el-button>el-form-item>el-form>

表单验证及提交

ruleForm对象为表单所绑定的数据模型
rules为表单具体字段的验证规则,针对每一个字段都可以设置多条规则
submitForm函数实现表单的验证及提交

 export default {name: 'login',data() {return {ruleForm: {name: '',pwd: '',},rules: {name: [{ required: true, message: '请输入用户名', trigger: 'blur' },{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }],pwd: [{ required: true, message: '请输入密码', trigger: 'blur' },{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }],}};},methods: {submitForm(formName) {this.$refs[formName].validate((valid) => {if (valid) {//表单验证成功,进入后台主页this.$router.push({name:'mainframe'});} else {console.log('error submit!!');return false;}});},resetForm(formName) {this.$refs[formName].resetFields();}}}

在这里插入图片描述

9、网站打包部署

网站资源打包
npm run build

网站打包后各种静态资源url错误:
https://www.muzhuangnet.com/show/60711.html

10、网站打包时保护源码

***亲测无效:https://www.jianshu.com/p/0bf0aae8cc0d ***
找到config/index.js 将以下代码注释掉,即可看不到vue源码了。
devtool: ‘#source-map’,

在这里插入图片描述


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部