vue3在今年内应该就会推出,尤大以前也针对vue3的设计和api给出了RFC和最新征求意见稿。本人阅读后总结了一些我的心得,但愿对你们有用。javascript
vue2在近几年不太长的生命周期内,经历了大小各类项目的历练,能够说很是易于上手,方便开发。同时也暴露了很多问题亟待解决:css
vue3基于上述弊端从新设计了内部的实现方式,而且同时从新设计了组件选项和api。主要有:html
从新设计了响应式数据对象,内部实现从defineProperty改成由浏览器原生支持的proxy实现。包括手动定义响应式数据(reactive)和包装对象(ref)两种api方式建立响应式数据。前端
示例代码:vue
// reactive响应式数据
import { reactive } from 'vue'
const state = reactive({
count: 0
})
function increment() {
state.count ++
}
复制代码
// ref包装对象
import { ref } from 'vue'
const count = ref(0);
// 以变量的形式引用包装对象
function increment() {
count.value ++
}
复制代码
新增了watchEffect api,和vue2中的watch效果相似,监测响应式数据变化并执行反作用函数。java
import { reactive, ref, watchEffect } from 'vue'
const state = reactive({
count: 0,
})
const titleCount = ref(0);
// 当state.count、titleCount变化时,watchEffect将会自动执行反作用回调函数
watchEffect(() => {
document.body.innerHTML = `count is ${state.count}`
document.title = `title count is ${titleCount}`
});
复制代码
从新设计了computed api,将会建立一个依赖其它状态的响应式状态。被依赖的状态能够是由reactive或ref建立响应式数据,生成的状态则是一个只读的包装对象,以变量的形式使用时须要以
.value
这种方式。react
import { reactive, ref, computed } from 'vue'
const state = reactive({
count: 0,
})
const num = ref(0);
const double = computed(() => state.count * 2)
// 使用ref建立响应式对象时须要用.value取值计算
const triple = computed(() => num.value * 3)
watchEffect(() => {
console.log(double.value) // -> 0
console.log(triple.value) // -> 0
})
state.count++ // -> 2
num.value++ // -> 3
复制代码
新设计了setup()组件选项,代替以前的data组件选项。这个函数是组件开始逻辑的地方,它接收组件的props属性做为参数,而后开始调用,整个组件生命周期内只会执行一次。webpack
import { ref } from 'vue'
const MyComponent = {
setup(props) {
const msg = ref('hello')
const appendName = () => {
msg.value = `hello ${props.name}`
}
return {
msg,
appendName
}
},
template: `<div @click="appendName">{{ msg }}</div>`
}
复制代码
类型推导,须要使用defineComponent函数定义组件才能支持typescript类型推导web
import { defineComponent, ref } from 'vue'
const MyComponent = defineComponent({
// props选项声明用来定义prop属性类型
props: {
msg: String
},
setup(props) {
console.log(props.msg) // string 或 undefined
// setup中返回的数据对象能够在模板中用于类型推断推断类型
const count = ref(0)
return {
count
}
}
})
复制代码
在了解了上面的一些基本api后,咱们能够看一下尤大给出的一个基本组件写法:typescript
import { ref, computed, watchEffect, onMounted } from 'vue'
const App = {
template: ` <div> <span>count is {{ count }}</span> <span>plusOne is {{ plusOne }}</span> <button @click="increment">count++</button> </div> `,
setup() {
// reactive state
const count = ref(0)
// computed state
const plusOne = computed(() => count.value + 1)
// method
const increment = () => { count.value++ }
// watch
watchEffect(() => count.value * 2, val => {
console.log(`count * 2 is ${val}`)
})
// lifecycle
onMounted(() => {
console.log(`mounted`)
})
// expose bindings on render context
return {
count,
plusOne,
increment
}
}
}
复制代码
这里只介绍了少数比较重要的vue3 api,并且不肯定最终api还会不会再改动,若是想要详细查询学习的同窗能够去查看官方api文档。
尤大亲自说过vue3的最新设计很大程度上是借鉴了react hooks的思路。具体类似的地方至少有:
官方文档也给出了一个将获取鼠标位置的功能抽取成独立函数的实例:
// 抽取获取鼠标x, y位置的成函数 mouse.js
import { ref, onMounted, onUnmounted } from 'vue'
export function useMousePosition() {
const x = ref(0)
const y = ref(0)
function update(e) {
x.value = e.pageX
y.value = e.pageY
}
onMounted(() => {
window.addEventListener('mousemove', update)
})
onUnmounted(() => {
window.removeEventListener('mousemove', update)
})
return { x, y }
}
复制代码
import { useMousePosition } from './mouse'
export default {
setup() {
const { x, y } = useMousePosition()
// 其余逻辑...
return { x, y }
},
}
复制代码
若是是写过react hooks的同窗会发现,这与react hooks抽取公用函数的写法一模一样。换句话说,写过二者其一的话,都有助于咱们理解另外一个框架。
虽然vue3的写法相似于react hooks,可是其内部实现思路是不一样的:
vue3的设计在尤大看来至少有一下优点:
在阅读api设计文档时确实发现一些容易让开发者搞晕的东西,尤大对此也进行了总结。对于我我的来讲有如下比较麻烦的地方:
我我的但愿vue3正式推出的时候,文档可能提供api使用推荐写法,同时能提供相应的lint校验插件辅助,这样才好让不一样开发者写出通用可读的代码。
随着vue3而来的构建工具不是webpack,而是vite一种新型的项目构建工具。vite做用相似webpack,可是原理与webpack不一样。对比webpack有如下优点:
我也研究了一下vite的技术原理:
做者简介: 宫晨光,人和将来大数据前端工程师。