1、如何解决vue第一次加载的时候 页面上使用的数据会闪烁
普通插值表达式插入数据:界面加载的时候会把节点直接挂载到文档树中,导致{{msg+"666"}}这个字符串会显示一下;vue对象生成data数据时候会去刷新界面,把{{msg+"666"}}字符串替换成结果字符串,导致界面第一次加载的时候会闪屏
解决方案:使用v-html、v-text指令操作,或者css中加[v-cloak] {display:none}
2、常用指令
(1)v-cloak:加上这个属性的标签相当于在构建虚拟节点的时候就会有这个属性,等data的数据生成的时候,这个标签会自动去掉这个属性,可以利用这个特性来在css中把这个元素在加载初期写样式(隐藏)
(2)v-html:按照html超文本格式往界面上插入文本==>innerHTML
(3)v-text:按照普通文本格式往界面上插入文本==>innerText
(4)v-pre:将插件表达式 双括号语法识别为普通文本
3、单向数据绑定
v-bind: 或 : 多用在标签属性值的数据绑定中
<a v-bind:href="link">baidu</a>
<a :href="link">baidu</a><br/>
<img v-bind:src="myimg" />
<img :src="myimg" />
4、事件绑定
v-on: 或 @
<button v-on:click="fn1">事件绑定1</button>
<button @click="fn2">事件绑定2</button>
事件修饰符:
- .stop 阻止事件传递,相当于event.stopPropagation()
- .prevent 阻止默认事件,相当于event.preventDefault()
- .capture 添加事件侦听器使事件在捕获阶段触发,相当于addEventListener监听器第三个参数设置true或false
- .self 其他元素的事件触发时,事件链经过它,无论是捕获还是冒泡阶段都不会触发它的事件,只有它自己是精准对象才会触 发事件,虽然它自己不会被别人影响,但是它自己的事件触发的时候还是会生成事件链经过其他元素,并不阻止继续冒泡到其他元素
- .once 事件只触发一次,触发完之后事件就解绑
5、双向数据绑定
v-model 用在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定,必须在组件的 data 选项中声明初始值。
单向数据绑定和双向数据绑定区别(重点!!!)
答:普通插值表达式{{msg}}就是单向数据绑定,我们只能通过代码去更新视图模型层VM中的的data数据从而更新视图层V,但是如果要实现用户更新视图层V的数据,视图模型层VM中的data数据自动更新,视图层也更新{{msg}}绑定的数据,比如我们要实现用户修改input表单,视图模型层VM中的data数据更新,页面也发生变化,我们有两种方法:
第一种就是通过单向绑定实现双向绑定的功能,给input绑定监听函数v-on:input="xxx",在绑定的函数里面通过this.msg = event.target.value去修改data中的msg数据,从而更新视图层显示。
第二种就是使用双向数据绑定v-model,双向数据绑定就是用户在视图层V中的修改会自动同步到视图模型层VM中的data数据,同样的,如果data数据的值发生了变化,也会立刻同步到视图层V中去。这样我们不用再绑定监听函数,视图模型层VM中的data更新了,视图层V也更新了,这就是双向绑定。
6、Vue双向数据绑定原理(重点!!!)
vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。
具体来说就是我们首先要设置一个监听器Observer,用来劫持并监听所有的属性。当数据发生变化,就发布消息告诉订阅者Watcher。因为订阅者是有很多个,所以我们需要有一个消息订阅器Dep来专门收集这些订阅者,然后在监听器Observer和订阅者Watcher之间进行统一管理的。当Observer监听到数据变化就通知Dep,Dep再去通知订阅者Watcher。同时,我们还需要一个解析器Compile,对每个节点元素进行扫描和解析,将相关指令对应初始化成一个订阅者Watcher,并给其绑定更新函数,此时当订阅者Watcher接收到相应数据的变化,就会执行对应的更新函数,从而更新视图。
js实现简单的双向绑定
<body>
<div id="app">
<input type="text" id="txt">
<p id="show"></p>
</div>
</body>
<script type="text/javascript">
var obj = {}
Object.defineProperty(obj, 'txt', {
get: function () {
return obj
},
set: function (newValue) {
document.getElementById('txt').value = newValue
document.getElementById('show').innerHTML = newValue
}
})
document.addEventListener('keyup', function (e) {
obj.txt = e.target.value
})
</script>
7、单页面的优缺点
优点:
- 用户体验好,快,内容的改变不需要重新加载整个页面,对服务器压力较小。
- 前后端分离,比如vue项目
- 完全的前端组件化,前端开发不再以页面为单位,更多地采用组件化的思想,代码结构和组织方式更加规范化,便于修改和调整;
缺点:
- 首次加载页面的时候需要加载大量的静态资源,这个加载时间相对比较长。
- 不利于 SEO优化,单页页面,数据在前端渲染,就意味着没有 SEO。
- 页面导航不可用,如果一定要导航需要自己建立堆栈管理。
8、前端性能优化方案
- 样式置顶,脚本置底;
- 减少http请求次数,使用精灵图等;
- 图片懒加载;
- 缓存Ajax请求的数据;
- 使用JSON作为数据格式;
- 尽量减少操作原生DOM元素,减少回流与重绘,使用Vue等去操作虚拟DOM树;
- 精简资源,压缩、合并CSS,JS文件。