8.前端router跳转页面query传值,刷新浏览器数据丢失
1.首先在页面A把传递的对象转json字符
that.$router.push({
path:'/B',
query:{
user: JSON.stringify(data), // 这里转成json字符串就行了
name: name // 这是个字符串
}
})
2.在页面B接收数据的时候转成json对象就行了
user: JSON.parse(this.$route.query.user), // 这里转成json对象
name: this.$route.query.name
7.导航栏菜单点击后高亮显示
<ul id="tabs_nav">
<li><a href="a.html" class="active"></a></li>
<li><a href="b.html"></a></li>
<li><a href="c.html"></a></li>
<li><a href="d.html"></a></li>
</ul>
实现:判断a标签中href属性与当前窗口URL是否匹配,匹配则给其添加样式。
js代码
//获取div下面所有的a标签(返回节点对象)
var myNav = document.getElementById("tabs_nav").getElementsByTagName("a");
//获取当前窗口的url
var myURL = document.location.href;
//循环div下面所有的链接,
for(var i=1;i<myNav.length;i++){
//获取每一个a标签的herf属性
var links = myNav[i].getAttribute("href");
var myURL = document.location.href;
//查看div下的链接是否包含当前窗口,如果存在,则给其添加样式
if(myURL.indexOf(links) != -1){
myNav[i].className="active";
myNav[0].className="";
}
}
6.回到顶部
创建toTop组件
<template>
<div class="toTop"
@click="backToTop"
v-show="visible">
<span class="el-icon-caret-top"></span>
</div>
</template>
<script>
export default {
name: 'toTop',
//定义一些父组件的配置项
props: {
visibilityHeight: { // 纵向滑动多远距离出现滚动条
type: Number
},
backPosition: { // 返回顶部时,滚动到哪里(距离顶部的距离)
type: Number,
default: 0
}
},
data () {
return {
//默认按钮不出现
visible: false,
//定义定时器
interval: null
}
},
//监听页面滚动
mounted() {
window.addEventListener('scroll', this.handleScroll)
},
//销毁定时器
beforeDestroy() {
window.removeEventListener('scroll', this.handleScroll)
if(this.interval) {
clearInterval(this.interval)
}
},
methods: {
handleScroll() {
this.visible = window.pageYOffset > this.visibilityHeight
},
//点击回到顶部
backToTop() {
let distanceY = window.pageYOffset
let i = 0
this.interval = setInterval(() => {
let next = Math.floor(this.easeInOutQuad(10 * i, distanceY, -distanceY, 500))
if(next <= this.backPosition) {
window.scrollTo(0, this.backPosition)
clearInterval(this.interval)
} else{
window.scrollTo(0, next)
}
i++
}, 17)
},
/*
缓动公式(Tween算法)
t: 动画已经执行的时间(实际上时执行多少次/帧数)
b: 起始位置
c: 终止位置
d: 从起始位置到终止位置的经过时间(实际上时执行多少次/帧数)
http://www.cnblogs.com/mrsunny/archive/2011/06/21/2086080.html
*/
easeInOutQuad(t, b, c, d) {
// 判断当前时间是否总在总时间的一半以内,是的话执行缓入函数,否则的话执行缓出函数
if ((t /= d / 2) < 1) {
return c / 2 * t * t + b
} else {
// 将总长度设置为一半,并且时间从当前开始递减,对图像进行垂直向上平移
return -c / 2 * (--t * (t - 2) - 1) + b
}
}
}
}
</script>
<style scoped>
.toTop{
position: fixed;
right: 70px;
cursor: pointer;
bottom: 150px;
width: 40px;
height: 40px;
text-align: center;
line-height: 40px;
font-size: 20px;
color: #0080EC;
background: #FFFFFF;
z-index: 99999999;
box-shadow: 0px 0px 4px 4px #ecefef;
border-radius: 600px;
}
</style>
全局定义组件-main.js
// 回到顶部
import toTop from '@/components/toTop'
Vue.component('toTop',toTop)
5.VUE识别访问设备是pc端还是移动端
创建util.js文件
export const checkMobile = () => {
const sUserAgent = navigator.userAgent;
const mobileAgents = [
"Android",
"iPhone",
"Symbian",
"WindowsPhone",
"iPod",
"BlackBerry",
"Windows CE",
];
let isMoblie = false;
for (let i = 0; i < mobileAgents.length; i++) {
if (sUserAgent.indexOf(mobileAgents[i]) > -1) {
isMoblie = true;
break;
}
}
return isMoblie;
};
在router.js文件中引用util.js文件
import {checkMobile} from '../store/util'
根据判断结果显示对应的页面
/* 网站 */
{
path: '/home',
name: 'home',
meta: {
title: '首页'
},
component: () => {
if (checkMobile()) return import('../views/mobile/m_home');// 移动端首页
return import('../views/website/homePage')// pc端首页
}
},
4.点击div的时候,改变背景色
<style>
.active{
color:red;
}
</style>
<ul>
<li v-for="(item,index) in divData" @click="liClick(index)" :class="{active:currentIndex === index}">
{{index}}{{item}}
</li>
</ul>
<script>
data: {
divData: ['海王','海贼王','加勒比海盗','海尔兄弟'],
currentIndex:0,// 记录状态的变量
},
methods: {
liClick(index) {
this.currentIndex = index;
}
}
</script>
3.Vue路由切换后, 页面滚动位置不变BUG处理
监听路由
直接在app.vue监测路由变化, 让body的滚动距离scrollTop=0/ scrollTo(0,0)
export default {
watch: {
$route: function(to, from) {
window.scrollTo(0,0);
//document.body.scrollTop = 0;
//document.documentElement.scrollTop = 0;
},
},
};
2.Blob 对象转换为 Base64 字符串
您可以使用以下代码将一个 Blob 对象转换为 Base64 字符串:
function blobToBase64(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(blob);
});
}
// 示例用法
const blob = new Blob(['Hello, World!'], { type: 'text/plain' });
blobToBase64(blob)
.then(base64String => {
console.log(base64String);
})
.catch(error => {
console.error(error);
});
1.el-menu相关问题
1.菜单动态渲染(一二级菜单)
<template v-for="i in navList">
//判断菜单中有没有children
<el-menu-item v-if="!i.children" :key="i.path" :index="i.path">
<i :class="i.icon"></i>
<span slot="title">{{i.label}}</span>
</el-menu-item>
<el-submenu v-else :index="i.path" :key="i.path ">
<template slot="title">
<i class="el-icon-location"></i>
<span>{{i.label}}</span>
</template>
<el-menu-item
v-for="child in i.children"
:key="child.path"
:index="child.path">
{{child.label}}
</el-menu-item>
</el-submenu>
</template>
data结构
data () {
return {
navList: [
{
path: '/DocumentManage',
label: '档案管理',
icon: 'el-icon-s-order',
children: [
{
path: '/DocumentManage',
label: '档案列表',
icon: 'el-icon-s-order'
}
]
},
{
path: '/UserData',
label: '用户档案',
icon: 'el-icon-s-custom'
}
]
}
}
2.多层菜单渲染
思路:
渲染一个多级菜单的过程实际上就是对后端给我们的多层数据格式进行循环遍历的一个过程,只是在遍历的过程中,需要对是否submit-menu和普通el-menu-item进行判断。
创建MenuTree组件
src/components/MenuTree.vue
// 以下是组件内容
<template v-for="menu in menuList">
<!-- 如果当前有子菜单,则显示 el-submenu ,在el-subment 里调用 递归组件 -->
<el-submenu
v-if="menu.children && menu.children.length > 0"
:index="menu.path"
:key="menu.id"
>
<template slot="title">
<i :class="menu.icon"></i>
{{ menu.menuName }}
</template>
<!-- 调用自身 此处是重点-->
<MenuTree :menuList="menu.children"></MenuTree>
</el-submenu>
<!-- 如果没有子菜单,则显示当前内容 -->
<el-menu-item v-else :index="menu.path" :key="menu.id">
<i :class="menu.icon"></i>
{{ menu.menuName }}
</el-menu-item>
</template>
export default {
name: 'MenuTree',
props: {
menuList: { // 在这里增加了引入校验,方便错误排除
type: Array,
required: false
}
}
}
3.el-menu常见属性设置
<el-menu
:collapse-transition="false" //关闭折叠动画
:collapse="isCollapse" //开启折叠收起
:router="true" // 是否使用 vue-router 的模式,启用该模式会在激活导航时以 index 作为 path 进行路由跳转
:default-active="$route.path" //当前激活菜单的 index 保持高亮
unique-opened //是否只保持一个子菜单的展开
class="el-menu-vertical-demo"
background-color="rgb(23, 38, 71)"
text-color="#fff"
active-text-color="rgb(0, 120, 215)">
...
</el-menu>
4.侧边栏折叠与展开功能
在头部添加一个折叠图标
<el-container>
<--侧边栏-->
<el-aside width="200px">
<!-- 侧边栏菜单区域 -->
<el-menu background-color="#333744" text-color="#fff"
active-text-color="#409BFF" :unique-opened="true">
<!-- 代码省略... -->
</el-aside>
<el-container>
<el-header>
<i class="el-icon-s-unfold"></i>
</el-header>
<el-main>Main</el-main>
</el-container>
</el-container>
el-menu设置“collapse”属性,并绑定一个动态值:
<el-menu background-color="#333744" text-color="#fff"
active-text-color="#409BFF" :unique-opened="true"
:collapse="isCollapse">
然后再数据区定义这个动态值,名为“isCollapse”,默认为false:
data(){
return {
isCollapse: false
}
}
给图标添加点击事件,根据isCollapse的值来更改展开图标和折叠图标
<i :class="isCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold'" @click="isCollapse = !isCollapse"></i>
因侧边栏的宽度是写死的200px导致折叠后侧边栏没有缩进,我们可以在isCollapse值为true的时候(折叠状态),将侧边栏的宽度缩小(折叠的宽度大概是64px),然后isCollapse值为false的时候,侧边栏宽度恢复为200px。
设置el-aside属性为一个动态结果,里面是一个“?:”条件运算符
<!-- 侧边栏 -->
<el-aside :width="isCollapse ? '64px' : '200px'">
<!-- 代码省略... -->
<el-aside>