vue hot true 不起作用_Vue + Flask 小知识(二)

微信公众号:萝卜大杂烩
关注可了解更多的原创内容。问题或建议,请公众号留言或加本人微信;如果你觉得文章对你有帮助,欢迎加微信交流

今天继续分享 Vue.js 学习笔记,结合 handsontable。

前面基础的如何使用 Flask + VUE 搭建环境,可以戳这里查看。

Vue + Flask 小知识(一)传送门

Handsontable

Handsontable 是一个网页版的类 excel 工具,其强大的地方已经不言而喻了。我们来看看官网上的几个例子:
漂亮的布局:

88080cce7ca8e84d6203985efccc4985.png

支持右键:

de8e05918c0d45e75f1bdd921c2dee81.png

支持下拉菜单:

aa0e756f2b831a431f282ea432964809.png

与 Vue 结合

Handsontable 官方提供了 Vue 支持的版本,安装使用也很简单。
安装

npm install handsontable @handsontable/vue

基本使用

<template>
  <hot-table :data="data" rowHeaders="true" colHeaders="true">hot-table>
template>

<script>import { HotTable } from '@handsontable/vue';export default {data: function() {return {data: [
          ["", "Ford", "Volvo", "Toyota", "Honda"],
          ["2016", 10, 11, 12, 13],
          ["2017", 20, 11, 14, 13],
          ["2018", 30, 15, 12, 13]
        ],
      };
    },components: {
      HotTable
    }
  }script>

<style src="../node_modules/handsontable/dist/handsontable.full.css">style>

这样,就把 Handsontable 与 Vue 框架结合到一起了。
下面我们做一些不一样的,从本地 excel 导入数据,在线编辑,最后再下载到本地

导入本地 excel 数据

页面布局

template 文件

<template>
  <div id="hot-preview">
          <div class="controls">
          <input accept=".xlsx" id="pop_file" type="file" value="选择模板" @change="impt(this)" />
          <el-button type="primary" name="save" id="save" class="intext-btn" v-on:click="save()">Saveel-button>
          <el-button type="primary" id="download" name="download" v-on:click="down()" class="intext-btn">Downloadel-button>
        div>
    <HotTable :root="root" ref="testHot" :settings="hotSettings" id="hottable">HotTable>
  div>
template>

布局效果:

d561cf4eb80bcf63df4e4743ab1c265d.png

对于 save 的处理,我的设想是保存到后台数据库中,暂时还未实现,就留到下次的分享了。

script 脚本

<script>import { HotTable } from '@handsontable/vue'import Handsontable from 'handsontable';import utl from '../../utils/utl'import xHred from '../../utils/header'export default {data: function() {return {root: 'test-hot',hotSettings: {// data: [['sample', 'data']],
          data: [        //数据可以是二维数组,也可以是数组对象                
          ],minRows: 1,  //最小行列
          minCols: 5,rowHeaders: true,//行表头,可以使布尔值(行序号),可以使字符串(左侧行表头相同显示内容,可以解析html),也可以是数组(左侧行表头单独显示内容)。
          colHeaders:   [ 'ID','账号', '用户名', '爱好', '能力', '频率','颜值',],//自定义列表头or 布尔值
          autoWrapRow: true, //自动换行
          contextMenu:{items:{"row_above": {name:'上方插入一行'
                },"row_below": {name:'下方插入一行'
                },"col_left": {name:'左方插入列'
                },"col_right": {name:'右方插入列'
                },"hsep1": "---------", //提供分隔线"remove_row": {name: '删除行',
                },"remove_col": {name: '删除列',
                },"make_read_only": {name: '只读',
                },"borders":{name:'表格线'
                },"copy":{name:'复制'
                },"cut":{name:'剪切'
                },"commentsAddEdit": {name: '添加备注',
                },"commentsRemove": {name: '取消备注',
                },"freeze_column": {name: '固定列',
                },"unfreeze_column": {name: '取消列固定',
                },"hsep2": "---------",
            }
          },manualColumnFreeze: true, //手动固定列  ?
          manualColumnMove: true, //手动移动列
          manualRowMove: true,   //手动移动行
          manualColumnResize: true,//手工更改列距
          manualRowResize: true,//手动更改行距
          comments: true, //添加注释  ?
          cell: [  
            {row: 1, col: 1, comment: {value: 'this is test'}},
          ],customBorders:[],//添加边框
          columnSorting: true,//排序
                    sortIndicator: true,autoColumnSize: true,dropdownMenu: true,stretchH: 'all',//根据宽度横向扩展,last:只扩展最后一列,none:默认不扩展
          fillHandle: true, //选中拖拽复制 possible values: true, false, "horizontal", "vertical"
          fixedColumnsLeft: 2,//固定左边列数
          fixedRowsTop: 2,//固定上边列数
          mergeCells: [   //合并// {row: 1, col: 1, rowspan: 3, colspan: 3},  //指定合并,从(1,1)开始行3列3合并成一格// {row: 3, col: 4, rowspan: 2, colspan: 2}
          ],columns: [     //添加每一列的数据类型和一些配置
            {},
        {},
        {},
        {},
        {},
        {},
            {}
          ],
        }
      };
    },methods:{// 导入数据
            impt() {const file = document.getElementById('pop_file');const hotinstance = this.$refs.testHot.hotInstance
                utl.XLSX.onImport(file, function () {var rt = utl.XLSX.getSheetsByIndex();
                    rt.forEach(function (value, index, array) {var myData = new Array();for (var i = 0; i                         var inner = [array[i]["ID"], array[i]["账号"], array[i]["用户名"]]
                        myData.push(inner);
                    }
                    hotinstance.loadData(myData);
                    });
                    });
                },//下载数据
            down() {const hotinstance = this.$refs.testHot.hotInstancevar d = utl.Object.copyJson(hotinstance.getSourceData());var tmp = new Array();for (var i = 0; i                     var inner = {ID: d[i][0], 账号: d[i][1], 用户名: d[i][2]};
                    tmp.push(inner);
                }
                tmp.unshift(utl.Object.reverse(xHred));
                utl.XLSX.onExport(tmp);
                },
    },components: {
      HotTable
    }
  }script>

