新建vue.config.js

clone项目,vue create项目,在根目录下新建vue.config.js进行配置
把一下配置代码粘上去

const path = require("path");
//主要是用于分析项目的大小占比的,不需要的话可以注释掉
// const WebpackBundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {// 部署应用时的基本 URL//部署应用时的根路径(默认'/'),也可用相对路径(存在使用限制)cli3.0以上使用publicPath替代baseUrl,解决build后找不到静态资源的问题publicPath: process.env.NODE_ENV === "production" ? "../" : "",// build时构建文件的目录 构建时传入 --no-clean 可关闭该行为outputDir: process.env.NODE_ENV === "production" ? "../dist" : "dist", // 运行时生成的生产环境构建文件的目录(默认''dist'',构建之前会被清除)// build时放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录(默认'')assetsDir: "assets",// 指定生成的 index.html 的输出路径 (相对于 outputDir),也可以是一个绝对路径。indexPath: "index.html",// 默认在生成的静态资源文件名中包含hash以控制缓存filenameHashing: true,// 是否在开发环境下通过 eslint-loader 在每次保存时 lint 检查代码(在生产构建时禁用 eslint-loader)lintOnSave: process.env.NODE_ENV !== "production",// 是否使用包含运行时编译器的 Vue 构建版本runtimeCompiler: false,// 生产环境是否生成 sourceMap 文件,如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建productionSourceMap: false,// Babel 显式转译列表,暂时没有用到transpileDependencies: [],// 设置生成的 HTML 中 <link rel="stylesheet"> 和 <script> 标签的 crossorigin 属性(注:仅影响构建时注入的标签)crossorigin: "",// 在生成的 HTML 中的 <link rel="stylesheet"> 和 <script> 标签上启用 Subresource Integrity (SRI)integrity: false,// 构建多页面应用,页面的配置,一般用不到devServer: {//所有 webpack-dev-server 的选项都支持。//主要是用于交互接口的调试disableHostCheck: true,host: "0.0.0.0", //localhostport: 8080,https: false,hotOnly: false,open: true, //配置自动启动浏览器overlay: {//配置eslint报错的级别// warnings: true,// error: true},proxy: {// 配置多个代理(配置一个 proxy: 'http://localhost:4000' // 本地模拟数据服务器)// "/dd": {//     target: "http://10.64.88.27:8088/",//     ws: true,//     changeOrigin: true// },// "/dd": {//   target: "http://10.64.90.8:8088/",//10.64.90.46//   ws: true,//   changeOrigin: true// },"/dd": {target: "https://direct.cn", //431ws: true,changeOrigin: true,},},},// 如果这个值是一个对象,则会通过 webpack-merge 合并到最终的配置中// 如果你需要基于环境有条件地配置行为,或者想要直接修改配置,那就换成一个函数 (该函数会在环境变量被设置之后懒执行)。该方法的第一个参数会收到已经解析好的配置。在函数内,你可以直接修改配置,或者返回一个将会被合并的对象configureWebpack: (config) => {if (process.env.NODE_ENV === "production") {// 为生产环境修改配置...config.mode = "production";} else {// 为生产环境修改配置...config.mode = "development";}// 开发生产共同配置别名Object.assign(config.resolve, {alias: {"@": path.resolve(__dirname, "./src"),assets: path.resolve(__dirname, "./src/assets"),common: path.resolve(__dirname, "./src/common"),components: path.resolve(__dirname, "./src/components"),network: path.resolve(__dirname, "./src/network"),configs: path.resolve(__dirname, "./src/configs"),views: path.resolve(__dirname, "./src/views"),plugins: path.resolve(__dirname, "./src/plugins"),},});},// 对内部的 webpack 配置(比如修改、增加Loader选项)(链式操作)chainWebpack: (config) => {// if (IS_PROD) {//主要是对打包的文件生成配置,可以将某些引用的第三方插件单独打包出来config.optimization.splitChunks({minSize: 30000, //依赖包超过300000bit将被单独打包minChunks: 1, // 模块的最小被引用次数// maxAsyncRequests: 5, // 按需加载的最大并行请求数// maxInitialRequests: 3, // 一个入口最大并行请求数// automaticNameDelimiter: '~', // 文件名的连接符name: true,cacheGroups: {common: {name: "chunk-common", // 打包后的文件名chunks: "initial", //可选值有:'all'(所有代码块),'async'(按需加载的代码块),'initial'(初始化代码块)maxInitialRequests: 5,priority: 1, //缓存组打包的先后优先级,数值大的优先reuseExistingChunk: true, //如果当前代码块包含的模块已经有了,就不在产生一个新的代码块},vendors: {name: "chunk-vendors",test: /[\\/]node_modules[\\/]/,chunks: "initial",priority: 2,reuseExistingChunk: true,enforce: true,},antDesignVue: {name: "chunk-ant-design-vue",test: /[\\/]node_modules[\\/]ant-design-vue[\\/]/,chunks: "initial",priority: 3,reuseExistingChunk: true,enforce: true,},moment: {name: "moment",test: /[\\/]node_modules[\\/]moment[\\/]/,chunks: "initial",priority: 4,reuseExistingChunk: true,enforce: true,},coreJs: {name: "chunk-core-js",test: /[\\/]node_modules[\\/]core-js[\\/]/,chunks: "initial",priority: 5,reuseExistingChunk: true,enforce: true,},// styles: {//     name: 'styles',//     test: /\.(sa|sc|c)ss$/,//     chunks: 'all',//     enforce: true,// },},});// }},// css的处理// css: {//   // 当为true时,css文件名可省略 module 默认为 false//   modules: true,//   // 是否将组件中的 CSS 提取至一个独立的 CSS 文件中//   // 默认生产环境下是 true,开发环境下是 false//   //是否使用css分离插件 ExtractTextPlugin 开启CSS分离之后每个组件的css会单独打包,造成页面上有大量请求,所以在正式环境中将CSS分离关闭//   extract: process.env.NODE_ENV === "production",//   // 是否为 CSS 开启 source map。设置为 true 之后可能会影响构建的性能//   sourceMap: false,//   // requireModuleExtension: false,// 启用 CSS modules for all css / pre-processor files.//   //向 CSS 相关的 loader 传递选项(支持 css-loader postcss-loader sass-loader less-loader stylus-loader)//   //css预设器配置项//   loaderOptions: {//     sass: {//       prependData: '@import "./src/styles/main.scss";',//     },//     css: {},//     less: {//       javascriptEnabled: true,//     },//   },// },// 是否为 Babel 或 TypeScript 使用 thread-loader 一般用不到parallel: require("os").cpus().length > 1,// 向 PWA 插件传递选项 一般用不到pwa: {},// 可以用来传递任何第三方插件选项 一般用不到pluginOptions: {},
};

