0%

Vue2.x 与 Vue3.x 区别

初始化

  1. 创建实例
  2. 使用 router、vuex 等
1
2
3
4
5
6
7
8
9
10
// vue2.x
import Vue from 'vue'
import router from './router'
import store from './store'
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
1
2
3
4
5
// vue3.x
import { createApp } from 'vue'
import router from './router'
import store from './store'
createApp(App).use(router).use(store).mount('#app')

选项式 API && 组合式 API

1
2
3
4
5
6
7
8
9
10
11
// vue2.x
export default {
name: '',
components: {},
props: {},
computed: {},
methods: {},
watch: {},
mounted: function () {},
data: () => {}
}
1
2
3
4
5
6
7
8
9
// vue3.x
export default {
name: '',
components: {},
props: [],
setup (props, context) {
return {}
}
}
  1. props
    props 是响应式的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    export default {
    props: {
    title: String
    },
    setup(props) {
    console.log(props.title)
    // ES6 的解构会消除 响应式,需要通过 toRefs 解构
    const { name } = toRefs(props)
    }
    }
  2. context
    普通的 js 对象,非响应式

    1
    2
    3
    4
    5
    6
    // 可以直接 ES6 解构
    // setup (props, { attrs, slots, emit, expose }) {
    setup (context) {
    // $attrs | $slots | $emit 方法 | expose 暴露一个属性,可以被外部访问 如 $refs
    const { attrs, slots, emit, expose } = context
    }
  3. 生命周期钩子

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Vue2---------------vue3
    beforeCreate -> setup()
    created -> setup()
    beforeMount -> onBeforeMount
    mounted -> onMounted
    beforeUpdate -> onBeforeUpdate
    updated -> onUpdated
    beforeDestroy -> onBeforeUnmount
    destroyed -> onUnmounted
    activated -> onActivated
    deactivated -> onDeactivated
    errorCaptured -> onErrorCaptured
  • setup: 组件创建之前,在 beforeCreate 和 created 之前执行,创建 data 和 methods

  • onBeforeMount: 组件挂载到节点上之前执行的函数

  • onMounted: …

  • 若组件被包含,则多出下面两个钩子函数

  • onActivated: 被激活时

  • onDeactivated: 失活时执行

注意

  • 执行 setup 时,只能访问 props/attrs/slots/emit
  • 无法访问 data/computed/methods/refs
  • setup 中不能使用 this,因为组件实例尚未被创建,this 不指向实例的引用,Vue 将其设置为 undefined

响应式 API

ref && reactive

  • vue2.x 的响应式数据 直接在 data 函数中
    1
    2
    3
    4
    5
    6
    7
    export default {
    data () {
    return {
    obj: {}
    }
    }
    }
  • vue3.x 的响应式数据 在 setup 函数返回
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import { ref, reactive } from 'vue'
    export default {
    setup () {
    /**
    * 封装成 proxy({ value: 'tang' }) 的形式
    */
    let name1 = ref('tang')
    const nameObj = reactive({ name: 'tang' })
    const { name } = toRefs(nameObj)
    return { name1, name }
    }
    }

computed && watch && watchEffect

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { computed, watch, watchEffect } from 'vue'
export default {
setup () {
computed(() => {})
computed({
set: () => {},
get: () => {}
})

watch(name, (newVal, oldVal) => {})
watch(() => nameObj.name, (curVal, preVal) => {})
watch(
[() => nameObj.name, () => nameObj.engName],
([curName, curEng], [preName, preEng]) => {},
{ deep: true }
)

watchEffect(() => {})
return {}
}
}

toRef

为源响应式对象上的一个 属性 创建一个 ref,它可以被传递,并且会保持对其源响应式对象的属性的 响应式链接

1
2
3
4
5
const state = reactive({ name: '111', age: 0 })
const ageRef = toRef(state, 'age')

ageRef.value++ // 1
state.age // 1

当你要将 prop 的 ref 传递给复合函数时,toRef 很有用

1
2
3
setup(props) {
useSomeFeature(toRef(props, 'foo'))
}

toRefs

将响应式对象转换为普通对象,但其内部的所有属性,指向的是其原始对象的属性的 ref (其内部属性还是响应式的)

将 proxy 对象
proxy({ name: 'tang', age: 12 })
转换成
{ name: proxy({ value: 'tang' }), age: proxy({ value: 12 }) }

1
2
3
4
5
6
7
8
const state = reactive({ name: '111', age: 0 })
const stateRefs = toRefs(state)

state.age++ // 1
stateRefs.age.value // 1

stateRefs.age.value++ // 2
state.age // 2

其他

响应式原理

Object.defineProperty => defineProxy

模板根节点

  • vue 2.x 的 template 根节点只能一个

    1
    2
    3
    <template>
    <div id="home"></div>
    </template>
  • vue 3.x 根节点可以有多个

    1
    2
    3
    4
    <template>
    <div id="home"></div>
    <div id="docker"></div>
    </template>

vue2.x 使用 flow, vue3.x 使用 typescript

对虚拟 DOM 的改进

  1. treeshaking
    options API 无法 摇树

  2. block
    vue2.x 对所有响应式数据 patch 和 diff,vue3.x 将 模板切分为 block(if | slot | for),对于静态节点优化,更新时只遍历动态节点

-------------本文结束感谢您的阅读-------------