前端的一些笔记
|字数总计:3.1k|阅读时长:14分钟|阅读量:|
CSS相关
div填充整个页面
1 2 3 4 5
| html, body { margin: 0; padding: 0; height: 100%; }
|
div位置移动
1 2 3 4 5
| .box-card1 { width: 520px; margin-left: 430px; margin-top: 140px; }
|
元素移动
style="float: left"
背景图填充整个div
1 2 3 4 5 6
| .login{ height: 100%; width: 100%; position: fixed; background-image: url("https://unpkg.com/nan-picture/img/3标签.jpg"); }
|
div添加下划线(阴影)
1 2 3
| .row-bg { border-bottom: medium solid #E0E0E0; }
|
更多介绍
控制字体行间距
1 2 3
| .i-info{ line-height: 28px; }
|
a标签字体去掉下划线
1
| <a href="/" style="text-decoration:none">
|
Js实现页面跳转
1
| <a shref='http://localhost:8181/download/2/web安全.md' download="web安全.md"></a>
|
例如a标签的跳转,可下载文件等。
1 2
| window.location.href = 'http://www.baidu.com' window.open('http://www.baidu.com')
|
Vue相关
Element的下拉菜单点击事件无反应
1
| <el-dropdown-item @click.native="out">退出</el-dropdown-item>
|
在@click后加.native
Vue中使用Cookie
安装:npm install js-cookie --save
在main.js中全局注册:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' import jsCookie from 'js-cookie'
Vue.prototype.$cookie = jsCookie;
Vue.config.productionTip = false
new Vue({ router, store, render: h => h(App) }).$mount('#app')
|
1
| this.$cookie.set("token",res.data.data)
|
注意:axios默认不携带cookie,需设置axios.defaults.withCredentials = true
在Vue中如何使用markdown编辑器
安装:npm install mavon-editor --save
在main.js中全局注册:
1 2 3 4 5 6
| import Vue from 'vue' import mavonEditor from 'mavon-editor' import 'mavon-editor/dist/css/index.css'
Vue.use(mavonEditor)
|
在页面使用组件即可:
1
| <mavon-editor v-model="ruleForm.content"></mavon-editor>
|
效果如下:
对于后台请求过来的markdown格式文章如何解析:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| template中使用该组件: :value是要展示的markdown格式内容 <mavon-editor :value="this.blog.content" :subfield="prop.subfield" :defaultOpen="prop.defaultOpen" :toolbarsFlag="prop.toolbarsFlag" :editable="prop.editable" :scrollStyle="prop.scrollStyle" ></mavon-editor>
script中添加该组件相关的计算属性: computed: { prop () { let data = { subfield: false, defaultOpen: 'preview', editable: false, toolbarsFlag: false, scrollStyle: true } return data } },
|
更多配置看mavonEditor的Github
Element UI导航菜单组件双击报错解决
1 2 3 4 5 6 7 8 9 10 11 12 13
| import Vue from 'vue' import VueRouter from 'vue-router'
Vue.use(VueRouter)
const originalPush = VueRouter.prototype.push VueRouter.prototype.push = function push(location) { return originalPush.call(this, location).catch(err => err) }const originalPush = VueRouter.prototype.push VueRouter.prototype.push = function push(location) { return originalPush.call(this, location).catch(err => err) }
|
前端路由权限拦截
- 我们后台的操作界面需要登录后才可以访问,所以我们在路由映射的meta里配置该路由是否需要权限才能访问:requireAuth: true/false
- 用户登录成功时通过设置sessionStorage(存储客户端临时信息的对象)标志该用户已登录:
sessionStorage.setItem('isLogin',true)
。
- 一旦所有窗口或标签页被关闭,那么所有通过sessionStorage存储的数据也就被清空了。
- 通过全局前置守卫,判断每次将要进入的路由是否需要权限,如果不需要权限或需要权限且已经登录,那么直接放行,否则重定向到登录页面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| const routes = [ ... { path: '/login', component: () => import("../views/Login"), meta: { title: "管理员登录" } }, { path: '/manage', component: () => import("../views/Manage"), children: [ { path: '', redirect: 'editTable' }, { path: 'editTable', component: () => import("../components/EditTable"), meta: { title: "后台管理", requireAuth: true } ] } ]
const router = new VueRouter({ routes, mode: 'history' })
router.beforeEach((to, from, next) => { if (to.meta.requireAuth) { const isLogin = sessionStorage.getItem("isLogin") if (isLogin) { next() } else { next({ path: '/login' }) } } else { next() } })
|
为了优化用户体验,避免多次登录,我们可以设置跳转登录页面的方法为:
1 2 3 4 5
| if (sessionStorage.getItem("isLogin")){ this.$router.push('/manage') }else { this.$router.push('/login') }
|
一刷新页面vuex的state数据丢失
因为store里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,store里面的数据就会被重新赋值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <template> <div id="app"> <router-view></router-view> </div> </template>
<script> export default { name: 'App', created() { //在页面加载时读取sessionStorage里的状态信息 if (sessionStorage.getItem("store")) { this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem("store")))) }
//在页面刷新时将vuex里的信息保存到sessionStorage里 window.addEventListener("beforeunload", () => { sessionStorage.setItem("store", JSON.stringify(this.$store.state)) }) } } </script> <style> html, body { margin: 0; padding: 0; height: 100%; } </style>
|
Element 侧边栏、头部固定
1 2 3 4 5 6 7
| <el-container> <el-header>Header</el-header> <el-container> <el-aside width="200px">Aside</el-aside> <el-main>Main</el-main> </el-container> </el-container>
|
布局如上,要求当el-main长度过长时可以滚动,但是顶部和侧边固定,添加如下样式即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| .el-aside { display: block; position: absolute; left: 0; top: 60px; bottom: 0; } .el-main { position: absolute; left: 200px; right: 0; top: 60px; bottom: 0; overflow-y: scroll; }
|
Element 路由刷新和导航栏菜单状态保持一致
当网页刷新或回退时,导航栏的当前激活菜单与路由地址不匹配。我们可以通过侦听器(watch)侦听路由地址的变化使它们一致:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| <template> <div> <el-menu :default-active="activeIndex" router class="el-menu-vertical-demo" > <el-menu-item index="/center/homePage"> <i class="el-icon-s-home"/> <span slot="title">首页</span> </el-menu-item> <el-menu-item index="/center/notesPage"> <i class="el-icon-notebook-2"/> <span slot="title">笔记</span> </el-menu-item> </el-menu> </div> </template>
<script> export default { name: "SideBar", data() { return { activeIndex: "/center/homePage" } }, watch: { $route () { this.setCurrentRoute() } }, methods: { setCurrentRoute () { this.activeIndex = this.$route.path }, }, created () { this.setCurrentRoute() }, } </script>
<style scoped> </style>
|
另外一种,适用于一个菜单包含多个地址的,比较实用的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| <template> <div> <el-menu :default-active="activeIndex" class="el-menu-vertical-demo"> <el-menu-item index="1" @click="toHomePage"> <i class="el-icon-s-home"/> <span slot="title">首页</span> </el-menu-item> <el-menu-item index="2" @click="toCoursePage"> <i class="el-icon-reading"/> <span slot="title">课程</span> </el-menu-item> <el-menu-item index="3"> <i class="el-icon-message-solid"/> <span slot="title">通知</span> </el-menu-item> <el-menu-item index="4" @click="toNotesPage"> <i class="el-icon-notebook-2"/> <span slot="title">笔记</span> </el-menu-item> <el-menu-item index="5"> <i class="el-icon-chat-dot-square"/> <span slot="title">讨论</span> </el-menu-item> </el-menu> </div> </template>
<script> export default { name: "SideBar", data() { return { activeIndex: '1', path: '' } }, methods: { setCurrentRoute() { this.path = this.$route.path if (this.path === '/center/homePage') { this.activeIndex = '1' } else if (this.path === '/center/course') { this.activeIndex = '2' } else if (this.path.includes('ote')) { this.activeIndex = '4' } }, toHomePage() { this.$router.push('/center/homePage') }, toCoursePage() { this.$router.push('/center/course') }, toNotesPage() { this.$router.push('/center/notesPage') }, }, watch: { $route() { this.setCurrentRoute() } }, created() { this.setCurrentRoute() } } </script>
<style scoped> </style>
|
Element中竖向分割线长度调整
f12检查元素,复制样式到vue文件中进行修改
1 2 3 4 5 6 7 8 9 10
| <style scoped> .el-divider--vertical { display: inline-block; width: 1px; height: 9em; margin: 0 8px; vertical-align: middle; position: relative; } </style>
|
在Vue中使用阿里矢量图标
https://www.iconfont.cn/
将想要的图标添加至自己的项目中,在项目里点击symbol,查看在线链接,例如://at.alicdn.com/t/font_2372769_xa9myt9i5o.js
浏览器访问该链接,在项目src/assets下新建iconfont.js文件,并将所有代码复制到js文件中
在App.vue中引入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <script> import './assets/iconfont.js' ... </script> <style> .icon { width: 1em; height: 1em; vertical-align: -0.15em; fill: currentColor; overflow: hidden; } </style>
|
使用如下:
1 2 3
| <svg class="icon" aria-hidden="true" style="font-size: 33px"> <use xlink:href="#icon-gonggao1"></use> </svg>
|
官方文档的symbol方式如下:
symbol引用
这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章 这种用法其实是做了一个svg的集合,与上面两种相比具有如下特点:
- 支持多色图标了,不再受单色限制。
- 通过一些技巧,支持像字体那样,通过
font-size
,color
来调整样式。
- 兼容性较差,支持 ie9+,及现代浏览器。
- 浏览器渲染svg的性能一般,还不如png。
使用步骤如下:
第一步:拷贝项目下面生成的symbol代码:
第二步:加入通用css代码(引入一次就行):
1 2 3 4 5 6 7 8
| ><style type="text/css"> .icon { width: 1em; height: 1em; vertical-align: -0.15em; fill: currentColor; overflow: hidden; } ></style>
|
第三步:挑选相应图标并获取类名,应用于页面:
1 2 3
| ><svg class="icon" aria-hidden="true"> <use xlink:href="#icon-xxx"></use> ></svg>
|
Element 中修改默认样式无效
第一种:使用深度作用选择器: /deep/
1 2 3 4 5
| <style scoped> .el-card__body /deep/ { padding: 0px; } </style>
|
第二种:使用父级类名加>>> 深入符号直接强制更改
1.在父元素中写一个类名
2.然后通过f12审查元素找到子级默认样式的类名:
3.为不改变全局样式,使用父级类名加>>> 深入符号直接强制更改,即可完成效果:
浏览器控制台关于sockjs.js报错
错误如下:sockjs.js?9be2:1606 GET http://192.168.43.226:8080/sockjs-node/info?t=1584966826465 net::ERR_CONNECTION_TIMED_OUT
网上找到的原因说是:sockjs-node
是一个JavaScript库,提供跨浏览器JavaScript的API,创建了一个低延迟、全双工的浏览器和web服务器之间通信通道。在项目运行以后,network会一直调用这个接口。如果没有使用,那么就一直会报这个异常。
解决方法:
1)找到/node_modules/sockjs-client/dist/sockjs.js文件
2)在1600行左右,注释掉self.xhr.send(payload);
这一行,然后就可以解决了。
VUE表单验证报错(’validate’ )
报错如下:
1
| [Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'validate' of undefined"
|
解决:refs和ref名字保持一致,如果不行可以把refs后面的[ ]去掉试试
1 2 3 4
| <el-form :model="unitForm" ref="unitForm" label-width="100px" class="demo-dynamic"> ... submitForm(unitForm) { this.$refs.unitForm.validate((valid) => {
|
VUE表单验证报错(有值却报错)
Form表单验证踩坑(表单验证明明有值,却提示错误)
prop对应的不单单是rules规则里面的验证项,同时对应着我们form-item下的v-model的值。prop绑定的类要与el-form-item下的v-model的值相对应。
我是因为rules绑定了数组的某个字段而失败,修改后(注意prop的值):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <el-form-item v-for="(unit, index) in unitForm.units" :label="'第' + (index+2) + '章'" :key="index" :prop="`units[${index}].unitName`" :rules="{required: true, message: '章节名称不能为空', trigger: 'blur'}"> <el-input v-model="unit.unitName" style="width: 270px"></el-input> <el-button @click.prevent="removeUnit(unit)" style="margin-left: 20px">删除</el-button> </el-form-item>
...
data() { return { unitForm: { units: [{ unitId: '', unitName: '' } ], unit1: { unitId: '1', unitName: 'dwqqw' } } }; },
|
Element中抽屉去除标题自带蓝色框
1 2 3
| /deep/ :focus { outline: 0; }
|