当前位置: 首页 > news >正文

Vue2后台管理:项目开发全流程(一)

​🌈个人主页:前端青山
🔥系列专栏:vue篇
🔖人终将被年少不可得之物困其一生

依旧青山,本期给大家带来vue篇专栏内容:Vue2后台管理:项目开发全流程(一)

目录

Vue项目开发

项目架构搭建

1、创建项目

2、技术栈说明

初始化项目包

3、UI组件库

4、路由规划和配置

二、功能实现

1、注册功能

2、登录功能

3、后台首页布局

4、实现菜单跳转路由

5、注销登录

6、防止翻墙越权

7、回车确认提交

Vue项目开发

Vue开发项目核心点使用JS开发项目,前端页面。

Vue和原生JS及其jQuery的区别:换一种操作语法,尽量少的操作DOM

拥有了组件化,工程化的概念。可以进打包,压缩,混淆代码。。。。。 单管理功能......针对不同的业务模块设置和开发的各种功能

项目架构搭建

前后端分离项目

1、创建项目
# 安装脚手架
npm i -g @vue/cli# 生成项目包  在哪儿生成项目包 在哪儿执行
vue create 项目名称

选择创建项目包的参数选项

2、技术栈说明

客户端:

Vuejs 渲染库

Vue-Router SPA 单页面应用路由管理

Vuex 组件状态共享和管理

axios ajax请求的发送和封装

momentjs 处理时间格式化

scss css预处理器

服务端:

1、nodejs结合mongodb实现API接口

2、json-server 模拟API数据结构

3、使用服务端人员开发的接口

初始化项目包

根据需求删除项目包中无用的文件和内容

3、UI组件库

UI组件库 能够帮助开发者快速实现页面效果的一种方式。封装好的一些组件开源出来,供大家使用。

自己调查一下,上网查,问问你的朋友同学他们在公司用什么?

组件库名称使用端框架
vantUI 有赞移动端Vue,React,微信小程序,支付宝小程序
mintUI 饿了么移动端Vue
elementUI 饿了么PC端Vue,React,Angular
antdesign 蚂蚁金服PC端Vue,React,Angular
antmobile 蚂蚁金服移动端React
nuxtui 京东移动端Vue,React

本次使用elementUI:https://element.eleme.io/#/zh-CN

①安装组件库

npm i element-ui -S

②完整引入elementUI

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// 1、添加引入以下两行
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'Vue.config.productionTip = false
// 2、使用组件库
Vue.use(ElementUI)
new Vue({router,store,render: (h) => h(App)
}).$mount('#app')

③测试使用

App.vue 测试按钮组件引入使用情况

<template><div><el-row><el-button>默认按钮</el-button><el-button type="primary">主要按钮</el-button><el-button type="success">成功按钮</el-button><el-button type="info">信息按钮</el-button><el-button type="warning">警告按钮</el-button><el-button type="danger">危险按钮</el-button></el-row><el-row><el-button plain>朴素按钮</el-button><el-buttontype="primary"plain>主要按钮</el-button><el-buttontype="success"plain>成功按钮</el-button><el-buttontype="info"plain>信息按钮</el-button><el-buttontype="warning"plain>警告按钮</el-button><el-buttontype="danger"plain>危险按钮</el-button></el-row><el-row><el-button round>圆角按钮</el-button><el-button :round="true">圆角按钮</el-button><el-buttontype="primary"round>主要按钮</el-button><el-buttontype="success"round>成功按钮</el-button><el-buttontype="info"round>信息按钮</el-button><el-buttontype="warning"round>警告按钮</el-button><el-buttontype="danger"round>危险按钮</el-button></el-row><el-row><el-buttonicon="el-icon-search"circle></el-button><el-buttontype="primary"icon="el-icon-edit"circle></el-button><el-buttontype="success"icon="el-icon-check"circle></el-button><el-buttontype="info"icon="el-icon-message"circle></el-button><el-buttontype="warning"icon="el-icon-star-off"circle></el-button><el-buttontype="danger"icon="el-icon-delete"circle></el-button></el-row></div>
</template><script>
export default {}
</script><style lang="scss" scoped>
</style>

