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() }) } } }
完成 !
实现思路非常简单,就是请求数据之前将遮罩显示,加载数据完成后将遮罩隐藏
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。