vue.js数据加载完成前显示原代码{{代码}}问题及解决
作者:美奇开发工作室
vue.js数据加载完成前显示原代码{{代码}}
分析原因
首先了解HTML的加载顺序:
解析html结构 → 加载外部脚本和样式表文件 → 解析并执行脚本代码 → 构造html dom模型 → 加载图片等外部文件 → 页面加载完毕
得出结论:
通过以上分析可知,当html加载的时候,就会把{{代码}} 当成文本加载出来,当vue初始化完成后,才会把{{代码}}解析成vue的语法。如果把引入vue.js的script放到head里面,那页面不会出现{{代码}},因为在body之前就把vue引入进来了,vue加载完成了。
解决方法
1、方式一:使用 v-cloak指令
<div v-cloak>{{msg}}</div>2、方式二:使用 v-html指令
<div v-html='msg'></div>
3、方式三:使用 v-text指令
<div v-text='msg'></div>
4、方式四:使用template标签将需要渲染的html包起来
HTML的 <template> 元素是一种用于保存客户端内容的机制,该内容在页面加载时不被渲染,但可以在运行时使用JavaScript进行实例化。
<div id="app"></div>
<!--此处template标签必须在vue绑定的元素外面定义,并且在页面中不显示下面的template标签中的内容-->
<template id="demo">
<div v-if="flag">{{msg}}<div>
<div v-else>无数据<div>
</template>
<script src="./js/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
msg:"hello world",
flag:true
},
template:"#demo"//通过该属性可以将自定义的template属性中的内容全部替换app的内容,并且会覆盖里面原有的内容,并且在查看dom结构时没有template标签
});
</script>vue数据未加载完成前显示loading遮罩
目的
在前后端分离项目中,由于页面请求和数据请求并非同步,所以导致页面和数据不能同时渲染,因此在实际过程中往往采用SSR即服务端渲染或者请求数据时采用遮罩(加载中)的方式提升用户体验。
下面我将使用loading遮罩的方式实现更加友好的数据加载
参考:https://codepen.io/bartezic/pen/ByqeNq
效果

代码
1.在App.vue中添加一个<div>
<div>
<div id="appLoading">
<div class='lmask'></div>
</div>
<div id="app">
<router-view v-if="isRouterAlive"/>
</div>
</div>2.以下是CSS样式
.lmask {
position: absolute;
height: 100%;
width: 100%;
background-color: #000;
bottom: 0;
left: 0;
right: 0;
top: 0;
z-index: 9999;;
opacity: 0.4;
&.fixed {
position: fixed;
}
&:before {
content: '';
background-color: rgba(0,0,0,0);
border: 5px solid rgba(0,183,229,0.9);
opacity: .9;
border-right: 5px solid rgba(0,0,0,0);
border-left: 5px solid rgba(0,0,0,0);
border-radius: 50px;
box-shadow: 0 0 35px #2187e7;
width: 50px;
height: 50px;
-moz-animation: spinPulse 1s infinite ease-in-out;
-webkit-animation: spinPulse 1s infinite linear;
margin: -25px 0 0 -25px;
position: absolute;
top: 50%;
left: 50%;
}
&:after {
content: '';
background-color: rgba(0,0,0,0);
border: 5px solid rgba(0,183,229,0.9);
opacity: .9;
border-left: 5px solid rgba(0,0,0,0);
border-right: 5px solid rgba(0,0,0,0);
border-radius: 50px;
box-shadow: 0 0 15px #2187e7;
width: 30px;
height: 30px;
-moz-animation: spinoffPulse 1s infinite linear;
-webkit-animation: spinoffPulse 1s infinite linear;
margin: -15px 0 0 -15px;
position: absolute;
top: 50%;
left: 50%;
}
}
@-moz-keyframes spinPulse {
0% {
-moz-transform:rotate(160deg);
opacity: 0;
box-shadow: 0 0 1px #2187e7;
}
50% {
-moz-transform: rotate(145deg);
opacity: 1;
}
100% {
-moz-transform: rotate(-320deg);
opacity: 0;
}
}
@-moz-keyframes spinoffPulse {
0% {
-moz-transform: rotate(0deg);
}
100% {
-moz-transform: rotate(360deg);
}
}
@-webkit-keyframes spinPulse {
0% {
-webkit-transform: rotate(160deg);
opacity: 0;
box-shadow: 0 0 1px #2187e7;
}
50% {
-webkit-transform: rotate(145deg);
opacity: 1;
}
100% {
-webkit-transform: rotate(-320deg);
opacity: 0;
}
}
@-webkit-keyframes spinoffPulse {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}3.此时遮罩层显示,我们需要当App加载完成后取消遮罩层,即display: none
document.getElementById('app').style.display = 'block';
document.getElementById('appLoading').style.display = 'none';4.如何在我们需要的地方调用呢
我采用的方法是写一个loading和loaded函数,在分别在请求数据前和请求数据完成后调用,因为该功能可能会重复的使用,所以将其封装成为一个可以复用的模块
在App.vue中写两个方法:
provide() {
return {
loading: this.loading,
loaded: this.loaded
}
},
methods: {
loading() {
document.getElementById('app').style.display = 'block';
document.getElementById('appLoading').style.display = 'block';
},
loaded() {
document.getElementById('app').style.display = 'block';
document.getElementById('appLoading').style.display = 'none';
}
}上面将这两个函数给暴露了出来,在我们需要的地方inject就好
5. 在需要使用的地方调用
export default {
inject: ['loading', 'loaded'],
name: "index",
created() {
this.getData()
},
methods: {
getData() {
this.loading()
getUserInfo().then(res => {
this.userInfo = res.data
}).finally(() => {
this.loaded()
})
}
}
}完成 !
实现思路非常简单,就是请求数据之前将遮罩显示,加载数据完成后将遮罩隐藏
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
