前台使用Vue
前台搭建遇到问题
----前台访问量大 未采用vue 单页面SAP 的方式构建 使用多HTML构建页面
项目构建
- vue 2.6 https://cn.vuejs.org/
- elementUI https://element.eleme.cn/#/zh-CN
- animate.css https://animate.style/
- vue-lazyload https://www.npmjs.com/package/vue-lazyload
- axios http://www.axios-js.com/zh-cn/docs/
- iconfont https://www.iconfont.cn/
<!-- 引入iconfont icon字体 -->
<link rel="stylesheet" type="text/css" href="../../public/css/icon-font.css">
<!-- 引入elementUI样式 -->
<link rel="stylesheet" type="text/css" href="../../public/elementUI/elementUI.css">
<!-- Vue开发环境版本,包含了有帮助的命令行警告 -->
<script src="../../public/js/vue.js"></script>
<!-- animate 动画 -->
<link rel="stylesheet" type="text/css" href="../../public/css/animate.min.css">
<!-- vue 图片懒加载 -->
<script src="../../public/js/vue-lazyload.js"></script>
<!-- 引入elementUI组件库 -->
<script src="../../public/elementUI/elementUI.js"></script>
<!-- 引入axios -->
<script src="../../public/js/axios.min.js"></script>
V-lazyload 配置
Vue.use(VueLazyload, {
preLoad: 1.3,//图片占比
error: '../../public/img/error.png', //图片加载错误时显示图片
loading: '../../public/img/loading.png',//图片加载中的图片
attempt: 1 //加载失败重试次数
})
/*
其他属性
preLoad:类型Number,默认1.3. 表示lazyload的元素距离页面底部距离的百分比.计算值为(preload - 1).
attempt:图片加载失败后的重试次数.默认为3.
error:类型string.图片加载失败后的显示的失败图片路径.
loading:类型string.图片正在加载中显示的loading图片的路径.
listenEvents:类型array.默认['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend', 'touchmove'].即是在监听上述事件中,判断图片是否在preload的位置.如果你不想在那么多事件中判断,可以指定一个或者几个.例如如果你给这个属性只指定['touchmove'].那么scroll 屏幕不会加载图片,只有手指滑动屏幕才会加载图片.
adapter:注册img 的loading,loaded,error三个状态的回调函数,参数会暴露懒加载的img元素,可以对其进行操作.
filter: img未加载之前,解析到src 的时候注册的回调函数.可以在加载图片之前,对src进行修改.注册在filter下的所有的函数都会执行
*/
v-lazyload使用
<!---将 img 标签的:src 属性直接改为v-lazy, :key是为了防止刷新页面或图片更改时图片不更新-->
<img v-lazy="proImg" :key="imgKey">
问题
引入elementUI 后 elementUI 提供的 icon 无法加载
需要单独引入elementUI的字体文件 element-icons.ttf 和 element-icons.woff
https://unpkg.com/browse/element-ui@2.15.0/lib/theme-chalk/fonts/
animate最新版 动画无效问题
最新版类名进行了修改 需要给每个类名添加animate__
前缀
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
<div >
<button @click="show = !show">
Toggle render
</button>
<transition
name="custom-classes-transition"
enter-active-class="animate__animated animate__tada"
leave-active-class="animate__animated animate__bounceOutRight"
>
<p v-if="show">hello</p>
</transition>
</div>
Axios 异步与同步问题
一些页面初始化数据需要先请求服务接口 后渲染到页面上 由于axios 的then() 与catch()方法都是异步的 所以当数据响应完毕页面已经加载完毕 数据无法渲染都网页上所以需要将axios改为同步请求让页面等待请求响应完毕再渲染页面
异步GET
请求
// 为给定 ID 的 user 创建请求
axios.get('url')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
异步POST
请求
axios.post('url', {
params1: 'value',
params1: 'value'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
ES7的异步特性async / await
async用于申明一个函数是异步的,await等待异步请求完成,await只能在async方法中使用
let fun1 = async function(){
await axios.get(url,params);
...
}
例如一个获取全国行政区划的接口
https://huangshen.oss-cn-beijing.aliyuncs.com/miao-shop/json/CityList.json
//获取地址信息
async getCityList() {
this.cityList = await axios.get(
'https://huangshen.oss-cn-beijing.aliyuncs.com/miao-shop/json/CityList.json')
.then(function (response) {
return response.data
})
.catch(function (error) {
console.log(error);
});
},
this.cityList会等待get请求的响应 后赋值 整个等待过程页面也在等待 会出现卡一下
的现象
el-scrollbar 组件滚动底部
el-scrollbar 是elementUI 的一个组件 但在官方文档中没有介绍 这是一个滚动面板组件 在做聊天窗口是很方便
使用时要首先在全局css中设置
body .el-scrollbar__wrap {
overflow-x: hidden; /*隐藏X轴滚动条*/
overflow-y: hidden; /*隐藏Y轴滚动条*/
}
默认都是在滚动面板的顶部 聊天窗口一般都是至于底部置底方法
//聊天窗口滚动条置底
scrollDown(){
this.$refs.myScrollbar.wrap.scrollTop=this.$refs.myScrollbar.wrap.scrollHeight
}
注意1 这个方法必须在页面加载完毕数据更新时调用 使用vue 的updated()钩子函数
updated(){
this.scrollDown();
}
注意2
-
el-scrollbar的父层要有固定高度
-
el-scrollbar的高度要设成100%
-
如果出现横滚动条,添加overflow-x:hidden;
scrollbar
介绍
scrollbar
组件暴露了 native
, wrapStyle
, wrapClass
, viewClass
, viewStyle
, noresize
, tag
这7个 props属性
props: {
native: Boolean, // 是否使用本地,设为true则不会启用element-ui自定义的滚动条
wrapStyle: {}, // 包裹层自定义样式
wrapClass: {}, // 包裹层自定义样式类
viewClass: {}, // 可滚动部分自定义样式类
viewStyle: {}, // 可滚动部分自定义样式
noresize: Boolean, // 如果 container 尺寸不会发生变化,最好设置它可以优化性能
tag: { // 生成的标签类型,默认使用 `div`标签包裹
type: String,
default: 'div'
}
}
页面之间信息共享
网站公共信息全部存储于 sessionStorage,localStorage
中
操作sessionStorage,localStorage的方法
sessionStorage.getItem('key')
sessionStorage.setItem('key','value')
localStorage.getItem('key')
localStorage.setItem("key","value")
sessionStorage仅在当前会话下有效,关闭页面或浏览器后被清除。存放数据大小为一般为5MB,而且它仅在客户端(即浏览器)中保存。
localStorage生命周期是永久,这意味着除非用户显示在浏览器提供的UI上清除localStorage信息,否则这些信息将永远存在。存放数据大小为一般为5MB,而且它仅在客户端(即浏览器)中保存。
页面间跳转 与 刷新
HTML 跳转
在HTML页中,可以使用meta标签进入页面的跳转,此方法可以控制跳转的时间,以及自由化的定义跳转的网址
<meta http-equiv="refresh" content="5;url=https://www.baidu.com">
meta 标签中有一个content属性,表示打开此页面后,多少秒后开启跳转。还有个URL属性,表示跳转的网址
HTML中A标签跳转
HTML中的A标签也可以看做为页面跳转的一种,只是通过鼠标点击的方式进入跳转
<a href="http://www.baidu.com">跳转到百度</a>
javascript代码跳转
在网页利用js也可以实现页面的跳转或定时跳转
window.location.href = 'https://www.baidu.com/';
// 五秒以后再跳转
setTimeout("javascript:location.href='https://www.baidu.com'", 5000);
//在新的窗口打开页面
var tempwindow=window.open('_blank');
tempwindow.location='../search/search.html;
页面刷新
window.location.reload();
页面跳转传参
要在跳转路径中传递参数 可以使用“?”传参
window.location.href='../index/index.html?wd1=value&wd2=value';
- 传参时出现中文乱码问题
在js中通过window.location.href方式跳转页面并在路径上传递参数中文乱码解决 js中对中文进行编码:(不对ASCII 字母和数字进行编码) window.location.href = ‘aaa.html?Unit=’+encodeURI(encodeURI(中文内容)) //有时需要两次编码 window.location.href = ‘aaa.html?Unit=’+encodeURI(中文内容) //有时只需要编码一次即可(具体原因没有细究) 在接收页面接收的时候再解码回来即可 decodeURI(window.location.href)
接收参数
参数传递时使用? = & 作为分隔符去的时候使用字符串操作取出
//原始页
var tempwindow=window.open('_blank'); tempwindow.location='../search/search.html?'+encodeURI('wd=零食');
//跳转页
//解码url
const params= decodeURI(window.location.href).split("?")[1].split("&");
//params ="wd=零食"
页面title 设置
使用js设置网页title
document.title='与零食有关的商品'
检测登录的方法
判断是否登录的依据是检查sessionStorage,localStorage 是否存储有用户信息
每次在页面加载之前 进行检测
在vue 中使用vue的生命周期钩子函数 进行检测
created() {
},
mounted() {
},
如果是一些必须要登录才可以访问的页面 检测到未登录后 将页面跳转到登录页
created() {
const userInfo = sessionStorage.getItem("userInfo")
if (null === userInfo) {
this.isLogin = false
window.location.href = '../index/index.html';
} else {
this.isLogin = true
}
}
vue 生命周期
JSON对象 与JSON字符串之间的转换
//JSON 对象
const message=[
{
id:1,
context:'这是测试'
},
{
id:2,
context:'这也是测试'
}
]
//JSON 字符串
[{"id":1,"context":"这是测试"},{"id":2,"context":"这也是测试"}]
有时需要对json对象进行存储 例如向sessionStorage,localStorage 存储 如果将JSON对象存入 则会显示 [object Object],[object Object]
这是无法使用的,需要将对象转为String 字符串后进行存储
JSON字符串转换为JSON对象
1. const obj = eval('(' + str + ')');
2. const obj = str.parseJSON();
3. const obj = JSON.parse(str);
将JSON对象转化为JSON字符串
1. let str=obj.toJSONString();
2. let str=JSON.stringify(obj);
JavaScript eval() 函数
eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。该方法只接受原始字符串作为参数,如果 string 参数不是原始字符串,那么该方法将不作任何改变地返回。因此请不要为 eval() 函数传递 String 对象来作为参数。
Cookies
上面页面信息共享已经使用了sessionStorage,localStorage
但是经过使用发现这两个存储方式 若是页面跳转打开的新页面数据是可以共享的,若重新打开新的标签页则无法做到数据共享。那么就要使用cookies
当 web 服务器向浏览器发送 web 页面时,在连接关闭后,服务端不会记录用户的信息。
Cookie 的作用就是用于解决 "如何记录客户端的用户信息":
Cookie 以名/值对形式存储,如下所示:
username=Huang Shen
创建Cookie
创建cookie
document.cookie="username=huangshen";
添加过期时间 到Sun, 24 Jan 2021 06:14:05 GMT 时过期自动删除
document.cookie="username=huangshen; expires=Sun, 24 Jan 2021 06:14:05 GMT";
可以使用 path 参数告诉浏览器 cookie 的路径。默认情况下,cookie 属于当前页面。
document.cookie="username=huangshen; expires=Sun, 24 Jan 2021 06:14:05 GMT; path=/";
读取 Cookie
const cookie = document.cookie;
document.cookie 将以字符串的方式返回当前域名下所有的 cookie,类型格式: username=huangshen; username=huangshen1;username2=huangshen2
修改 Cookie
修改 cookie 类似于创建 cookie,旧的 cookie 将被覆盖。
document.cookie="username=huangshen1; expires=Sun, 24 Jan 2021 06:14:05 GMT; path=/";
删除 Cookie
只需要将cookie过期时间 设置 expires 参数为以前的时间 注意 ,删除时不必指定 cookie 的值
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
Cookie 封装
//设置cookie
function setCookie(name, value, time) {
var strsec = getsec(time);
var exp = new Date();
exp.setTime(exp.getTime() + strsec * 1);
document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString();
}
//这是有设定过期时间的使用示例:
//s20是代表20秒
//h是指小时,如12小时则是:h12
//d是天数,30天则:d30
function getsec(str) {
alert(str);
var str1 = str.substring(1, str.length) * 1;
var str2 = str.substring(0, 1);
if (str2 == "s") {
return str1 * 1000;
} else if (str2 == "h") {
return str1 * 60 * 60 * 1000;
} else if (str2 == "d") {
return str1 * 24 * 60 * 60 * 1000;
}
}
//读取cookies
function getCookie(name) {
var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
console.log(document.cookie);
if (arr = document.cookie.match(reg))
return unescape(arr[2]);
else
return null;
}
//删除cookies
function delCookie(name) {
var exp = new Date();
exp.setTime(exp.getTime() - 1);
var cval = getCookie(name);
if (cval != null)
document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
}
//使用示例
setCookie("name", "hayden", "s20");
getCookie("name");