本文已参与「新人创作礼」活动,一起开启掘金创作之路。
之前一直在用vue2开发项目,前些天学了vue3,首先是写法大不相同,其次就是响应式原理,有很大区别。下面就自己总结一下具体区别。
响应式原理的不同
vue2的响应式是通过Object.defineProperty()属性描述符的方式监听对象属性的改变,对数据进⾏劫持并结合 发布-订阅模式的⽅式,vue3使用的是es6新增的Proxy代理的方式监听对象的变化。
为什么要用proxy
- 比如新增属性、删除属性,defineProperty监听不到
- defineProperty的设计初衷是定义普通的属性,不是为了去监听一个对象中的所有属性
vue2使用Options API ,vue3使用Composition API
vue2的Options API写法会把数据,方法放到不同地方写。
export default {
props: {}, //父组件传递过来的值
components:{}, //引用的组件
computed:{} //计算属性
created(){}, //生命周期函数
mounted(){},//生命周期函数
data () { //响应式数据
return {}
},
methods: {}, //方法
}
vue3的Composition API会将变量声明、方法、生命周期函数、计算属性等都写在一个setup函数中,并通过return返回,并需要从vue包中引入
import { ref,reactive,computed,watch,onUnmounted } from "vue"
export default {
props: {},
setup () {
const num = ref(2) //声明响应式变量
const form = reactive({ //声明响应式变量
name: "" ,
password: ""
})
const list = computed(() => num.value + 1) //计算属性
watch( //watch监听
form,
(newVal) => {
console.log(newVal, "------------------------")
},
{
deep: true
}
)
const sub = () => { console.log(num.value - 10) } // 方法
onUnmounted(() => { console.log("onUnmounted"); }); //生命周期函数
return {
num,
form,
list
}
}
}
setup函数的参数
setup(props, { attrs, slots, emit }){}
// 透传 Attributes(非响应式的对象,等价于 $attrs)
// 插槽(非响应式的对象,等价于 $slots)
// 触发事件(函数,等价于 $emit)
生命周期函数发生变化
父子传参变化
vue2父子传参
//父组件
<HelloWorld :num="num" @add="add">
export default {
data(){
return {
num:10
}
},
methods: {
add(){
this.num++
}
},
//子组件
export default {
props: { //接收父组件的值
num:{
type:Number,
default:0
}
},
data () { //响应式数据
return {}
},
methods: {
this.$emit('add')
},
}
vue3父子传值
//父组件
<HelloWorld :num="num" @add="add">
export default {
setup(){
const num = ref(10)
const add = () =>{
num.value = 30
}
return {
num
}
}
},
//子组件
import { ref } from 'vue'
export default ({
props: {
num: {
type: Object,
required: true
}
},
emits:['add'],
setup(props,{ emit }) {
const add = () => {
console.log(props.num)
emit('add')
}
return {
add
}
}
})