作者:大转转FE
转发链接:https://mp.weixin.qq.com/s/gZVn9eDruyv7G_UJFTPuGQ
这几天,陆续学习了解了关于vue-next(Vue 3.0)(https://github.com/vuejs/vue-next)的一些新特性,尤其是新的 CompositionAPI的用法。这套新的API中最重要、最核心的部分,恐怕就是实现响应式功能的这一块了。而且,这套响应式API不仅可以在 vue-next环境下使用,也可以独立使用。
笔者在阅读源码看到, vue-next已全部由 TypeScript构建,看来 ts 必学技能。接下来带你了解vue-next。
vue-next计划并已实现的主要架构改进和新功能:
运行时(Runtime)的更新主要体现在以下几个方面:
最后,还有一些 2.x 的功能尚未移植过来,如下:
==目前不支持IE11==
vue-next(Vue 3.0) 的源码虽然发布了,但是预计最早也需要等到 2020 年第一季度才有可能发布 3.0 正式版。
代码仓库中有个 packages 目录,里面主要是 vue-next 的相关源码功能实现,具体内容如下所示。
const { render, createApp } = createRenderer({ patchProp, ...nodeOps})export { render, createApp }
'use strict'if (process.env.NODE_ENV === 'production') { module.exports = require('./dist/vue.cjs.prod.js')} else { module.exports = require('./dist/vue.cjs.js')}
这个原理老生常谈了,就是拦截对象,给对象的属性增加 set 和 get方法,因为核心是 defineProperty所以还需要对数组的方法进行拦截
function observer(target){ // 如果不是对象数据类型直接返回即可 if(typeof target !=='object'){ return target} // 重新定义key for(let key in target){ defineReactive(target,key,target[key]) }}function update(){ console.log('update view')}function defineReactive(obj,key,value){ observer(value); // 有可能对象类型是多层,递归劫持 Object.defineProperty(obj,key,{ get(){ // 在get 方法中收集依赖 return value }, set(newVal){ if(newVal !== value){ observer(value); update(); // 在set方法中触发更新 } } })}const obj ={name:'zhuanzhuan'}observer(obj);obj.name ='new-name';
输出:update view
const oldProtoMehtods = Arrayprototypeconst proto = Object.create(oldProtoMehtods)function update(){ console.log('update view')}function defineReactive(obj,key,value){ observer(value) // 有可能对象类型是多层,递归劫持 Object.defineProperty(obj,key,{ get(){ // 在get 方法中收集依赖 return value }, set(newVal){ if(newVal !== value){ observer(value) update() // 在set方法中触发更新 } } })}['push','pop','shift','unshift'].forEach(method=>{ Object.defineProperty(proto, method,{ get(){ update() return oldProtoMehtods[method] } })})function observer(target){ if(typeof target !== 'object'){ return target } // 如果不是对象数据类型直接返回即可 if(Array.isArray(target)){ Object.setPrototypeOf(target, proto) // 给数组中的每一项进行observr for(let i = 0 ; i < target.length; i++){ observer(target[i]) } return } // 重新定义key for(let key in target){ defineReactive(target, key, target[key]) }}let obj = {hobby:[{name:'zhuanzhuan'}]}observer(obj)// 使用['push','pop','shift','unshift'] 方法,更改数组会触发视图更新obj.hobby.push('转转')// 更改数组中的对象也会触发视图更新obj.hobby[0].name = 'new-name'console.log(obj.hobby)
输出:update viewupdate view[ { name: [Getter/Setter] }, '转转' ]
Object.defineProperty缺点:
无论是阅读这篇文章,还是阅读 vue-next 响应式模块的源码,首先有两个知识点是必备的:
let data=[1,2,3]let p=new Proxy(data,{get(target,key){console.log('获取值:',key)return target[key]},set(target,key,value){console.log('修改值:',key,value)target[key]=valuereturn true}})p.push(4)
输出:获取值: push获取值:length修改值:3 4修改值: length 4
比 defineproperty优秀的 就是数组和对象都可以直接触发 getter和 setter, 但是数组会触发两次,因为获取 push和修改 length的时候也会触发
Proxy 取代 deineProperty 除了性能更高以外,还有以下缺陷,也是为啥会有$set,$delete的原因 :
let data = [1,2,3]let p = new Proxy(data,{get(target,key){ console.log('获取值:',key) return Reflect.get(target,key)}, set(target,key,value){ console.log('修改值:',key,value) return Reflect.set(target,key,value)}})p.push(4)
输出:获取值: push获取值: length修改值: 3 4修改值: length 4
let data={name:{title:'zhuanzhuan'}}let p= new Proxy(data,{get(target,key){ console.log('获取值:',key) return Reflect.get(target,key)}, set(target,key,value){ console.log('修改值:',key,value) return Reflect.set(target,key,value)}})p.name.title = 'xx'
输出:获取值: name
之后会带你看下 vue-next是怎么解决的。
$ git clone https://github.com/vuejs/vue-next.git
$ npm run dev
$ npm install -g @vue/cli# OR$ yarn global add @vue/cli
2. 创建项目
$ vue create my-project# OR$ vue ui
3. 在项目中安装 composition-api 体验 vue-next 新特性
$ npm install @vue/composition-api --save# OR$ yarn add @vue/composition-api
4. 在使用任何 @vue/composition-api 提供的能力前,必须先通过 Vue.use() 进行安装
import Vue from 'vue'import VueCompositionApi from '@vue/composition-api'Vue.use(VueCompositionApi)
安装插件后,您就可以使用新的 Composition API 来开发组件了。
直接拷贝下面代码,去运行看效果吧。推荐使用高版本的chrome浏览器,记得打开F12调试工具哦!
Title
这个reactive和react-hooks越来越像了, 大家可以去Composition API RFC(https://vue-composition-api-rfc.netlify.com/#api-introduction)这里看细节。
《实践Vue 3.0做JSX(TSX)风格的组件开发》
《一篇文章教你并列比较React.js和Vue.js的语法【实践】》
《手拉手带你开启Vue3世界的鬼斧神工【实践】》
《深入浅出通过vue-cli3构建一个SSR应用程序【实践】》
《怎样为你的 Vue.js 单页应用提速》
《聊聊昨晚尤雨溪现场针对Vue3.0 Beta版本新特性知识点汇总》
《【新消息】Vue 3.0 Beta 版本发布,你还学的动么?》
《Vue真是太好了 壹万多字的Vue知识点 超详细!》
《Vue + Koa从零打造一个H5页面可视化编辑器——Quark-h5》
《深入浅出Vue3 跟着尤雨溪学 TypeScript 之 Ref 【实践】》
《手把手教你深入浅出vue-cli3升级vue-cli4的方法》
《Vue 3.0 Beta 和React 开发者分别杠上了》
《手把手教你用vue drag chart 实现一个可以拖动 / 缩放的图表组件》
《Vue3 尝鲜》
《总结Vue组件的通信》
《手把手让你成为更好的Vue.js开发人员的12个技巧和窍门【实践】》
《Vue 开源项目 TOP45》
《2020 年,Vue 受欢迎程度是否会超过 React?》
《尤雨溪:Vue 3.0的设计原则》
《使用vue实现HTML页面生成图片》
《实现全栈收银系统(Node+Vue)(上)》
《实现全栈收银系统(Node+Vue)(下)》
《vue引入原生高德地图》
《Vue合理配置WebSocket并实现群聊》
《多年vue项目实战经验汇总》
《vue之将echart封装为组件》
《基于 Vue 的两层吸顶踩坑总结》
《Vue插件总结【前端开发必备】》
《Vue 开发必须知道的 36 个技巧【近1W字】》
《构建大型 Vue.js 项目的10条建议》
《深入理解vue中的slot与slot-scope》
《手把手教你Vue解析pdf(base64)转图片【实践】》
《使用vue+node搭建前端异常监控系统》
《推荐 8 个漂亮的 vue.js 进度条组件》
《基于Vue实现拖拽升级(九宫格拖拽)》
《手摸手,带你用vue撸后台 系列二(登录权限篇)》
《手摸手,带你用vue撸后台 系列三(实战篇)》
《前端框架用vue还是react?清晰对比两者差异》
《Vue组件间通信几种方式,你用哪种?【实践】》
《浅析 React / Vue 跨端渲染原理与实现》
《10个Vue开发技巧助力成为更好的工程师》
《手把手教你Vue之父子组件间通信实践讲解【props、$ref 、$emit】》
《1W字长文+多图,带你了解vue的双向数据绑定源码实现》
《深入浅出Vue3 的响应式和以前的区别到底在哪里?【实践】》
《干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)》
《基于Vue/VueRouter/Vuex/Axios登录路由和接口级拦截原理与实现》
《手把手教你D3.js 实现数据可视化极速上手到Vue应用》
《吃透 Vue 项目开发实践|16个方面深入前端工程化开发技巧【上】》
《吃透 Vue 项目开发实践|16个方面深入前端工程化开发技巧【中】》
《吃透 Vue 项目开发实践|16个方面深入前端工程化开发技巧【下】》
《Vue3.0权限管理实现流程【实践】》
《后台管理系统,前端Vue根据角色动态设置菜单栏和路由》
《React 函数式组件性能优化知识点指南汇总》
《13个精选的React JS框架》
《深入浅出画图讲解React Diff原理【实践】》
《【React深入】React事件机制》
《Vue 3.0 Beta 和React 开发者分别杠上了》
《手把手深入Redux react-redux中间件设计及原理(上)【实践】》
《手把手深入Redux react-redux中间件设计及原理(下)【实践】》
《前端框架用vue还是react?清晰对比两者差异》
《为了学好 React Hooks, 我解析了 Vue Composition API》
《【React 高级进阶】探索 store 设计、从零实现 react-redux》
《写React Hooks前必读》
《深入浅出掌握React 与 React Native这两个框架》
《可靠React组件设计的7个准则之SRP》
《React Router v6 新特性及迁移指南》
《用React Hooks做一个搜索栏》
《你需要的 React + TypeScript 50 条规范和经验》
《手把手教你绕开React useEffect的陷阱》
《浅析 React / Vue 跨端渲染原理与实现》
《React 开发必须知道的 34 个技巧【近1W字】》
《三张图详细解说React组件的生命周期》
《手把手教你深入浅出实现Vue3 & React Hooks新UI Modal弹窗》
《手把手教你搭建一个React TS 项目模板》
《全平台(Vue/React/微信小程序)任意角度旋图片裁剪组件》
《40行代码把Vue3的响应式集成进React做状态管理》
《手把手教你深入浅出React 迷惑的问题点【完整版】》
作者:大转转FE
转发链接:https://mp.weixin.qq.com/s/gZVn9eDruyv7G_UJFTPuGQ