4、路由规划和配置

功能URL备注
注册/register
登录/login
管理功能/admin父级路由
用户管理功能/admin/user嵌套子路由

注意:在配置好路由文件后,一定要记得在App.vue添加渲染标签 否则无法切换显示

<router-view></router-view>

二、功能实现

1、注册功能

①表单选项布局

根据注册功能需要的表单选项进行表单的设置及其校验工作。收集数据并通过ajax提交

src\views\Register.vue

<template><div class="container"><div class="title">综合数据运营管理平台</div><!-- 注册表单 --><!-- card组件 --><el-card style="margin-top: 20px;padding: 10px 30px"><!-- 表单组件 --><el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px"><!-- 表单每个元素 --><el-form-item prop="username"><!-- 输入框 --><el-input v-model="ruleForm.username" placeholder="用户名"></el-input></el-form-item><el-form-item prop="pass"><el-input type="password" v-model="ruleForm.pass" autocomplete="off" placeholder="密码"></el-input></el-form-item><el-form-item prop="checkPass"><el-input type="password" v-model="ruleForm.checkPass" autocomplete="off" placeholder="确认密码"></el-input></el-form-item><el-form-item style="display: flex;justify-content:space-around;"><el-button type="primary" style="width: 220px;" @click="submitForm('ruleForm')">注册</el-button><!-- <el-button @click="resetForm('ruleForm')">重置</el-button> --></el-form-item></el-form></el-card></div>
</template><script>
export default {data() {// 校验用户名var checkUsername = (rule, value, callback) => {if (!value) {return callback(new Error('用户名不能为空'));}return callback()};// 校验密码var validatePass = (rule, value, callback) => {if (value === '') {callback(new Error('请输入密码'));} else if (value.length < 6) {callback(new Error('密码长度最少6位'))}else {if (this.ruleForm.checkPass !== '') {this.$refs.ruleForm.validateField('checkPass');}callback();}};// 校验确认密码var validatePass2 = (rule, value, callback) => {if (value === '') {callback(new Error('请再次输入密码'));} else if (value !== this.ruleForm.pass) {callback(new Error('两次输入密码不一致!'));} else {callback();}};return {// 表单双向绑定数据ruleForm: {username: '',pass: '',checkPass: '',},// 校验规则及其校验时机rules: {pass: [{ validator: validatePass, trigger: 'blur' }],checkPass: [{ validator: validatePass2, trigger: 'blur' }],username: [{ validator: checkUsername, trigger: 'blur' }]}};},methods: {submitForm(formName) {this.$refs[formName].validate((valid) => {if (valid) {alert('submit!');} else {console.log('error submit!!');return false;}});},resetForm(formName) {this.$refs[formName].resetFields();}}
}
</script><style lang="scss" scoped>
.container {height: 100vh;background: url('../assets/images/bg.jpg');background-size: cover;display: flex;flex-direction: column;justify-content: center;align-items: center;.title {font-size: 28px;padding: 15px;border-radius: 10px;font-weight: bold;color: white;background-color: rgba($color: #000000, $alpha: 0.4);}
}/* 使用::v-deep(选择器) 实现样式向下级组件穿透 */
::v-deep(.el-form-item__content) {margin-left: 0px !important;
}
</style>

②安装axios

npm i axios

③发送根据请求进行判断业务逻辑

methods: {// 提交表单submitForm(formName) {// ref获取到子组件的实例  validate el-from表单组件里的校验方法this.$refs[formName].validate((valid) => {if (valid) {// 通过就提交表单// alert('submit!');// 收集数据console.log(this.ruleForm);const { username, pass } = this.ruleForm// 组合接口需要的数据结构const data = { username, password: pass }axios.post('http://localhost:5000/api/v1/register', data).then(res => {console.log(res);// message提示框组件this.$message({type: res.data.code === 0 ? 'success' : 'error',duration:1000,message: res.data.msg,onClose: () => {// 跳转到登录页面this.$router.push('/login')}});})} else {// 校验不通过console.log('error submit!!');return false;}});},}

请求方法的拦截器封装

src\utils\request.js

/***  axios拦截器*  请求拦截器   统一配置请求参数信息*  响应拦截器   统一处理响应返回数据* */import axios from 'axios'
import { Loading } from 'element-ui'
var loading
const instance = axios.create({// 接口基础地址  接口的公共地址 一般域名// baseURL:'',// 超时时间// timeout:5000
})
// 请求拦截器
instance.interceptors.request.use(cfg => {// 封装请求加载状态loading = Loading.service({text: "loading...",spinner: "el-icon-loading",background: "rgba(0, 0, 0, 0.8)"});return cfg
})// 响应拦截器
instance.interceptors.response.use(res => {setTimeout(() => {// 请求加载状态停止loading.close()}, 700)return res
})export default instance

接口地址封装

src\config\url.js

/***  封装接口url地址*  方便统一管理* */const prefix = 'http://localhost:5000/api/v1'
const url = {// 注册Register: prefix + '/register'
}
export default url

2、登录功能

①表单收集用户登录信息

②发送请求给服务端接口

③根据返回结果处理业务逻辑 服务端

​ 1> 登录成功返回token

​ 2> 登录失败提示错误

④存储token和用户信息方便后续使用

响应拦截器 \backend\src\http\req.js

axios.interceptors.response.use((res) => {// 统一存储tokenif (res.data.code === 0) {localStorage.setItem('token', res.data.token)}return res.data
})

登录成功后设置 \backend\src\views\Login.vue

if (res.code === 0) {localStorage.setItem('username',res.data.username)this.$message({message: '登录成功',type: 'success',duration:1000,onClose: () => {this.$router.push('/admin')}})
} 

3、后台首页布局

布局实现

src\views\Admin\Admin.vue

<template><div><!-- 整个容器布局 --><el-container><!-- 左侧菜单 --><el-aside width="200px"><el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose"background-color="#545c64" text-color="#fff" active-text-color="#ffd04b"><el-submenu index="1"><template slot="title"><i class="el-icon-location"></i><span>导航一</span></template><el-menu-item-group><template slot="title">分组一</template><el-menu-item index="1-1">选项1</el-menu-item><el-menu-item index="1-2">选项2</el-menu-item></el-menu-item-group><el-menu-item-group title="分组2"><el-menu-item index="1-3">选项3</el-menu-item></el-menu-item-group><el-submenu index="1-4"><template slot="title">选项4</template><el-menu-item index="1-4-1">选项1</el-menu-item></el-submenu></el-submenu><el-menu-item index="2"><i class="el-icon-menu"></i><span slot="title">导航二</span></el-menu-item><el-menu-item index="3" disabled><i class="el-icon-document"></i><span slot="title">导航三</span></el-menu-item><el-menu-item index="4"><i class="el-icon-setting"></i><span slot="title">导航四</span></el-menu-item></el-menu></el-aside><!-- 右侧容器 --><el-container><!-- 头部 --><el-header>Header</el-header><!-- 主体 --><el-main>Main</el-main><!-- 底部 --><el-footer>Footer</el-footer></el-container></el-container></div>
</template><script>
export default {}
</script><style lang="scss" scoped>
.el-container {/* 设置容器的高度 */height: 100vh;
}.el-menu {/* 默认菜单右侧1px边框 去掉 */border-right: 0;
}.el-header,
.el-footer {background-color: #B3C0D1;color: #333;text-align: center;line-height: 60px;
}.el-aside {background-color: #D3DCE6;color: #333;text-align: center;line-height: 200px;
}.el-main {background-color: #E9EEF3;color: #333;text-align: center;line-height: 160px;
}.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;
}
</style>

左侧列表菜单

使用组件:https://element.eleme.io/#/zh-CN/component/menu

NavMenu 导航菜单

el-menu 整个菜单组件

el-menu-item 每个菜单组件

src\views\Admin\Admin.vue

<template><div><!-- 整个容器布局 --><el-container><!-- 左侧菜单 --><el-aside width="200px"><div class="logo"><div><img src="@/assets/logo.png" alt="" srcset=""></div><div>综合数据管理平台</div></div><!-- 菜单 --><el-menu router default-active="2" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b"><!-- index 开启router路由模式 会作为路由跳转的路径 --><el-menu-item index="/admin/dashboard"><!-- icon图标 菜单左侧 --><i class="el-icon-menu"></i><span slot="title">控制台</span></el-menu-item><!-- <el-submenu index="/admin/user"><template slot="title"><i class="el-icon-location"></i><span slot="title">用户管理</span></template> --><!-- <el-menu-item index="4"><i class="el-icon-setting"></i><span slot="title">管理员管理</span></el-menu-item> --><el-menu-item index="/admin/user"><i class="el-icon-setting"></i><span slot="title">会员管理</span></el-menu-item><!-- </el-submenu> --></el-menu></el-aside><!-- 右侧容器 --><el-container><!-- 头部 --><el-header>Header</el-header><!-- 主体 --><el-main><!-- 嵌套路由渲染容器 --><router-view></router-view></el-main><!-- 底部 --><el-footer>Footer</el-footer></el-container></el-container></div>
</template><script>
export default {}
</script><style lang="scss" scoped>
.el-container {/* 设置容器的高度 */height: 100vh;
}.el-menu {/* 默认菜单右侧1px边框 去掉 */border-right: 0;
}.el-aside {background-color: #D3DCE6;color: #333;text-align: center;
}.logo {height: 60px;display: flex;justify-content: space-around;align-items: center;color: white;font-weight: bold;background-color: rgb(84, 92, 100);>div:first-child {width: 40px;height: 40px;>img {width: 100%;}}
}.el-main {background-color: #E9EEF3;color: #333;
}.el-header,
.el-footer {background-color: #B3C0D1;color: #333;text-align: center;line-height: 60px;
}.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;
}
</style>

4、实现菜单跳转路由

①在后台首页面中添加渲染容器

\src\views\Admin\Admin.vue

 <el-main><!-- 子路由渲染容器 --><router-view></router-view></el-main>

②根据嵌套路由的配置规则创建对应路由和页面组件

src\router\index.js

{path:'/admin',component:()=>import('@/views/Admin/Admin.vue'),children:[{path:'dashboard',component:()=>import('@/views/admin/Dashboard.vue'),},{path:'user',component:()=>import('@/views/admin/User.vue'),},{path:'goods',component:()=>import('@/views/admin/Goods.vue'),},]}

③开启菜单路由功能,并且配置对应的index参数

\backend\src\views\admin\Index.vue

<el-menudefault-active="/admin/dashboard"class="el-menu-vertical-demo"@open="handleOpen"@close="handleClose"background-color="#001529"text-color="#fff"active-text-color="#409eff"router><el-menu-item index="/admin/dashboard"><!-- <i class="el-icon-platform-eleme" style="color:#409eff"></i> --><i class="el-icon-platform-eleme"></i><span slot="title">控制台</span></el-menu-item><el-menu-item index="/admin/user"><i class="el-icon-user-solid"></i><span slot="title">用户管理</span></el-menu-item><el-menu-item index="/admin/goods"><i class="el-icon-s-goods"></i><span slot="title">商品管理</span></el-menu-item></el-menu>

5、注销登录

思路:

1、按钮点击触发事件 处理注销

2、登录依据是判断是否有token,及其是否过期,退出登录的核心就是把token删除

退出按钮

<!-- 显示管理登录信息及其下拉菜单 --><el-dropdown @command="handleCommand"><span class="el-dropdown-link"><el-avatar size="medium"src="https://img1.baidu.com/it/u=3096599450,2589974591&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500"></el-avatar><span style="font-weight: bold;">{{ username }}</span><iclass="el-icon-arrow-down el-icon--right"></i></span><el-dropdown-menu slot="dropdown"><el-dropdown-item command="ucenter">个人中心</el-dropdown-item><el-dropdown-item command="logout">退出</el-dropdown-item></el-dropdown-menu></el-dropdown>

js代码部分删除token

 handleCommand(value) {console.log(value);if (value === 'logout') {this.$confirm('确认退出吗?')// 确定.then(_ => {// 将用户的token和记录信息全部清空掉localStorage.removeItem('token')localStorage.removeItem('username')this.$message({message: '退出成功',type: 'success',duration: 700,onClose: () => {this.$router.replace('/login')}})})// 取消.catch(_ => {// console.log(_);// console.log('2222');});}}

6、防止翻墙越权

注意校验是否登录权限,需要携带token信息在请求头

// 请求拦截器
instance.interceptors.request.use(cfg => {// 如果token存在,则统一添加token到请求头信息if (localStorage.getItem('token')) {cfg.headers.Authorization = localStorage.getItem('token')}// 封装请求加载状态loading = Loading.service({text: "loading...",spinner: "el-icon-loading",background: "rgba(0, 0, 0, 0.8)"});return cfg
})

实现方法:

方法一:父级路由组件的beforeCreate生命周期拦截

beforeCreate() {if (!localStorage.getItem('token')) {this.$tip('请先登录', 'error')this.$router.replace('/login')} else {this.$http.get('http://127.0.0.1:5000/api/v1/profile').then((res) => {if (res.data.code === 401) {this.$tip('请先登录', 'error')this.$router.replace('/login')} else {localStorage.setItem('userInfo', JSON.stringify(res.data.data))}})}},

方法二:使用路由守卫进行拦截

全局路由前置守卫

src\router\index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import { Message } from 'element-ui';
import url from '@/config/url';
import req from '@/utils/request'
import Register from '../views/Register.vue'
import Login from '../views/Login.vue'
import Admin from '../views/Admin/Admin.vue'
import Dashboard from '../views/Admin/Dashboard.vue'
import User from '../views/Admin/User.vue'Vue.use(VueRouter)const routes = [{path: '/',redirect: '/register'},{path: '/register',name: 'register',component: Register,meta: {isAuth: false}},{path: '/login',name: 'login',component: Login,// 路由元信息 路由传参meta: {isAuth: false}},{path: '/admin',name: 'admin',component: Admin,children: [{// 嵌套路由中 path 不需要写/  path: 'dashboard',name: 'dashboard',component: Dashboard},{path: 'user',name: 'user',component: User}],
]const router = new VueRouter({mode: 'history',base: process.env.BASE_URL,routes
})
// 全局前置守卫
router.beforeEach((to, from, next) => {console.log(to, from);// 根据路由元信息 判断哪些路由是需要校验登录if (to.meta.isAuth === false) {next()} else {// 如果本地存储未报错token 肯定没有登录if (!localStorage.getItem('token')) {Message({message: '未登录,请先登录',type: 'error',duration: 1000,onClose: () => {// 跳转到登录界面next('/login')}})} else {// 校验token的有效性req.get(url.Profile).then(res => {console.log(res);if (res.data.code === 0) {// 存储管理员登录信息localStorage.setItem('username', res.data.data.username)} else {Message({message: '登录失效,重新登录',type: 'error',duration: 1000,onClose: () => {// 跳转到登录界面next('/login')}})}})next()}}})export default router

路由独享守卫

src\router\index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import { Message } from 'element-ui';
import url from '@/config/url';
import req from '@/utils/request'
import Register from '../views/Register.vue'
import Login from '../views/Login.vue'
import Admin from '../views/Admin/Admin.vue'
import Dashboard from '../views/Admin/Dashboard.vue'
import User from '../views/Admin/User.vue'Vue.use(VueRouter)const routes = [{path: '/',redirect: '/register'},{path: '/register',name: 'register',component: Register,meta: {isAuth: false}},{path: '/login',name: 'login',component: Login,// 路由元信息 路由传参meta: {isAuth: false}},{path: '/admin',name: 'admin',component: Admin,children: [{// 嵌套路由中 path 不需要写/  path: 'dashboard',name: 'dashboard',component: Dashboard},{path: 'user',name: 'user',component: User}],// 路由 独享守卫beforeEnter: (to, from, next) => {// console.log(to);// // 如果本地存储未报错token 肯定没有登录if (!localStorage.getItem('token')) {Message({message: '未登录,请先登录',type: 'error',duration: 1000,onClose: () => {// 跳转到登录界面next('/login')}})} else {// 校验token的有效性req.get(url.Profile).then(res => {console.log(res);if (res.data.code === 0) {// 存储管理员登录信息localStorage.setItem('username', res.data.data.username)next()} else {Message({message: '登录失效,重新登录',type: 'error',duration: 1000,onClose: () => {// 跳转到登录界面next('/login')}})}})}},}// {//   path: '/about',//   name: 'about',//   // route level code-splitting//   // this generates a separate chunk (about.[hash].js) for this route//   // which is lazy-loaded when the route is visited.//   component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')// }
]const router = new VueRouter({mode: 'history',base: process.env.BASE_URL,routes
})
export default router

组件内部的前置守卫

src\views\Admin\Admin.vue

<template><div><!-- 整个容器布局 --><el-container><!-- 左侧菜单 --><el-aside width="200px"><div class="logo"><div><img src="@/assets/logo.png" alt="" srcset=""></div><div>综合数据管理平台</div></div><!-- 菜单 --><!-- default-active 根据路由路径匹配 选中的对应的菜单高亮 --><el-menu router :default-active="$route.path" background-color="#001529" text-color="#ccc"><!-- index 开启router路由模式 会作为路由跳转的路径 --><el-menu-item index="/admin/dashboard"><!-- icon图标 菜单左侧 --><i class="el-icon-data-line"></i><span slot="title">控制台</span></el-menu-item><!-- <el-submenu index="/admin/user"><template slot="title"><i class="el-icon-location"></i><span slot="title">用户管理</span></template> --><!-- <el-menu-item index="4"><i class="el-icon-setting"></i><span slot="title">管理员管理</span></el-menu-item> --><el-menu-item index="/admin/user"><i class="el-icon-user"></i><span slot="title">会员管理</span></el-menu-item><!-- </el-submenu> --></el-menu></el-aside><!-- 右侧容器 --><el-container><!-- 头部 --><el-header>Header</el-header><!-- 主体 --><el-main><!-- 嵌套路由渲染容器 --><div><router-view></router-view></div></el-main><!-- 底部 --><el-footer>Footer</el-footer></el-container></el-container></div>
</template><script>
import { Message } from 'element-ui';
import url from '@/config/url';
import req from '@/utils/request'
export default {// 拦截操作 判断用户是否登录// 路由 组件内置守卫  内部获取不到组件的this 此时组件还未被创建beforeRouteEnter(to, form, next) {// 如果本地存储未报错token 肯定没有登录if (!localStorage.getItem('token')) {Message({message: '未登录,请先登录',type: 'error',duration: 1000,onClose: () => {// 跳转到登录界面next('/login')}})} else {// 校验token的有效性req.get(url.Profile).then(res => {console.log(res);if (res.data.code === 0) {// 存储管理员登录信息localStorage.setItem('username',res.data.data.username)} else {Message({message: '登录失效,重新登录',type: 'error',duration: 1000,onClose: () => {// 跳转到登录界面next('/login')}})}})next()}}
}
</script><style lang="scss" scoped>
.el-container {/* 设置容器的高度 */height: 100vh;
}.el-menu {/* 默认菜单右侧1px边框 去掉 */border-right: 0;
}.el-aside {background-color: #001529;color: #333;/* text-align: center; */
}.logo {height: 60px;display: flex;/* justify-content: space-around; */align-items: center;color: white;font-weight: bold;background-color: #001529;padding: 5px;>div:first-child {width: 40px;height: 40px;>img {width: 100%;}}>div:nth-child(2) {margin-left: 10px;}
}.el-main {background-color: #f5f5f5;>div {background-color: #fff;min-height: calc(100vh - 60px - 60px - 20px - 20px - 20px);margin-top: 20px;}
}.el-menu-item {height: 40px;line-height: 40px;margin: 5px 10px;border-radius: 10px;
}.el-menu-item.is-active {color: white !important;background-color: #1677ff !important;
}.el-header {background-color: #ffffff;text-align: center;line-height: 60px;
}.el-footer {background-color: #f5f5f5;text-align: center;line-height: 60px;
}
</style>

7、回车确认提交

mounted() {// 文档对象监听键盘事件   回车键document.onkeyup = (event) => {var e = event || window.eventif (e && e.keyCode == 13) {// console.log('回车')this.submitForm('ruleForm')}}},

相关文章:

  • 37、matlab矩阵运算
  • 【Unity】RPG2D龙城纷争(二)关卡、地块
  • 一个简单的R语言数据分析案例
  • centos7.6使用飞鱼FlyFish的docker镜像
  • 【GeoTransformer系列】——数据部分梳理(1)
  • 【源码】Spring Data JPA原理解析之事务注册原理
  • SHELL脚本学习(六) 呈现数据
  • 联想测开一面(电话面试)笔试60%
  • WPS JSA 宏脚本入门和样例
  • 【AI应用探讨】— GPT-4o模型应用场景
  • Synchronized 用过吗,其原理是什么???
  • 理解数学概念——线性(线性性)
  • Android: Null extracted folder for artifact: ResolvedArtifact(xxx 项目编译失败
  • Socket编程学习笔记之TCP与UDP
  • LabVIEW结构体内部缺陷振动检测
  • CentOS 7 修改主机名
  • JavaScript设计模式系列一:工厂模式
  • Java深入 - 深入理解Java集合
  • js中的正则表达式入门
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • Material Design
  • Mybatis初体验
  • vue的全局变量和全局拦截请求器
  • vue脚手架vue-cli
  • 高程读书笔记 第六章 面向对象程序设计
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 回流、重绘及其优化
  • 跨域
  • 全栈开发——Linux
  • 什么软件可以剪辑音乐?
  • 算法-图和图算法
  • 带你开发类似Pokemon Go的AR游戏
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • ​2021半年盘点,不想你错过的重磅新书
  • # Panda3d 碰撞检测系统介绍
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #define,static,const,三种常量的区别
  • #vue3 实现前端下载excel文件模板功能
  • (175)FPGA门控时钟技术
  • (arch)linux 转换文件编码格式
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (汇总)os模块以及shutil模块对文件的操作
  • (转)机器学习的数学基础(1)--Dirichlet分布
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException
  • .FileZilla的使用和主动模式被动模式介绍
  • .net 7 上传文件踩坑
  • .net core 6 redis操作类
  • .NET 发展历程
  • .net 微服务 服务保护 自动重试 Polly
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .net反编译工具
  • .NET轻量级ORM组件Dapper葵花宝典
  • :中兴通讯为何成功