Vue3.0全家桶最全入门指南 - 3.x跟2.x的其他差异 (4/4)

Posted coderkey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue3.0全家桶最全入门指南 - 3.x跟2.x的其他差异 (4/4)相关的知识,希望对你有一定的参考价值。

四、3.x跟2.x的其他差异

ctx属性

对于网上一些其他文档使用ctx. r o u t e r 、 c t x . router、ctx. routerctx.store访问router和store的应该小心避坑,注意开发环境和生产环境的差别

vue3.x 开发环境 ctx

开发环境的ctx,可以看到 r o u t e r 、 router、 routerstore、声明的变量和方法等
在这里插入图片描述
vue3.x 生产环境 ctx

生产环境的ctx, r o u t e r 、 router、 routerstore没有了,其他属性也都没有了,不能通过ctx. r o u t e r 、 c t x . router、ctx. routerctx.store访问router和store,因此ctx可以说对我们没有用,应该避免在代码中使用ctx
在这里插入图片描述
执行顺序

vue3.x中会先执行setup方法,再执行兼容2.x的其他方法,比如data、computed、watch等,
并且在setup执行过程中,无法访问data中定义的属性,因为此时还未执行到data方法

mount挂载

使用mount挂载的时候
2.x会使用挂载元素的outerhtml作为template,并替换挂载元素
3.x会使用挂载元素的innerHTML作为template,并且只替换挂载元素的子元素

this.$el、reactive refs、template refs

2.x可以在组件挂载之后通过this. e l 访 问 组 件 根 元 素 3. x 去 掉 t h i s , 并 且 支 持 F r a g m e n t , 所 以 t h i s . el访问组件根元素 3.x去掉this,并且支持Fragment,所以this. el访3.xthisFragmentthis.el没有存在的意义,建议通过refs访问DOM
当使用组合式 API 时,reactive refs 和 template refs 的概念已经是统一的。为了获得对模板内元素或组件实例的引用,我们可以像往常一样在 setup() 中声明一个 ref 并返回它

使用reactive refs和template refs

<template>
  <div ref="root"></div>
</template>

<script>
  import { ref, onMounted, getCurrentInstance } from 'vue'

  export default {
    setup() {
      const vm = getCurrentInstance()
      const root = ref(null)

      onMounted(() => {
        // 在渲染完成后, 这个 div DOM 会被赋值给 root ref 对象
        console.log(root.value) // <div/>
        console.log(vm.refs.root) // <div/>
        console.log(root.value === vm.refs.root) // true
      })

      return {
        root
      }
    }
  }
</script>

在v-for中使用

<template>
  <div v-for="(item, i) in list" :key="i" :ref="el => { divs[i] = el }">
    {{ item }}
  </div>
</template>

<script>
  import { ref, reactive, onBeforeUpdate } from 'vue'

  export default {
    setup() {
      const list = reactive([1, 2, 3])
      const divs = ref([])

      // 确保在每次变更之前重置引用
      onBeforeUpdate(() => {
        divs.value = []
      })

      return {
        list,
        divs
      }
    }
  }
</script>

setup返回普通对象

setup返回普通对象的时候,会跟reactive对象一样,具备响应式,执行下面这段代码后会发现普通对象obj1.cnt也具有响应式了,虽然这样可以行得通,但是为了可读性,防止不了解这个特性的同学误解为非响应式的,建议还是通过reactive包一下。

<template>
  <div>{{ obj1.cnt }}</div>
  <div>{{ obj2.cnt }}</div>
</template>

<script>
import { reactive } from 'vue'

export default {
  setup () {
    // 普通对象
    const obj1 = {
      cnt: 1
    }
    // 代理对象
    const obj2 = reactive({
      cnt: 1
    })
    setInterval(() => {
      obj1.cnt++
      obj2.cnt++
    }, 5000)
    
    return {
      obj1,
      obj2
    }
  }
}
</script>

directive指令

vue3.x对指令的生命周期钩子进行了改造,改造后更像3.x普通vue组件的钩子,更方便记忆

// vue2.x
export default {
  name: 'YourDirectiveName',
  bind(el, binding, vnode, oldVnode) {},
  inserted(...) {},
  update(...) {},
  componentUpdated(...) {},
  unbind(...) {}
}

// vue3.x
export default {
  beforeMount(el, binding, vnode, oldVnode) {},
  mounted(...) {},
  beforeUpdate(...) {},
  updated(...) {},
  beforeUnmount(...) {},
  unmounted() {...}
}

render方法修改

vue、react都提供了render方法渲染html模板,直接使用render方法的还是比较少,毕竟有template和JSX,对于确实需要自定义render方法渲染模板内容的,具体变动如下:

// vue2.x
export default {
  render(h) {
    return h('div')
  }
}

// vue3.x
import { h } from 'vue'
export default {
  render() {
    return h('div')
  }
}

3.x中移除的一些特性

取消KeyboardEvent.keyCode

在vue3.x中,给keyup事件配置一个指定按钮的keyCode(数字)将不会生效,但是依然可以使用别名,例如:

// 无效
<input @keyup.13="handler" />
// 有效
<input @keyup.enter="handler" />

移除 on,on,on,off 和 $once方法

在Vue2.x中可以通过EventBus的方法来实现组件通信

// 声明实例
var EventBus = new Vue()
Vue.prototype.$globalBus = EventBus
// 组件内调用
this.$globalBus.$on('my-event-name', callback)
this.$globalBus.$emit('my-event-name', data)

在vue3.x中移除了 o n 、 on、 onoff等方法,而是推荐使用mitt方案来代替:

// 声明实例
import mitt from 'mitt'
const emitter = mitt()
// 组件内调用
// listen to all events
emitter.on('*', (type, e) => console.log(type, e))
emitter.on('my-event-name', callback)
emitter.emit('my-event-name', data)
// clearing all events
emitter.all.clear()

移除filters

在vue3.x中,移除了组件的filters项,可以使用methods的或者computed来替代

移除inline-template

在Vue2.x中,在父组件引入子组件时,会用到inline-template来使子组件的内容也得到展示,参考这里,例如:

<my-component inline-template>
  <div>
    <p>These are compiled as the component's own template.</p>
    <p>Not parent's transclusion content.</p>
  </div>
</my-component>

在Vue3中,这个功能将被移除,目前inline-template使用的并不多,这里就不再过多讲解

以上是关于Vue3.0全家桶最全入门指南 - 3.x跟2.x的其他差异 (4/4)的主要内容,如果未能解决你的问题,请参考以下文章

Vue3.0全家桶最全入门指南 - 快速搭建 (1/4)

Vue3.0全家桶最全入门指南 - 快速搭建 (1/4)

Vue3.0全家桶最全入门指南 - vue-router@4.x和vuex@4.x (3/4)

最全153道Spring全家桶面试题,java初级面试官常问的问题

Java面试题!最全153道Spring全家桶面试题

最全153道Spring全家桶面试题,简单java编程题