<style src="../../../node_modules/handsontable/dist/handsontable.full.css">style>

下面我们来逐步看下

首先说下 utl.js 文件,其实是在网上找的佚名大神的代码,哈哈哈,拿来即用。里面封装了对 excel 的相关操作,是核心的核心。
然后在 header.js 中,定义了表格所拥有的列

const xHred = {
    "ID": "ID",
    "账号": "账号",
    "用户名": "用户名",
    "爱好": "爱好",
    "能力": "能力",
    "频率": "频率",
    "颜值": "颜值"
    };

export default xHred;

至于 hotSettings 里的内容,都是 Handsontable 官网的内容,通读官方文档很重要哦。

下面,来看看 impt 函数
首先获取到选择文件 input 控件中选择的 .xlsx 文件,然后调用 utl.js 中封装的函数 omImport,把数据导入到内存中,接着再遍历数据,再导入到 Handsontable 实例中,即页面的表格中。

对于 down,其实也差不多
把页面表格中的数据导入到内存中,然后调用 onExport 函数,导出到本地。
我们来看看导入时的效果

4fb79c45729dcf6287073ba7c1c5be51.gif

对于 download 就不再演示了,小伙伴儿们自行尝试下吧。

希望大家喜欢这个 Vue 系列

猜泥稀饭:

从头搭建一个在线聊天室(一)

从头搭建一个在线聊天室(二)

从头搭建一个在线聊天室(三)

