前端开发 直播课&公开课

腾讯课堂

慕课网

网易云课堂

一节课让你面试无惧vue响应式原理

  • Vue 2 的数据响应式原理
  • Vue 3 的数据响应式原理
  • Diff 算法和 virtual dom

什么是 defineProperty

defineProperty 其实是定义对象的属性
defineProperty 其实并不是核心的为一个对象做数据双向绑定,而是去给对象做属性标签,只不过属性里的 get 和 set 实现了响应式。

属性名 Second Header
value undefined
get undefined
set undefined
writable false
enumerable false
configurable false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var obj = {
a : 1,
b : 2
}

Object.defineProperty(obj,'a',{
writable : false,
enumerable : false,
configurable : false,
})
// getOwnPropertyDescriptor 返回指定对象上一个自有属性对应的属性描述符
console.log(Object.getOwnPropertyDescriptor(obj,'a'));

// output
// {value: 1, writable: false, enumerable: false, configurable: false}

面试加分技术点-ssr怎么做

什么是 ssr

传统的 vue 纯浏览器渲染

传统的 vue 纯浏览器渲染

这样渲染造成的影响
1、不利于SEO;搜索引擎优化
2、首屏问题;所有文件都要一次性加载完成,通过按需加载一定程度上缓解
3、性能问题;所有渲染都交给浏览器,造成浏览器性能下降。

ssr
ssr

1
2
3
4
5
6
7
8
9
10
11
12
const vue = require("vue");
const renderer = require('vue-server-renderer').createRenderer();
const app = new vue({
template: `<div>Hellow World<span>{{num}}</span></div>`,
data: {
num: 123
}
})
// 将 vue 变成字符串返回
renderer.renderToString(app).then(html => {
console.log(html);
})

node

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const vue = require('vue');
const server = require('express')();
const renderer = require('vue-server-renderer').createRenderer();
const fs = require('fs');

function createApp(url){
if(url == ''{
url = '/index'
})
}

// 读取对应的数据 数据存在 json 文件中
var json = fs.readFileSync(`json${url}.json`,'utf-8');
var tempalte = fs.readFileSync(`tempalte${url}.html`,'utf-8');

return new vue({
tempalte: tempalte,
data: JSON.parse('json').data
})

server.get("*",(req,res) => {
if(req.url != '/favicon.ico'){
const app = createApp(req.url);
renderer.renderToString(app).then(html => {
res.end(html);
})
}
})

server.listen(7070)

特性

每一次访问必须新建一个 vue 实例
只会触发组件的 beforeCreate 和 creatd 钩子,所以需要客户端 js。

自己动手搭建一个 ssr + vue 项目

ssr 需要哪些东西

ssr

vue ssr 框架 nuxt

分别打包好客户端和服务端
加 nginx 代理

vue高级实战技巧-骚操作和最佳实践

优化三字经:快(执行快)、小(文件小)、省(减少 http请求)。
缓存 - 是所有优化方案里,最常用,最有效的,可以节省 http 请求,可以从内存里最快读取数据

vue3 优化
1、优化 diff 对比
2、define 改为 proxy
3、100kb 到 30kb 函数编程

api 数据缓存
资源缓存是浏览器自动缓存

请求缓存思路

请求缓存思路

缓存架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//  main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'

// 1、缓存区域唯一、单一,参考单例模式。
// 2、缓存数据不能直接操作
// 3、缓存的问题 存在内存中 更新问题解决
// v8 标准 64 1.4g 32 0.7g

if(!window.mycache){
window.mycache = ( function (){
var cache = {}
var cacheArr = []
return {
get:function(api){
return new Promise((resolve,reject) => {
if(cache[api]){
resolve(cache[api])
}else{
this.set(api).then(()=>{
if(cacheArr.length == 1){
var _api = cacheArr.shift();
this.remove(_api);
}
cache[api] = res;
cacheArr.push(api);
resolve(res);
})
}
})
},
set:function(api){
return axios.get(api)
},
remove:function(){

}
}
})()
}

new Vue({
el: '#app',
router,
render: h => h(App)
})

vue 插件

Vue.use
原理:判断传入的东西有没有 install,有则执行 install,没有 install 并且传入的是一个方法的话执行传入的东西

Vue.mixin

插件
提供逻辑复用
注入自定义操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//  main.js
var a = {
install:function(vue){
// 生命周期混入
Vue.mixin({
beforeCreate:function(){
// this 指向当前组件
// 拿到当前组件 export default 的对象
// 异步加载 vuex
if(this.$options.isVuex){
var name = this.$options.name
import('./store/module'+name).then(res =>{
this.$store.registModule(this.$options.name,res.default)
})
}
},
data:function(){
return {
b: 123
}
},
methods: {
a:function(){

}
}
})
}
}
Vue.use(a);

vue 底层 api 运用

  • Vue.util.defineReative:把一个外部数据的改变能够触发 vue 的视图更新
    vue-router
    原理 hash 值改变 > 触发 vue-router 对象的 current 变量改变 > 触发视图更新

  • Vue.extend

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//  main.js
// 返回一个 vue 的构造
Vue.extend({})
// index.vue

// 调用 弹窗组件
<button @click="show('hello',$ref.cover)"></button>
<div ref = "cover">
</div>

// 组件
import pop from './components/pop.vue'
// 弹窗
Vue.mixin({
methods: {
show:function(mes,el){
const popContructor = Vue.extend(pop);
const vm = new popContructor();
vm.$data.mes = mes;
vm.$mount (el);
}
}
})

单元测试 > vue 某个组件的方法执行结果对不对,渲染结果 > 需要拿到 vue 的实例

extend:帮助我们跟 vue 没有关系的系统里能够拿到 vue 的组件实例,并且能够很好的模拟真实挂载状态

  • 利用 render 渲染

render 代替 template:提供用 js 描述 template复杂逻辑

1
2
3
render:function(h){
h("h" + this.level)
}

相关资料
深入响应式原理
[视频]网易高级前端开发系列直播课②
[视频]网易高级前端开发系列直播课④
[视频]网易高级前端开发系列直播课⑤
[视频]网易高级前端开发系列直播课⑥
[视频]网易高级前端开发系列直播课⑦
[视频]网易高级前端开发系列直播课⑧
[视频]网易高级前端开发系列直播课⑨
[视频]【网易】高级前端4天试学营9.21
[视频]【网易】高级前端4天试学营3
Vue服务器渲染器
Vue.js 服务器端渲染指南
前端权威0基础入门 + Web百大项目案例

You need to set client_id and slot_id to show this AD unit. Please set it in _config.yml.