腾讯课堂
慕课网
网易云课堂
一节课让你面试无惧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, })
console.log(Object.getOwnPropertyDescriptor(obj,'a'));
|
面试加分技术点-ssr怎么做
什么是 ssr
传统的 vue 纯浏览器渲染

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

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
| import Vue from 'vue' import App from './App.vue' import router from './router'
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
| var a = { install:function(vue){ Vue.mixin({ beforeCreate:function(){ 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 运用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
Vue.extend({})
<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 代替 template:提供用 js 描述 template复杂逻辑
1 2 3
| render:function(h){ h("h" + this.level) }
|
相关资料
深入响应式原理
[视频]网易高级前端开发系列直播课②
[视频]网易高级前端开发系列直播课④
[视频]网易高级前端开发系列直播课⑤
[视频]网易高级前端开发系列直播课⑥
[视频]网易高级前端开发系列直播课⑦
[视频]网易高级前端开发系列直播课⑧
[视频]网易高级前端开发系列直播课⑨
[视频]【网易】高级前端4天试学营9.21
[视频]【网易】高级前端4天试学营3
Vue服务器渲染器
Vue.js 服务器端渲染指南
前端权威0基础入门 + Web百大项目案例