• vue2和vue3有哪些区别和不同


    Vue v3.x 概述

    Vue 3 引入了一些新功能和一系列重大更改。让我们看看这些更改将如何影响我们的应用程序。

    Vue V3.x 重大更改

    在 Vue 3 中,重大更改基本上分为七类:

    • 全局 API
      (负责 Vue 的行为方式) - 您很可能想要查看这些更改。
    • 模板指令
      (对 v- 指令的工作方式所做的更改) - 您很可能想要查看这些更改。
    • 组件
      (对组件工作方式的更改) - 如果您的应用程序使用组件,则您很可能要查看这些更改
    • 呈现函数(允许您以编程方式创建 HTML 元素)
    • 自定义元素(告诉 Vue 有关创建自定义 HTML 元素的信息)
    • 次要更改(这些可能不会影响您,但您仍然需要查看这些更改)
    • 删除了 API(在 Vue 3 中不再可用的内容)

    在所有更改中,有一些是任何应用程序都会使用的,例如全局API和组件。因此,如果你想开始使用新的 Vue 版本,就需要考虑它们。

    值得一提的是以下附加更改:

    • 您创建 Vue 应用程序和组件实例的方式已更改(全局 API)
    • 应始终将数据选项声明为函数(细微更改)
    • 对同一元素使用 v-if 和 v-for 时的优先级更改(模板 Ddrectives)
    • 应为组件事件(组件)声明发出选项

    有关更改的完整列表,您可以转到文档

    现在,让我们更详细地看一下其中的一些更改。

    全局属性

    vue2

    • 对于一些第三方插件,Vue2通常使用原型原型来挂载到VUE对象上。
    1. import Vue from 'vue'
    2. Vue.prototype.$http=Axiox
    3. Vue.prototype.$echart= Echart

    vue3

    • Vue3Global 属性配置中提供了一个名称,可以替换 Vue2 中的原型globalProperties
    1. app.config.globalProperties.$http = Axios
    2. app.config.globalProperties.$echart = Echart
    • 使用 $ http
    1. import {getCurrentInstance} from 'vue'
    2. setup () {
    3. const { ctx } = getCurrentInstance();
    4. onMounted(() => {
    5. console.log(ctx.$http)
    6. })
    7. .......
    8. }

    REF 和 V-用于生成

    vue2

    VUE2中的V-FOR与REF一起使用,当引用批量模板时,获得的REF是一个数组。

    1. <div v-for = "i in 3" ref = "setItemref": key = "i"> {{i}} </ div> // Here are arrays
    2. mounted() {
    3. console.log(this.$refs.setItemRef)
    4. },

    vue3

    VUE3 中的 REF 绑定是一个函数,

    1. <div v-for = "item in 3": ref = "setItemRef"> </ div> // This is a function
    2. setup(){
    3. let itemRefs = []
    4. const setItemRef = el => {
    5. itemRefs.push(el)
    6. }
    7. onMounted(() => {
    8. console.log(itemRefs)
    9. })
    10. }

    REF 的 DOM 模式已更改,但结果是相同的

    异步组件

    在路由中,通常使用延迟加载的方式来引入组件。

    vue2

     component: () => import('@/views/homePage/index.vue'),
    

    vue3

    在 Vue3 中引入一个新方法--->定义异步组件来打包 Vue2 介绍的内容defineAsyncComponent

    1. import { defineAsyncComponent } from 'vue'
    2. component: defineAsyncComponent(() => import('./NextPage.vue'))

    自定义说明

    更改挂钩函数的命名

    vue2

    VUE2 中绑定的钩子函数是

    • bind - 指令绑定到元素。仅发生一次。
    • inserted - 将元素插入父 DOM 时。
    • update - 当元素更新,但子元素尚未更新时,将调用此挂接。
    • componentUpdate - 一旦组件和子级更新,将调用此挂接。
    • unbind - 接触绑定。一旦指令被删除,将调用此钩子。只呼叫一次。

    vue3

    钩子函数的命名与生命周期的钩子函数一致

    • bind → beforeMount
    • inserted → mounted
    • beforeUpdate:new!这是在元素本身更新之前调用的,非常类似于组件生命周期挂钩。
    • componentUpdated → updated
    • beforeUnmount:new!与组件生命周期挂钩类似,它将在卸载元素之前调用。
    • unbind -> unmounted

    挂接函数中的引用组件实例

    某些实例需要获取组件中实例的某些属性

    vue2

    • 需要通过 vNod 获取实例
    1. Vue.directive('has', {
    2. inserted: (el, binding, vnode) => checkPermission(el, binding, vnode),
    3. });
    4. export const checkPermission = (el, binding, vnode) => {
    5. ...
    6. Const permissionarr = vnode.context. $ store.state.PermissionID // All permission ID
    7. ...
    8. }

    vue3

    • 从绑定中获取对象
    1. export const checkPermission = (el, binding, vnode) => {
    2. ...
    3. Const permissionarr = binding.instance. $ store.State.PermissionID // All permission ID
    4. ...
    5. }

    v-bind=“$attrs”

    自定义元素元素交互

    IS 用法

    vue2

    • 组件:
    <component :is="currentTabComponent"></component>
    
    • html
    1. <table>
    2. <tr is="blog-post-row"></tr>
    3. </table>

    vue3

    • 子组件Assembly
    <component is="currentTabComponent"></component>
    
    • html
    1. <table>
    2. <TR V-IS = "'blog-post-rot"> </ tr> // V-IS is similar to binding a variable, and we need a component name, a string, so wrapped with single quotes
    3. </table>

    事件

    • Vue3 移除、、,三种方法,只保留。$on$off$once$emit

    滤波器

    过滤器函数在 Vue3 中被删除。建议使用方法或计算代替,实际上,在 Vue2 中,你可以实现这两种方式。

    部分过滤器

    vue2

    1. <p>{{message|toLower}}</p>
    2. data() {
    3. return {
    4. message: 'ABC'
    5. }
    6. },
    7. filters: {
    8. toLower(value) {
    9. return value.toLowerCase()
    10. }
    11. }

    vue3

    • Vue3 是用计算或方法定义的
    1. <p>{{messageToLower}}</p>
    2. import {
    3. computed,
    4. ref,
    5. } from 'vue';
    6. setup(){
    7. let message = ref('ABC')
    8. let messageToLower = computed(() => {
    9. // console.log(message)
    10. return message.value.toLowerCase()
    11. })
    12. return{
    13. messageToLower,
    14. }
    15. }

    全局过滤器

    vue2

    1. Vue.filter('toLower', (value)=> {
    2. return value.toLowerCase()
    3. })

    vue3

    • 在main.js中注册
    1. const app =createApp(App)
    2. app.config.globalProperties.$filter={
    3. toLower(value){
    4. return value.toLowerCase()
    5. }
    6. }
    <p>{{$filters.toLower(message)}}</p>
    

    根节点

    vue2

    • Vue2只有一个根节点只能存在template
    1. <template>
    2. <div id="app">
    3. ...
    4. </div>
    5. </template>

    vue3

    • Vue3 中可以存在多个节点
    1. <template>
    2. <div>...</div>
    3. <a>...</a>
    4. <p>...</p>
    5. </template>

    template

    1. <template>
    2. <div class="wrap">
    3. <div>{{ num }}</div>
    4. <Button @ click = "getdata"> change data </ ​​button>
    5. </div>
    6. </template>
    7. <style lang="less" scoped>
    8. .wrap {
    9. width: 100%;
    10. height: 100%;
    11. border: 1px solid red;
    12. }
    13. </style>

    vue2

    1. <!-- vue2 -->
    2. <script>
    3. export default {
    4. data() {
    5. return {
    6. num: 333,
    7. };
    8. },
    9. //
    10. mounted() {
    11. alert('111');
    12. this.getData();
    13. },
    14. methods: {
    15. getData() {
    16. this.num = '2222';
    17. },
    18. },
    19. };
    20. </script>

    vue3.0

    1. <!-- vue3.0 -->
    2. <script>
    3. import { defineComponent, ref } from 'vue';
    4. export default defineComponent({
    5. setup() {
    6. let num = ref(1223);
    7. function getSecondData(params) {
    8. alert('222');
    9. }
    10. function getData(params) {
    11. num.value = 'weruwiru';
    12. getSecondData();
    13. }
    14. return {
    15. num,
    16. getData,
    17. };
    18. },
    19. });
    20. </script>

    vue3.2

    1. <!-- vue3.2 -->
    2. <script setup>
    3. import { ref } from 'vue';
    4. let num = ref(1223);
    5. function getSecondData(params) {
    6. alert('222');
    7. }
    8. function getData(params) {
    9. num.value = 'weruwiru';
    10. getSecondData();
    11. }
    12. </script>

    功能组件

    全球原料药

    内联模板

    vue2

    • 使用内联模板属性

    • Vue2 中的文档会提示这样一个词,所以我几乎用了

      但是,内联模板会使模板的作用更难理解。因此,作为最佳实践,请选择组件模板 Option 或.vue One中的file<template> Elements来定义模板。>

    vue3

    删除此功能,

    唯一键

    输入 V-IF

    vue2

    • 在 Vue2 中,V-IF 中的关键是 V-Else 控制组件或元素。
    • 如果您没有密钥,您将被重复使用。<你好世界>组件仅创建一个
    1. <!---->
    2. <template v-if="loginType === 'username'">
    3. <hello-world title="username"></hello-world>
    4. </template>
    5. <template v-else>
    6. <hello-world title="email"></hello-world>
    7. </template>
    8. <Button @ Click = "ChangeType"> Switch </ button>
    • 使用 Key,每个开关将呈现组件(在 KEY 中提供)
    1. <template v-if="loginType === 'username'">
    2. <hello-world title="username" key="a"></hello-world>
    3. </template>
    4. <template v-else>
    5. <hello-world title="email" key="b"></hello-world>
    6. </template>
    7. <Button @ Click = "ChangeType"> Switch </ button>

    vue3

    Vue3 默认为键,此键始终是唯一的,不同于其他键,不能使用相同的来强制重用分支。

    1. <div v-if="condition">Yes</div>
    2. <div v-else>No</div>

    在模板中的 V-for 中 KEY

    vue2

    在 Vue2 的 Template 选项卡上,你可以使用 V-FOR 指令,但不能绑定 Key,只能在子节点上绑定唯一的 KEY。

    1. <template v-for="item in list">
    2. <div :key="item.id">...</div>
    3. </template>

    vue3

    键可以绑定到 Vue3 中的模板

    1. <template v-for="item in list" :key="item.id">
    2. <div>...</div>
    3. </template>

     

    设置数据

    这就是主要区别所在 —— Vue2 Options API 与 Vue 3 Composition API。

    选项 API 将我们的代码分为不同的属性:数据、计算属性、方法等。同时,组合API允许我们按函数而不是属性类型对代码进行分组。

    对于窗体组件,假设我们只有两个数据属性:a 和 a。username        password

    Vue2 代码看起来像这样 – 我们只是在数据属性中折腾了两个值。

    1. export default {
    2. props: {
    3. title: String,
    4. },
    5. data() {
    6. return {
    7. username: "",
    8. password: "",
    9. };
    10. },
    11. };

    在 Vue 3 中,我们必须通过使用一种新方法来投入更多的精力,其中所有组件初始化都应该进行。setup()

    此外,为了让开发人员能够更好地控制什么是反应式的,我们可以直接访问 Vue 的反应性 API。

    创建反应式数据涉及三个步骤:

    • 从 vue 导入reactive

    • 使用反应式方法声明我们的数据

    • 让我们的方法返回反应式数据,以便我们的模板可以访问它setup

    就代码而言,它看起来有点像这样。

    1. import { reactive } from "vue";
    2. export default {
    3. props: {
    4. title: String,
    5. },
    6. setup() {
    7. const state = reactive({
    8. username: "",
    9. password: "",
    10. });
    11. return { state };
    12. },
    13. };

    然后,在我们的模板中,我们像和state.username        state.password

    在 Vue 2 与 Vue 3 中创建方法

    Vue2 选项 API 有一个单独的方法部分。在其中,我们可以定义我们所有的方法并以我们想要的任何方式组织它们。

    Vue 3 Composition API中的 setup 方法也处理方法。它的工作方式有点类似于声明数据——我们必须首先声明我们的方法,然后返回它,以便我们组件的其他部分可以访问它。

    创建我们的模板(根目录)

    对于大多数组件,Vue 2 和 Vue 3 中的代码即使不相同,也会非常相似。但是,Vue 3 支持 Fragments,这意味着组件可以有多个根节点。

    这在渲染列表中的组件以删除不必要的包装器 div 元素时特别有用。但是,在这种情况下,我们将为表单组件的两个版本保留一个根节点。

    Vue3

    唯一真正的区别是我们如何访问我们的数据。在 Vue 3 中,我们的响应式数据都包装在一个响应式状态变量中——因此我们需要访问这个状态变量来获取我们的值。

    生命周期挂钩

    在 Vue2 中,我们可以直接从我们的组件选项中访问生命周期钩子。对于我们的示例,我们将等待mounted 事件。

    现在使用 Vue 3 组合 API,几乎所有内容都在 setup() 方法中。这包括已安装的生命周期挂钩。

    但是,默认情况下不包含生命周期钩子,因此我们必须导入onMounted在 Vue 3 中调用的方法。这看起来与之前导入响应式的方法相同。

    然后,在我们的 setup 方法中,我们可以通过将 onMounted 方法传递给我们的函数来使用它。

    计算属性

    让我们添加一个计算属性,将我们的用户名转换为小写字母。

    为了在 Vue2 中实现这一点,我们向选项对象添加了一个计算字段。从这里,我们可以像这样定义我们的属性……

    Vue 3 的设计允许开发人员导入他们使用的东西,并且在他们的项目中没有不必要的包。本质上,他们不希望开发人员必须包含他们从未使用过的东西,这在 Vue2 中正成为一个日益严重的问题。

    因此,要在 Vue 3 中使用计算属性,我们首先必须将计算属性导入到我们的组件中。

    然后,与我们之前创建响应式数据的方式类似,我们可以将一段响应式数据作为计算值

    访问props

    访问 props 带来了 Vue 2 和 Vue 3 之间的重要区别——this意味着完全不同的东西。

    在 Vue2 中,this几乎总是引用组件,而不是特定的属性。虽然这在表面上使事情变得容易,但它使类型支持变得痛苦。

    然而,我们可以很容易地访问道具——让我们添加一个简单的例子,比如title在挂载的钩子中打印出我们的道具:

    但是在 Vue 3 中,我们不再使用this来访问 props、发出事件和获取属性。相反,该setup()方法采用两个参数:

    • props– 对组件道具的不可变访问

    • context– Vue 3 公开的选定属性(emit、slots、attrs)

    使用 props 参数,上面的代码看起来像这样。

    Emitting事件

    同样,在 Vue 2 中Emitting事件非常简单,但 Vue 3 让您可以更好地控制如何访问属性/方法。

    假设在我们的例子中,当按下“提交”按钮时,我们想要向父组件发出登录事件。

    Vue 2 代码只需要调用this.$emit并传入我们的有效负载对象。

    然而,在 Vue 3 中,我们现在知道这this不再意味着同样的事情,所以我们必须以不同的方式来做。

    幸运的是,上下文对象暴露emit给了我们同样的东西this.$emit

    我们所要做的就是将context第二个参数添加到我们的设置方法中。我们将解构上下文对象以使我们的代码更简洁。

    然后,我们只需调用 emit 来发送我们的事件。然后,就像以前一样,emit 方法接受两个参数:

    • 我们的活动名称

    • 与我们的事件一起传递的有效负载对象

     如何在 Vue 3 中创建应用程序和组件实例

    在 Vue 3 中,你创建应用的方式发生了变化。Vue 应用程序现在使用新方法来创建应用程序实例。.createApp()

    Vue 应用程序现在被视为根组件,因此您定义其数据选项的方式也发生了变化。

    HTML 根元素尚未更改,因此在索引.html文件中,您仍将看到如下内容:

    <div id="app"></div>

    在 JavaScript 文件中,您需要了解一个重要的更改:您将不再用于创建新的应用程序实例,而是使用一个名为:new Vue()createApp()

    1. // Vue 3 syntax
    2. const app = Vue.createApp({
    3. // options object
    4. })
    5. app.mounth('#app') // Vue Instance - Root component
    6. // Vue 2 syntax
    7. const app = new Vue({
    8. // options object
    9. el: '#app'
    10. })

    如何在 Vue 3 中定义组件

    要在 Vue 3 中定义组件,请不再使用 。相反,您现在使用应用程序根组件,如下所示:Vue.component()

    1. /* Vue 3 syntax */
    2. const app = Vue.createApp({
    3. // options here
    4. })
    5. app.component('componenet-name', {
    6. // component code here
    7. })
    8. /* Vue 2 syntax*/
    9. Vue.component('component-name', {
    10. // component code here
    11. })

    如何在 Vue 3 中使用数据选项对象

    假设主应用实例现在被视为根组件,则无法再将数据属性指定为对象。相反,您需要将其定义为返回对象的函数,就像通常在组件中所做的那样。

    1. // Vue 3
    2. const app = Vue.createApp({
    3. // options object
    4. data(){
    5. return {
    6. message: 'hi there'
    7. }
    8. }
    9. })
    10. app.mounth('#app') // Vue Instance - Root component
    11. // Vue 2 syntax
    12. const app = new Vue({
    13. // options object
    14. el: '#app'
    15. data: {
    16. message: 'hi there'
    17. }
    18. })

    Vue 3 中 v-if/v-for 的优先级更改

    在 Vue 2 中,如果在同一元素上使用了两个指令,则 v-for 指令将优先于 v-if。但是在 Vue 3 中,v-if 总是优先。

    但是,使用这两个指令并不是一个好主意。请务必访问此处的文档以了解更多信息。

    如何在 Vue 3 中的组件事件上使用 Emits 属性(重大更改/新功能)

    与该属性类似,现在在 Vue 3 中,还有一个属性,组件可以使用该属性来声明它可以向父组件发出的事件。propsemits

    我强烈建议使用此属性,以避免在需要重新发出本机事件(如单击事件)的组件中两次发出事件。

    以下是官方文档中的示例:

    1. <template>
    2. <div>
    3. <p>{{ text }}</p>
    4. <button v-on:click="$emit('accepted')">OK</button>
    5. </div>
    6. </template>
    7. <script>
    8. export default {
    9. props: ['text'],
    10. emits: ['accepted']
    11. }
    12. </script>

    emits 属性也可以接受对象。

    我现在还不会深入探讨这个问题,但我保证迟早会在专门的视频系列中解决每个功能/变化。

    Vue 路由器 v4.x 概述

    随着 Vue.js 的新版本发布,我们也有了新版本的 Vue Router。新版本 v4.x 有一些重大更改,如果你想将项目迁移到新的 Vue 版本,你需要考虑这些更改。

    Vue 路由器 V4 重大更改

    两个重大更改特别值得一提,因为它们位于 Vue 路由器应用程序的基础。稍后需要了解它们才能迁移应用程序。

    • Vue 路由器实例已更改
    • 有一个新的历史记录选项

    此处提供了更改的完整列表。

    让我们深入看看这两个变化。

    Vue 路由器 4 实例已更改

    要创建新的 Vue 路由器实例,请不再使用 VueRuter 函数构造函数。

    以下是 Vue Router v.3x 文档,因此您可以进行比较。

    代码由以下原因更改:

    1. // 3. Create the router instance and pass the `routes` option
    2. // You can pass in additional options here, but let's
    3. // keep it simple for now.
    4. const router = new VueRouter({
    5. routes // short for `routes: routes`
    6. })
    7. // 4. Create and mount the root instance.
    8. // Make sure to inject the router with the router option to make the
    9. // whole app router-aware.
    10. const app = new Vue({
    11. router
    12. }).$mount('#app')

    对此:

    1. // 3. Create the router instance and pass the `routes` option
    2. // You can pass in additional options here, but let's
    3. // keep it simple for now.
    4. const router = VueRouter.createRouter({
    5. // 4. Provide the history implementation to use. We are using the hash history for simplicity here.
    6. history: VueRouter.createWebHashHistory(), // <-- this is a new property and it is mandatory!
    7. routes, // short for `routes: routes`
    8. })
    9. // 5. Create and mount the root instance.
    10. const app = Vue.createApp({})
    11. // Make sure to _use_ the router instance to make the
    12. // whole app router-aware.
    13. app.use(router)
    14. app.mount('#app')

    在上面的代码中,要创建新的 Vue 路由器实例,您现在必须使用 VueRouter 对象并调用该方法。createRouter()

    此外,新的历史记录属性是必需的 – 。您必须定义它,否则将收到控制台错误。history: VueRouter.createWebHashHistory()

    接下来,您将使用该方法创建 Vue 实例,并使用变量来调用该方法。您将您在上一步中创建的路由器实例传递到该位置。createApp()app.use()

    最后,您可以使用 在应用程序实例上挂载根 DOM 元素。app.mount('#app')

    你可以阅读 Vue 路由器 v4.x 文档了解更多详情。

    路由的变化:

    main.js

    1. // create and mount the Vue instance
    2. const app = new Vue({
    3. router
    4. }).$mount('#app')

    对此:

    1. // create and mount the Vue instance
    2. const app = Vue.createApp({
    3. router
    4. })
    5. app.mount('#app')

    Vue 路由器的实例化方式已更改

    它从这个变化:

    1. // create the router instance
    2. const router = new VueRouter({
    3. routes
    4. })

    对此:

    1. // create the router instance
    2. const router = VueRouter.createRouter({
    3. // Provide the history implementation to use. We are using the hash history for simplicity here.
    4. history: VueRouter.createWebHashHistory(),
    5. routes, // short for `routes: routes`
    6. })

    上面的代码处理两个主要更改:已替换为 ,新选项现在将替换 。new VueRouter()VueRouter.createRouter()historymode

    请访问 Vue 路由器 4 的文档以了解更多信息。

    最后,让我们的应用程序知道我们正在使用 Vue 路由器。如果我们在 Vue 应用程序中注入了路由器实例,现在我们需要指示它使用 Vue 路由器,使用该方法执行此操作,并将路由器实例传递给它。.use()

    由此更改:

    1. // create and mount the Vue instance
    2. const app = Vue.createApp({
    3. router
    4. })
    5. app.mount('#app')

    对此:

    1. // create and mount the Vue instance
    2. const app = Vue.createApp({})
    3. app.use(router)
    4. app.mount('#app')

  • 相关阅读:
    Java竞赛快速输入输出,防止读取数据过慢导致超时
    Postman使用简介
    护理教育学-简答题
    CDH大数据平台 31Cloudera Manager Console之impala hive负载均衡(markdown新版)
    【软件安装】Linux中RabbitMQ的安装
    HR们,快看这是不是你想要的办公神器!
    ftpClient.listFiles()一直无法获取ftp上的目录文件
    HarmonyOS 应用生命周期有哪些? 按返回键会调用哪些生命周期?
    python自动化测试(二):xpath获取元素
    电脑重装系统后DirectX12旗舰版禁用了怎么解决?
  • 原文地址:https://blog.csdn.net/qq_22182989/article/details/125253780