中国在数码网站注册域名好>,长春网站设计策划,python登录wordpress,搜索引擎优化通常要注意的问题有( )# 源码结构 源码位置是在packages文件件内#xff0c;实际上源码主要分为两部分#xff0c;编译器和运行时环境 1. 编译器 compiler-core 核心编译逻辑compiler-dom 针对浏览器平台编译逻辑compiler-sfc 针对单文件组件编译逻辑compiler-ssr 针对服务端渲染编译逻辑 2. 运行时… # 源码结构 源码位置是在packages文件件内实际上源码主要分为两部分编译器和运行时环境 1. 编译器 compiler-core 核心编译逻辑compiler-dom 针对浏览器平台编译逻辑compiler-sfc 针对单文件组件编译逻辑compiler-ssr 针对服务端渲染编译逻辑 2. 运行时环境 runtime-core 运行时核心runtime-dom 运行时针对浏览器的逻辑runtime-test 浏览器外完成测试环境仿真 reactivity 响应式逻辑template-explorer 模板浏览器vue 代码入口整合编译器和运行时server-renderer服务器端渲染share 公用方法 # Vue 3初探 !DOCTYPE htmlhtml langenheadmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0 meta http-equivX-UA-Compatible contentieedgetitlehello vue3/titlescript src../dist/vue.global.js/script/headbody div idapph1{{message}}/h1/div scriptVue.createApp({data: { message: Hello Vue 3! }}).mount(#app) /script/body/html # Composition API Composition API字面意思是组合API它是为了实现基于函数的逻辑复用机制而产生的 # 1. 数据响应式 divcount: {{ state.count }}/divscript const { createApp, reactive} Vue;// 声明组件 const App {// setup是一个新的组件选项它是组件内使用Composition API的入口 // 调用时刻是初始化属性确定后beforeCreate之前setup() {// 响应化:接收一个对象返回一个响应式的代理对象 const state reactive({ count: 0 })// 返回对象将和渲染函数上下文合并 return { state } }}createApp(App).mount(#app) /script # 2. 计算属性 divdoubleCount: {{doubleCount}}/div # 3. 事件处理 div clickaddcount: {{ state.count }}/div # 4. 侦听器 # 5. 引用对象:单个原始值响应化 divcounter: {{ counter }}/div # 6. 体验逻辑组合 const { createApp, reactive, onMounted, onUnmounted, toRefs } Vue// 鼠标位置侦听 function useMouse() { // 数据响应化 const state reactive({ x: 0, y: 0 }) const update e { state.x e.pageX state.y e.pageY } onMounted(() { window.addEventListener(mousemove, update) }) onUnmounted(() { window.removeEventListener(mousemove, update) }) // 转换所有key为响应式数据 return toRefs(state)}// 事件监测function useTime() { const state reactive({ time: new Date() }) onMounted(() { setInterval(() { state.time new Date() }, 1000) }) return toRefs(state)}// 逻辑组合const MyComp { template: divx: {{ x }} y: {{ y }}/div ptime: {{time}}/p , setup() { // 使用鼠标逻辑 const { x, y } useMouse() // 使用时间逻辑 const { time } useTime() // 返回使用 return { x, y, time } } }createApp().mount(MyComp, #app) 对比mixins好处显而易见: x,y,time来源清晰不会与data、props等命名冲突 # Vue3响应式原理 # Vue2响应式原理回顾 // 1.对象响应化:遍历每个key定义getter、setter// 2.数组响应化:覆盖数组原型方法额外增加通知逻辑 const originalProto Array.prototypeconst arrayProto Object.create(originalProto);[push, pop, shift, unshift, splice, reverse, sort].forEach(method { arrayProto[method] function() { originalProto[method].apply(this, arguments) notifyUpdate() }} )function observe(obj) { if (typeof obj ! object || obj null) {return}// 增加数组类型判断若是数组则覆盖其原型 if (Array.isArray(obj)) { Object.setPrototypeOf(obj, arrayProto) } else { const keys Object.keys(obj) for (let i 0; i keys.length; i) { const key keys[i] defineReactive(obj, key, obj[key]) } } }function defineReactive(obj, key, val) { observe(val) // 解决嵌套对象问题 Object.defineProperty(obj, key, { get() { return val }, set(newVal) { if (newVal ! val) { observe(newVal) // 新值是对象的情况 val newVal notifyUpdate() } }}) }function notifyUpdate() { console.log(页面更新!)} vue2响应式弊端: 响应化过程需要递归遍历消耗较大新加或删除属性无法监听数组响应化需要额外实现Map、Set、Class等无法响应式修改语法有限制 # Vue3响应式原理剖析 vue3使用ES6的Proxy特性来解决这些问题。 function reactive(obj) { if (typeof obj ! object obj ! null) { return obj }// Proxy相当于在对象外层加拦截// http://es6.ruanyifeng.com/#docs/proxy const observed new Proxy(obj, { get(target, key, receiver) { // Reflect用于执行对象默认操作更规范、更友好 // Proxy和Object的方法Reflect都有对应 // http://es6.ruanyifeng.com/#docs/reflect const res Reflect.get(target, key, receiver) console.log(获取${key}:${res}) return res }, set(target, key, value, receiver) { const res Reflect.set(target, key, value, receiver) console.log(设置${key}:${value}) return res }, deleteProperty(target, key) { const res Reflect.deleteProperty(target, key) console.log(删除${key}:${res}) return res } }) return observed} 测试代码 const state reactive({ foo: foo, bar: { a: 1 } })// 1.获取state.foo // ok// 2.设置已存在属性state.foo fooooooo // ok // 3.设置不存在属性state.dong dong // ok // 4.删除属性delete state.dong // ok 1. 嵌套对象响应式 测试:嵌套对象不能响应 // 4.设置嵌套对象属性react.bar.a 10 // no ok 添加对象类型递归 2. 避免重复代理 重复代理比如 reactive(data) // 已代理过的纯对象 reactive(react) // 代理对象 解决方式:将之前代理结果缓存get时直接使用 const toProxy new WeakMap() // 形如obj:observed const toRaw new WeakMap() // 形如observed:objfunction reactive(obj) { //... // 查找缓存避免重复代理 if (toProxy.has(obj)) { return toProxy.get(obj) }if (toRaw.has(obj)) { return obj} const observed new Proxy(...) // 缓存代理结果 toProxy.set(obj, observed) toRaw.set(observed, obj) return observed } // 测试效果 console.log(reactive(data) state) console.log(reactive(state) state) 3. 依赖收集 建立响应数据key和更新函数之间的对应关系。 设计 实现三个函数: effect:将回调函数保存起来备用立即执行一次回调函数触发它里面一些响应数据的gettertrack:getter中调用track把前面存储的回调函数和当前target,key之间建立映射关系trigger:setter中调用trigger把target,key对应的响应函数都执行一遍 target,key和响应函数映射关系 实现 设置响应函数创建effect函数 // 保存当前活动响应函数作为getter和effect之间桥梁 const effectStack []// effect任务:执行fn并将其入栈 function effect(fn) { const rxEffect function() { // 1.捕获可能的异常 try { // 2.入栈用于后续依赖收集 effectStack.push(rxEffect) // 3.运行fn触发依赖收集 return fn() } finally { // 4.执行结束出栈 effectStack.pop() } } // 默认执行一次响应函数 rxEffect() // 返回响应函数 return rxEffect} 依赖收集和触发 function reactive(obj) { // ... const observed new Proxy(obj, { get(target, key, receiver) { // 依赖收集 track(target, key) return isObject(res) ? reactive(res) : res }, set(target, key, value, receiver) { // 触发响应函数 trigger(target, key) return res } })}// 映射关系表结构大致如下:// {target: {key: [fn1,fn2]}}let targetMap new WeakMap()function track(target, key) { // 从栈中取出响应函数 const effect effectStack[effectStack.length - 1] if (effect) { // 获取target对应依赖表 let depsMap targetMap.get(target) if (!depsMap) { depsMap new Map() targetMap.set(target, depsMap) } // 获取key对应的响应函数集 let deps depsMap.get(key) if (!deps) { deps new Set() depsMap.set(key, deps) } // 将响应函数加入到对应集合 if (!deps.has(effect)) { deps.add(effect) } }}// 触发target.key对应响应函数function trigger(target, key) { // 获取依赖表 const depsMap targetMap.get(target) if (depsMap) { // 获取响应函数集合 const deps depsMap.get(key) if (deps) { // 执行所有响应函数 deps.forEach(effect { effect() }) } }}