一、新旧写法
切入正题,以下内容是基于Vue3.0.0-alpha.1版本与Vue2.x版本对比编写~
setup()函数
setup() 函数是 vue3 专门为组件提供的新属性,它为 Composition API 新特性提供了统一的入口。
setup函数会在 beforeCreate 之后、created 之前执。即一个组件实例被创建时,初始化了 props 之后调用, 取代了Vue2.x的careted和beforeCreate。
setup(props,ctx)提供了两个参数:
①props:模板传递的参数,Vue3的props不像vue2.x可以通过this.propsA访问到, 这里要通过setup传入参数props.propsA进行访问。
②ctx:第二个参数是一个上下文对象,setup里面this不再指向vue实例,
setup(props, ctx) { console.log(ctx) // 在 setup() 函数中无法访问到 this console.log(this) // undefined }
ctx包含了一些有用的属性:slots, root, parent, refs, attrs, listeners, isServer, ssrContext, emit,其中root指向vue实例,其他详细介绍可见Vue Composition API
Ref vs. Reactive
原先通过data中声明的响应式属性,现在替换成由 ref 函数来创建
// Vue2.x Options API 写法 data() { return { count: 0 } } // Vue3.x Composition API 写法 const count = ref(0)
ref 函数传入一个值作为参数,返回一个基于该值的响应式Ref对象,通过修改 count.value 的值,可以触发模板的重新渲染。
除了 ref 函数,Vue3.0中还提供了另外一个可以创建响应式对象的函数,那就是 reactive 函数。
两者声明方式对比如下:
// Ref const x = ref(0) const y = ref(0) const isDisplay = ref(false) // Reactive const state = reactive({ x: 0, y: 0, isDisplay: false })
二、双向绑定
vue2.x双向绑定
众所周知,Vue2.x双向绑定通过Object. defineproperty重定义data中的属性的get和set方法,从而劫持了data的get和set操作。Vue2.x双向绑定存在的弊端有:
1.实例创建后添加的属性监听不到,因为数据劫持是在实例初始化过程中执行, 具体是在beforeCreate和created生命周期间完成。 可以通过$set来解决后期添加监听属性的问题。
2.defineproperty ()无法监听数组变化,当直接用index设置数组项是不会被检测到的。 如:this.showData[1] = {a:1}。当然也能用$set解决。
官方文档指出,通过下面八种方法操作数组,Vue能检测到数据变化, 分别为:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
vue3.0双向绑定
Vue3.0采用Proxy和Reflect实现双向绑定, 它在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。我们可以这样认为,Proxy是Object.defineProperty的全方位加强版。
Object.defineProperty能做的Proxy能做
Proxy有多达13种拦截方法,不限于apply、ownKeys、deleteProperty、has等等是Object.defineProperty不具备的。Object.defineProperty不能做的Proxy还能做。
Proxy作为新标准,得到了各大浏览器厂商的大力支持,性能持续优化。唯一的不足就是兼容性的问题,而且无法通过polyfill解决。
三、生命周期
上面说了,Vue3.0中不再存在beforeCreate和created。composition-api暴露其他生命周期的API,都是以on开头的API。
下面就mounted写法进行举例,其他生命周期类比。
import { onMounted, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onUnmounted, onUpdated, } from "@vue/composition-api"; export default { setup(props, ctx) { onMounted(()=>{ console.log('mounted') }) }, };
🎨 原创不易,支持请点赞、转载请注明本文作者为子成君