从头搭建一个在线聊天室(四)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本文将介绍如何使用 VueFlask 搭建一个具有登录、注册、权限控制等基础功能的后台管理系统。 首先,我们需要准备以下环境: 1. Python3.x 2. Flask 3. Flask-RESTful 4. Flask-JWT-Extended 5. Vue.js 6. Vue Router 7. Element UI 接下来,我们开始搭建后台管理系统。 1. 安装 Flask 和相关扩展 使用 Python3.x 版本安装 Flask 和相关扩展,可以使用 pip 工具,执行以下命令: ``` pip install flask Flask-RESTful Flask-JWT-Extended ``` 2. 创建 Flask 应用 在项目根目录创建一个 app.py 文件,编写以下代码: ```python from flask import Flask, jsonify from flask_restful import Api from flask_jwt_extended import JWTManager app = Flask(__name__) app.config['JWT_SECRET_KEY'] = 'jwt-secret-string' api = Api(app) jwt = JWTManager(app) @app.route('/ping') def ping(): return jsonify({'message': 'pong'}) if __name__ == '__main__': app.run(debug=True) ``` 上面的代码创建了一个 Flask 应用,并注册了一个 `/ping` 路由,用于测试应用是否正常运行。 3. 创建 Vue 项目 使用 Vue CLI 创建一个新的 Vue 项目,执行以下命令: ``` vue create vue-admin ``` 安装 Element UI 和 Vue Router,执行以下命令: ``` cd vue-admin npm install element-ui vue-router --save ``` 4. 配置 Vue Router 打开 src/router/index.js 文件,编写以下代码: ```javascript import Vue from 'vue' import Router from 'vue-router' import Home from '@/views/Home.vue' import Login from '@/views/Login.vue' Vue.use(Router) const router = new Router({ routes: [ { path: '/', name: 'home', component: Home }, { path: '/login', name: 'login', component: Login } ] }) export default router ``` 上面的代码定义了两个路由,一个是首页路由 `/`,一个是登录页路由 `/login`。 5. 创建登录页 在 src/views 目录下创建 Login.vue 文件,编写以下代码: ```html <template> <div class="login"> <el-form ref="form" :model="form" :rules="rules" label-width="80px"> <el-form-item label="用户名" prop="username"> <el-input v-model="form.username"></el-input> </el-form-item> <el-form-item label="密码" prop="password"> <el-input type="password" v-model="form.password"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="handleSubmit">登录</el-button> </el-form-item> </el-form> </div> </template> <script> export default { data() { return { form: { username: '', password: '' }, rules: { username: [{ required: true, message: '请输入用户名', trigger: 'blur' }], password: [{ required: true, message: '请输入密码', trigger: 'blur' }] } } }, methods: { handleSubmit() { this.$refs.form.validate(valid => { if (valid) { console.log('submit', this.form) } else { console.log('validate failed') return false } }) } } } </script> <style scoped> .login { width: 400px; margin: 0 auto; padding-top: 100px; } </style> ``` 上面的代码创建了一个登录表单,用于用户登录,表单提交时会调用 handleSubmit 方法。 6. 实现登录功能 打开 src/views/Login.vue 文件,修改 handleSubmit 方法,使用 axios 发送登录请求,如下: ```javascript handleSubmit() { this.$refs.form.validate(valid => { if (valid) { axios.post('/api/auth/login', this.form) .then(({ data }) => { console.log('login success', data) localStorage.setItem('jwt', data.access_token) this.$router.push('/') }) .catch(err => console.error(err)) } else { console.log('validate failed') return false } }) } ``` 上面的代码使用 axios 发送登录请求,将登录成功后返回的 access_token 存储在 localStorage ,并跳转到首页。 7. 添加路由守卫 打开 src/router/index.js 文件,添加路由守卫,如下: ```javascript import Vue from 'vue' import Router from 'vue-router' import Home from '@/views/Home.vue' import Login from '@/views/Login.vue' Vue.use(Router) const router = new Router({ routes: [ { path: '/', name: 'home', component: Home, meta: { requiresAuth: true } }, { path: '/login', name: 'login', component: Login } ] }) router.beforeEach((to, from, next) => { if (to.matched.some(record => record.meta.requiresAuth)) { const jwt = localStorage.getItem('jwt') if (!jwt) { next('/login') } else { next() } } else { next() } }) export default router ``` 上面的代码添加了路由守卫,如果用户未登录,访问需要认证的路由时会自动跳转到登录页。 8. 实现 Flask API 在 app.py 文件添加以下代码: ```python from flask_restful import Resource, reqparse from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity parser = reqparse.RequestParser() parser.add_argument('username', type=str, required=True, help='Username required') parser.add_argument('password', type=str, required=True, help='Password required') class Auth(Resource): def post(self): args = parser.parse_args() username = args['username'] password = args['password'] if username == 'admin' and password == 'admin': access_token = create_access_token(identity=username) return {'access_token': access_token}, 200 else: return {'message': 'Invalid credentials'}, 401 class User(Resource): @jwt_required def get(self): current_user = get_jwt_identity() return {'username': current_user}, 200 api.add_resource(Auth, '/api/auth/login') api.add_resource(User, '/api/user') ``` 上面的代码实现了两个 API 接口,一个是登录接口 `/api/auth/login`,一个是获取当前用户接口 `/api/user`,这两个接口都需要认证才能访问。 9. 实现 Element UI 布局 打开 src/App.vue 文件,编写以下代码: ```html <template> <div class="app"> <el-container style="height: 100%;"> <el-header style="height: 60px; line-height: 60px;"> <el-row> <el-col :span="12"> <h1 style="color: #fff; margin-left: 20px;">后台管理系统</h1> </el-col> <el-col :span="12"> <div style="float: right; margin-right: 20px;"> <el-dropdown> <span class="el-dropdown-link"> <i class="el-icon-user"></i> {{ username }} <i class="el-icon-arrow-down el-icon--right"></i> </span> <el-dropdown-menu slot="dropdown"> <el-dropdown-item @click="handleLogout">退出登录</el-dropdown-item> </el-dropdown-menu> </el-dropdown> </div> </el-col> </el-row> </el-header> <el-container> <el-aside style="width: 200px;"> <el-menu default-active="1" class="el-menu-vertical-demo" :router="true" :collapse="isCollapse"> <el-submenu index="1"> <template slot="title"> <i class="el-icon-menu"></i> <span>菜单1</span> </template> <el-menu-item index="/menu1/page1">页面1</el-menu-item> <el-menu-item index="/menu1/page2">页面2</el-menu-item> </el-submenu> <el-submenu index="2"> <template slot="title"> <i class="el-icon-setting"></i> <span>菜单2</span> </template> <el-menu-item index="/menu2/page1">页面1</el-menu-item> <el-menu-item index="/menu2/page2">页面2</el-menu-item> </el-submenu> </el-menu> </el-aside> <el-main> <router-view></router-view> </el-main> </el-container> </el-container> </div> </template> <script> import axios from 'axios' export default { data() { return { username: '', isCollapse: false } }, mounted() { axios.get('/api/user') .then(({ data }) => { console.log('get user', data) this.username = data.username }) .catch(err => console.error(err)) }, methods: { handleLogout() { localStorage.removeItem('jwt') this.$router.push('/login') } } } </script> <style> .app { height: 100%; } </style> ``` 上面的代码使用 Element UI 实现了后台管理系统的布局,包括头部、侧边栏和主体区域。 10. 完成 至此,我们已经完成了一个基于 VueFlask 的后台管理系统的开发,具有登录、注册、权限控制等基础功能。后续可以根据项目需求进行功能扩展和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值