router重定向配置

const routes = [{path: "/",redirect: "login"},{path: "/login",name: "Home",component: () => import("../views/Login/index.vue"),},{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/About.vue"),},
];

CSS

开始在login里的index.vue里面写代码

.login {background-color: #344a5f;/* vh做单位,相当于可视区的百分比 */height: 100vh;
}


校验

用的elmm-ui
以下是src/utils/validate.js

/*** 过滤特殊字符*/
export function stripscript(str) {var pattern = new RegExp("[`~!@#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*( )——|{}【】‘;:”“'。,、?]");var rs = "";for (var i = 0; i < str.length; i++) {rs = rs + str.substr(i, 1).replace(pattern, "");}return rs;
}/*** 过滤邮箱*/
export function validateEmail(value) {const regEmail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/;return regEmail.test(value);
}/*** 验证密码,6至20位的字母+数字*/
export function validatePass(value) {const regPassword = /^(?!\D+$)(?![^a-zA-Z]+$)\S{6,20}$/;return regPassword.test(value);
}/*** 验证验证码,6位的字母+数字*/
export function validateVCode(value) {const regCode = /^[a-z0-9]{6}$/;return regCode.test(value);
}

以下是src/views/login/index.vue

<template><div class="login"><div class="login-wrap"><ul class="menu-tab"><li:class="{ current: item.current }"v-for="item in menuTab":key="item.id"@click="toggleMenu(item)">{{ item.txt }}</li></ul><el-form:model="ruleForm"status-icon:rules="rules"ref="ruleForm"class="login-form"size="medium"><el-form-item prop="username" class="item-form"><label>邮箱</label><el-inputtype="text"v-model="ruleForm.username"autocomplete="off"></el-input></el-form-item><el-form-item prop="password" class="item-form"><label>密码</label><el-inputtype="text"v-model="ruleForm.password"autocomplete="off"minlength="6"maxlength="20"></el-input></el-form-item><el-form-item prop="code" class="item-form"><label>验证码</label><el-row :gutter="10"><el-col :span="15"><el-inputv-model="ruleForm.code"minlength="6"maxlength="6"></el-input></el-col><el-col :span="9"><el-button type="success" class="block">获取验证码</el-button></el-col></el-row></el-form-item><el-form-item><el-buttontype="danger"@click="submitForm('ruleForm')"class="login-btn block">提交</el-button></el-form-item></el-form></div></div>
</template><script>
import {stripscript,validateEmail,validatePass,validateVCode,
} from "@/utils/validate";export default {name: "index.vue",data() {// 验证用户名为邮箱var validateUsername = (rule, value, callback) => {if (value === "") {callback(new Error("请输入用户名"));} else if (!validateEmail(value)) {callback(new Error("用户名格式有误"));} else {callback();}};// 验证密码var validatePassword = (rule, value, callback) => {this.ruleForm.password = stripscript(value);value = this.ruleForm.password;if (value === "") {callback(new Error("请输入密码"));} else if (!validatePass(value)) {callback(new Error("密码为6-20位数字+字母"));} else {callback();}};// 验证验证码var validateCode = (rule, value, callback) => {this.ruleForm.code = stripscript(value);value = this.ruleForm.code;if (value === "") {callback(new Error("请输入验证码"));} else if (!validateVCode(value)) {callback(new Error("验证码格式有误"));} else {callback();}};return {menuTab: [{ txt: "登录", current: true },{ txt: "注册", current: false },],ruleForm: {username: "",password: "",code: "",},rules: {username: [{ validator: validateUsername, trigger: "blur" }],password: [{ validator: validatePassword, trigger: "blur" }],code: [{ validator: validateCode, trigger: "blur" }],},};},methods: {toggleMenu(data) {this.menuTab.forEach((elem) => {elem.current = false;});data.current = true;},submitForm(formName) {this.$refs[formName].validate((valid) => {if (valid) {alert("submit!");} else {console.log("error submit!!");return false;}});},},
};
</script><style lang="scss" scoped>
.login {background-color: #344a5f;/* vh做单位,相当于可视区的百分比 */height: 100vh;
}
.login-wrap {width: 330px;margin: auto;
}
.menu-tab {text-align: center;li {display: inline-block;width: 88px;line-height: 36px;font-size: 14px;color: #fff;border-radius: 2px;cursor: pointer;}.current {background-color: rgba(0, 0, 0, 0.1);}
}
.login-form {margin-top: 29px;label {display: block;font-size: 14px;color: #fff;margin-bottom: 3px;}.item-form {margin-bottom: 13px;}.block {width: 100%;display: block;}.login-btn {margin-top: 19px;}
}
</style>

接口跨域拦截器

在src/api/login.js
在src/utils/request.js


路由跳转

<router-view />

将会默认显示

{path: "/console",name: "Console",component: () => import("../views/Layout/index.vue"),children: [{path: "/console",name: "Console",component: () => import("../views/Console/index.vue"),},],},

第一个children


子父组件传值

子组件

<template></template><script>export default {name: "SvgIcon",props: ['iconClass', 'className'],mounted() {console.log(this.iconClass + this.className)}}
</script><style lang="scss" scoped></style>
<template></template><script>export default {name: "SvgIcon",// props: ['iconClass', 'className'],props: {iconClass: {type: String, // 定义接收的值的类型default: 'qqqq', // 没传进来的时候,默认值为qqqqrequired: true, // 是否必须传validator: (value) => { // 校验return value >= 0}}},mounted() {console.log(this.iconClass + this.className)}}
</script><style lang="scss" scoped></style>

自创组件

import Vue from "vue";
import SvgIcon from "./SvgIcon"Vue.component('svg-icon',SvgIcon)const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => {console.log(requireContext.keys())return requireContext.keys().map(requireContext)
}
requireAll(req)

父组件

<svg-icon iconClass="menu" className="menu"></svg-icon>

传值,单向,不能反向修改,需要用watch监听


就是别去改那个父组件传过来的值就行了

子组件回调父组件的方法,回调的是父组件的属性


修饰器sync




因为修饰器直接更新属性的值,而不是去触发一个函数方法


浏览器端存储


Vuex 与 store.js






content指向的就是上面的state mutations等


路由跳转之前做什么事情


permision.js
只要路由改变,就会执行一次以下beforeEach函数

// 路由守卫
router.beforeEach((to, from, next) =>{console.log(to) // 进入的页面(下一个页面)console.log(next) // 离开之前的页面(上一个)
})
import router from "./index";
import { getToken } from "../utils/app";const whiteRouter = ["/login"]// 路由守卫
router.beforeEach((to, from, next) =>{if (getToken()){// 路由动态添加,分配菜单,每个角色分配不同的菜单console.log("存在")} else {console.log("不存在")if (whiteRouter.indexOf(to.path) !== -1) {next()} else {next("/login")}}console.log(to) // 进入的页面(下一个页面)console.log(next) // 离开之前的页面(上一个)next()
})



在utils里写一个app.js,用来存放token
next()里面不写参数,进入to的页面,然后不会再执行beforeEach


动画效果

p23 38分钟左右


全局方法







params.fn如果为true则不会跑后面那一个params.fn()


请求拦截器

封装请求头

service.interceptors.request.use(function (config) {// 在发送请求之前做些什么//  后端需要前端在请求头添加的数据config.headers['Token'] = getToken()config.headers['UserName'] = getUsername()return config;},function (error) {// 对请求错误做些什么return Promise.reject(error);}
);

vue中使用富文本编辑器





七牛云图片存储










vue组件思想


keep-alive组件缓存


实战——登陆注册管理后台相关推荐

  1. 登陆进管理后台的首页

    jsp的东西:jstl和el 请再看一边 登陆 login.jsp 两个input标签 一个checkbox选择 一个button提交 <input name> 属性用于对提交到服务器后的 ...

  2. django之二十二--admi管理后台页面的文案展示等相关配置

    一.前言 1.django提供的admin管理后台页面默认是英文展示的页面.我们不喜欢英文的话,可以改下[settings.py]里面的常量[LANGUAGE_CODE]的值为[zh-Hans]使页面 ...

  3. php注册登录模板,Phpcms V9 管理后台登陆及会员注册登录模板的修改方法

    一.怎么修改Phpcms V9管理后台登陆界面样式? 具体模板文件位置:phpcms/modules/admin/templates/login.tpl,打开查看到这一段代码: 复制代码代码如下: & ...

  4. 登录、注册、后台管理页面(动态)

    一.作业需求: 1.后台管理主界面(左边菜单框.(全选.反选)框.返回顶部按钮) 2.老男孩登录.注册页面 二.博客地址:https://www.cnblogs.com/catepython/p/93 ...

  5. 老男孩Day16作业:登录、注册、后台管理页面(动态)

    一.作业需求:1.后台管理主界面(左边菜单框.(全选.反选)框.返回顶部按钮)2.老男孩登录.注册页面二.博客地址:https://www.cnblogs.com/catepython/p/93063 ...

  6. Vue.js 3.0企业级管理后台开发实战:基于Element Plus UI

    Vue.js 3.0企业级管理后台开发实战:基于Element Plus UI - 每天更新 前言 文章内容 项目源码及课件 第1章 项目启动 1.1 项目原型 1.2 项目UI 1.3 项目开发流程 ...

  7. 新网服务器网站后台怎么登陆,新网域名管理后台

    在新网域名管理后台的系统中,您只需要拥有域名管理密码,即可以管理域名.域名证书的作用是证明域名所有权.如果您需要对网站进行备案时,需要提供给您的主机空间服务商.所有通过新网注册并交纳相应注册费用的用户 ...

  8. 实战新项目丨锋迷健康体检预约管理后台开发流程,速来围观

    原创作者:千锋文哥 一. 项目背景 锋迷健康管理系统是一款应用于健康管理机构的业务系统,实现健康管理机构工作内容可视化.会员管理专业化.健康评估数字化.健康干预流程化.知识库集成化,从而提高健康管理师 ...

  9. 微信小程序如何登陆管理后台并且绑定开发者账号?

    一 .微信公众号官网 1.输入网址:https://mp.weixin.qq.com/ 2.登陆公众号并且查看小程序登录邮箱 3.使用小程序邮箱账户登录,进入小程序管理后台 4.进入小程序管理后台 5 ...

最新文章

  1. 石墨烯区块链(6)开发实例
  2. mac能远程到wjn的linux,linux远程桌面vnc-server安装配置
  3. android+模拟器+ram,Android模拟器RAM修改方法 - 尤其是3.0
  4. 安卓与Linux共存,Android和Linux重新合并成一个操作系统
  5. Windows获取本机主机IP信息
  6. Laravel核心技术解析(1)—— Composer 组件管理与自动加载
  7. Spring中使用的九种设计模式
  8. 学会Zynq(15)UDP sendto函数的使用
  9. LTE相关协议2——下行峰值速率计算
  10. 用手机当电脑摄像头的方法
  11. TLS原理及证书生成
  12. 如何进行隐私协议测试
  13. 视频监控录像机默认端口 34567 修改为37420
  14. Excel Application对象应用
  15. JAVA#内部类'学习札记
  16. CC3200 Debug时报错:Unable to launch CCS debug-session based on current selection.的解决方法
  17. could not find java in ES_JAVA_HOME at /root/opt/elastic/elasticsearch-8.1.2/jdk/bin/java
  18. 微信公众平台测试帐号的注册与使用
  19. nodejs在Linux下使用图片相关模块出现Error: write EPIPE
  20. 新年伊始 沐圣moolsun强势来袭

热门文章

  1. 在Ubuntu上安装NTL库以及编译测试
  2. NTL密码算法开源库-大整数ZZ类(一)
  3. 作为一直火爆市场的二级分销,你知道哪些
  4. 树莓派frp内网穿透
  5. 一线大公司面试必备技能
  6. arcgis_随机数vb脚本
  7. GNU GRUBversion 2.04Minimal BASH-like line editing is supported.For the first word
  8. 实验题7.1 实现二分查找的算法
  9. 如何培养孩子的阅读兴趣
  10. 飞行汽车能顺利上天吗?