Vue2转Vue3快速上手第一篇(共两篇)

简介: Vue2转Vue3快速上手

Vue3

v2-v3的学习成本不高,只要有v2基础,基本可以上手vue3

一、setup语法

setup中不能访问v2的配置比如data,methods等

二、ref响应数据

使用ref可以创建一个对象,可以是基本类型,也可以是对象

例如:

<template>
  <div class="home">
    <!-- 渲染 -->
  {{a}}
  </div>
</template>
<script>
import { ref} from 'vue'
export default {
  name: 'Home',
  setup(){
    // 创建
  const a = ref('')
    // 使用方法  xxx.value
  a.value = 'NanChen'
  return{
  a,
  }
  },
}
</script>

8c1fbe782d39479ca8ecd7b11190d711.png

三、reactive创建响应式数据

这是一个对象类型的响应数据,例:

<template>
  <div class="home">
    {{a.sex}}
    {{a.name}}
  </div>
</template>
<script>
import { reactive } from "vue";
export default {
  name: "Home",
  setup() {
    const a = reactive({
      sex: "",
      name: "",
    });
    a.sex = "男";
    a.name = "NanChen";
    return {
      a,
    };
  },
};
</script>

0fcb9205ed6a417bbe9c403256b8c0db.png

四、computed 计算属性

例:

<template>
  <div>
    <div>
      姓:{{per.firstName}}
    </div>
    <div>
      名:{{per.lastName}}
    </div>
    <div>
      加起来:{{per.fullName}}
    </div>
  </div>
</template>
<script>
import { reactive, computed } from "vue";
export default {
  setup() {
    let per = reactive({
      firstName: "Nan",
      lastName: "Chen",
    });
    per.fullName = computed(() => {
      return per.firstName + "++" + per.lastName;
    });
    return {
      per,
    };
  },
};
</script>
<style>
</style>

714b6fa9b3164437b1b9e0eca760a08a.png

五、watch 监听器

例(一):监听单个ref的响应式数据

<template>
  <div>
  监听<button @click="num++">+1查看监听器变化</button>
  <div>{{num}}</div>
  </div>
</template>
<script>
import { ref, watch } from "vue";
export default {
  setup() {
  let num = ref(0);
  watch(num,(newValue,oldValue)=>{
  console.log('newValue: '+newValue,' oldValue: '+oldValue);
  })
  return{
  num
  }
  },
};
</script>

7013e821941f4d9b9f5cc37ec595043b.gif

例(二):监听ref定义的多个响应式数据

<template>
  <div>
    <div>
      <button @click="num++">+1查看监听器变化</button>
      <div>num:{{num}}</div>
    </div>
    <div>
      <button @click="num2+='改动了'">改变</button>
      <div>num2:{{num2}}</div>
    </div>
  </div>
</template>
<script>
import { ref, watch } from "vue";
export default {
  setup() {
    let num = ref(0);
    let num2 = ref("监听多个ref响应式的使用");
    watch(
      [num, num2],
      (newValue, oldValue) => {
        console.log("num and num2 ", newValue, oldValue);
      },
      /* immediate:第一次就监听 */
      { immediate: true }
    );
    return {
      num,
      num2,
    };
  },
};
</script>

894c78f988b6443380766feaf5bc177c.gif

例(三):监听reactive所定义的一个响应式数据

<template>
  <div>
    <div>
      <button @click="a.name+='XX'">更改姓名</button>
      <div>{{a.name}}</div>
    </div>
    <div>
      <button @click="a.age++">更改年龄</button>
      <div>{{a.age}}</div>
    </div>
  </div>
</template>
<script>
import { reactive, watch } from "vue";
export default {
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
    });
     watch(a,(newValue, oldValue) => {
        console.log(newValue, oldValue);
      },{immediate:true,deep:false}//deep无效
    );
    return {
      a,
    };
  },
};
</script>

d60c4f8c26264c309b725561de7ac593.png

例(四):监听reactive定义的一个响应式数据中的某一个属性

<template>
  <div>
    <div>
      <button @click="a.name+='XX'">更改姓名</button>
      <div>{{a.name}}</div>
    </div>
    <div>
      <button @click="a.age++">更改年龄</button>
      <div>{{a.age}}</div>
    </div>
  </div>
</template>
<script>
import { reactive, watch } from "vue";
export default {
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
    });
    watch(() => a.name,(newValue, oldValue) => {
        console.log(newValue, oldValue);
      }
    );
    return {
      a,
    };
  },
};
</script>

32fd6fcdd6134c069848993b788503c8.png

例(五):监听reactive定义的一个响应式数据中的某些属性

<template>
  <div>
    <div>
      <button @click="a.name+='XX'">更改姓名</button>
      <div>{{a.name}}</div>
    </div>
    <div>
      <button @click="a.age++">更改年龄</button>
      <div>{{a.age}}</div>
    </div>
  </div>
</template>
<script>
import { reactive, watch } from "vue";
export default {
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
    });
    watch([() => a.name, () => a.age],(newValue, oldValue) => {
        console.log(newValue, oldValue);
      }
    );
    return {
      a,
    };
  },
};
</script>

6bd51a82aa3c410a840518910e746473.png

例(六):监听reactive定义的嵌套对象

<template>
  <div>
    <div>
      <button @click="a.name+='XX'">更改姓名</button>
      <div>{{a.name}}</div>
    </div>
    <div>
      <button @click="a.age++">更改年龄</button>
      <div>{{a.age}}</div>
    </div>
    <div>
      <button @click="a.obj.objList.num++">更改数字</button>
      <div>{{a.obj.objList.num}}</div>
    </div>
  </div>
</template>
<str>
import { reactive, watch } from "vue";
export default {
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
      obj: {
        objList: {
          num: 100,
        },
      },
    });
    watch(() => a.obj,(newValue, oldValue) => {
        console.log(newValue, oldValue);
      },{ deep: true }); // 这里是坚挺的reactive对象中的某个属性,因此deep生效
    // deep:其值是true或false;确认是否深入监听。(一般监听时是不能监听到对象属性值的变化的,数组的值变化可以听到。
    return {
      a,
    };
  },
};
</script>

1cb06a0d933a45f6a9bd81dc754af6c7.png

六、watchEffect 监听器

特性,也可以说成和watch的区别

不需要手动传入依赖

每次初始化时会执行一次回调函数来自动获取依赖

无法获取到原值,只能得到变化后的值

<template>
  <div>
    <div>
      <button @click="a.name+=' hello'">更改姓名</button>
      <div>{{a.name}}</div>
    </div>
    <div>
      <button @click="a.age++">更改年龄</button>
      <div>{{a.age}}</div>
    </div>
  </div>
</template>
<script>
import { reactive, watchEffect } from "vue";
export default {
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
    });
    watchEffect(() => {
      console.log(a.name);
      console.log(a.age);
    });
    setTimeout(() => {
      a.name += " hi";
      a.age++;
    }, 1000);
    return {
      a,
    };
  },
};
</script>

81323b2562e64d97a532d18746b2793b.png

七、Vue3生命周期

所有的声明周期要放在setup中

Vue3的生命周期如下:

1、beforeCreate -> 使用 setup()

2、created -> 使用 setup()

3、beforeMount -> onBeforeMount

4、mounted -> onMounted

5、beforeUpdate -> onBeforeUpdate

6、updated -> onUpdated

7、beforeDestroy -> onBeforeUnmount

8、destroyed -> onUnmounted

9、errorCaptured -> onErrorCaptured

语法

setup() {
    onMounted(() => {
      console.log('mounted')
    })
}

八、toRef

说白话文就是不用写前面的对象名称直接渲染里面的属性即可

<template>
  <div>
    <div>{{name}}</div>
    <div>{{age}}</div>
    <div>{{num}}</div>
  </div>
</template>
<script>
import { reactive, toRef } from "vue";
export default {
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
      list: {
        num: 0,
        num1: 1,
        num2: 2,
        num3: 3,
        num4: 4,
      },
    });
    return {
      name: toRef(a, "name"),
      age: toRef(a, "age"),
      num: toRef(a.list, "num"),
    };
  },
};
</script>

81110f52313a4f2abc343e5c79c1f345.png

九、toRefs 响应式转换

一键给对象中的多个属性全部响应转换

<template>
  <div>
    <div>{{name}}</div>
    <div>{{age}}</div>
    <div>{{num}}</div>
    <div>{{num1}}</div>
    <div>{{num2}}</div>
    <div>{{num3}}</div>
    <div>{{num4}}</div>
  </div>
</template>
<script>
import { reactive, toRefs } from "vue";
export default {
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
      list: {
        num: 0,
        num1: 1,
        num2: 2,
        num3: 3,
        num4: 4,
      },
    });
    return {
      ...toRefs(a),
      ...toRefs(a.list),
    };
  },
};
</script>

ad55f496229d4e39b2d5822c586335fd.png

十、shallowReactive (浅响应式)

只处理对象最外面一层的响应式数据(浅响应式)

<template>
  <div>
    <h1>姓:{{name}}</h1>
    <h2>岁数:{{age}}</h2>
    <h3>对象{{obj.objList.name}}</h3>
    <button @click="name += '+'">修改姓名</button>
    <button @click="age++">修改年龄</button>
    <button @click="obj.objList.name += '!'">修改对象</button>
  </div>
</template>
<script>
import { reactive, toRefs, shallowReactive } from "vue";
export default {
  name: "App",
  setup() {
    // 定义了一段数据
    let a = shallowReactive({
      // 只将第一层数据做了响应式处理
      name: "NanChen",
      age: 20,
      obj: {
        objList: {
          name: "Jia", // 深层次的数据将会是一个普通的对象
        },
      },
    });
    // 将数据返回出去
    return {
      ...toRefs(a),
    };
  },
};
</script>

b4c1e071342640c4b55a977a2679730b.gif

十一、shallowRef 不进行对象响应式

只处理基础数据类型的响应式,不进行对象类型的响应式。

<template>
  <div>
    <h1>姓:{{a}}</h1>
    <button @click="a += '+'">修改姓名</button>
    <h2>{{b.num}}</h2>
    <button @click="b++">修改num</button>
  </div>
</template>
<script>
import { shallowRef } from "vue";
export default {
  name: "App",
  setup() {
    // 定义了一段数据
    let a = shallowRef("NanChen");
    let b = shallowRef({
      num: 1,
    });
    console.log(b.value.num);
    // 将数据返回出去
    return {
      a,
      b,
    };
  },
};
</script>

8f64bacb87334971a189e406995945c3.gif

这里可以看到,修改数据后将不会在触发页面的更新 因为监测不到了

十二、readonly(深只读)

const a = shallowRef({
  name: 'NanChen', // 只读
  obj: {
    objList: 2 // 也是只读
  }
})

十三、shallowReadonly(浅只读)

const a = shallowReadonly({
  name: 'NanChen', // 只读
  obj: {
    objList: 2 // 不是只读
  }
})

十四、toRaw 将响应式对象转换成普通对象

例:

<template>
  <h2>姓名:{{a.name}}</h2>
  <h2>年龄:{{a.age}}</h2>
  <button @click="showRawA">点我显示原始a</button>
</template>
<script>
import { reactive, toRaw } from "vue";
export default {
  name: "Demo",
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
    });
    function showRawA() {
      console.log("a=", a);
      let p = toRaw(a);
      console.log("raw a = ", p);
    }
    return {
      a,
      showRawA,
    };
  },
};
</script>

98bdb95a348b4c7f9b706949cb4e4d26.jpg

这里可以看到使用toRaw后,响应式对象变成了一个普通的对象

十五、markRaw 永久不响应

这里看一下使用markRaw和不使用markRaw的区别

不使用markRaw

看这个例子:

<template>
  <h2>姓:{{a.name}}</h2>
  <div v-if="a.other" style="border: 1px solid #000;width: 200px;padding: 10px;margin-bottom: 10px;">
    <h3>开发岗位:{{a.other.kaifa}}</h3>
    <h3>待遇:{{a.other.money}}K</h3>
    <button @click="changeOne">更换工程师</button>&nbsp;
    <button @click="changeTwo">加薪资</button>
  </div>
  <button @click="addOther">添加信息</button>
</template>
<script>
import { reactive } from "vue";
export default {
  name: "Demo",
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
    });
    function addOther() {
      a.other = {
        kaifa: "web开发",
        money: 1,
      };
    }
    function changeOne() {
      a.other.kaifa = "java开发";
    }
    function changeTwo() {
      a.other.money++;
    }
    return {
      a,
      addOther,
      changeOne,
      changeTwo,
    };
  },
};
</script>

效果:

97ee3f5e5d474b4589bc1d3bf9bb1b74.gif

可以看到这里的数据是可以进行响应

添加markRaw

<template>
  <h2>姓名:{{a.name}}</h2>
  <div v-if="a.other" style="border: 1px solid #000;width: 200px;padding: 10px;margin-bottom: 10px;">
    <h3>开发岗位:{{a.other.kaifa}}</h3>
    <h3>待遇:{{a.other.money}}K</h3>
    <button @click="changeOne">更换工程师</button>&nbsp;
    <button @click="changeTwo">加薪资</button>
  </div>
  <button @click="addOther">添加信息</button>
</template>
<script>
import { reactive, markRaw } from "vue";
export default {
  name: "Demo",
  setup() {
    let a = reactive({
      name: "NanChen",
      age: 20,
    });
    function addOther() {
      a.other = markRaw({
        kaifa: "web开发",
        money: 1,
      });
    }
    function changeOne() {
      a.other.kaifa = "java开发";
    }
    function changeTwo() {
      a.other.money++;
    }
    return {
      a,
      addOther,
      changeOne,
      changeTwo,
    };
  },
};
</script>

效果:

7a36e15c62d4474f92b2effef2d7bf2e.gif

因为markRaw将{kaifa: “web开发”,money: 1,}变成了一个非响应式对象。因此,当修改 a.other.kaifa 或 a.other.money时,界面不会更新

十六、provide / inject

在组合式 API 中使用 provide/inject,两个只能在 setup 期间调用

provide 函数是有两个接受参数,是用来提供和发送数据

provide(name,value)

祖先组件:

import { provide,reactive } from "vue"
export default {
  setup(){
    let obj = reactive({
        name:'NanChen',
        age:20
    }
    provide('obj',obj)
  }
}

inject则是用来接受数据

后代组件:

import { inject } from "vue"
export default {
  setup(){
    const obj = inject('car')
    return{obj}
  }
}

十七、isRef

判断值是否为ref对象

let name = ref('NanChen')
console.log(isRef(name)); // true

十八、isReactive

判断值是否为isReactive对象

let num = isReactive({})
console.log(isRef(val)); // true

十九、inReadonly

检查对象是否是由readonly创建的只读代理

const state = reactive({
  name: 'NanChen'
})
console.log(isReactive(state)) // true

二十、isProxy

检查对象是否是由reactive或者readonly创建的proxy

const state = reactive({
  name: 'NanChen'
})
console.log(isProxy(state)) // true


相关文章
|
16天前
|
JavaScript 前端开发 安全
Vue 3
Vue 3以组合式API、Proxy响应式系统和全面TypeScript支持,重构前端开发范式。性能优化与生态协同并进,兼顾易用性与工程化,引领Web开发迈向高效、可维护的新纪元。(238字)
397 139
|
10天前
|
缓存 JavaScript 算法
Vue 3性能优化
Vue 3 通过 Proxy 和编译优化提升性能,但仍需遵循最佳实践。合理使用 v-if、key、computed,避免深度监听,利用懒加载与虚拟列表,结合打包优化,方可充分发挥其性能优势。(239字)
108 1
|
2月前
|
开发工具 iOS开发 MacOS
基于Vite7.1+Vue3+Pinia3+ArcoDesign网页版webos后台模板
最新版研发vite7+vue3.5+pinia3+arco-design仿macos/windows风格网页版OS系统Vite-Vue3-WebOS。
270 11
|
6月前
|
缓存 JavaScript PHP
斩获开发者口碑!SnowAdmin:基于 Vue3 的高颜值后台管理系统,3 步极速上手!
SnowAdmin 是一款基于 Vue3/TypeScript/Arco Design 的开源后台管理框架,以“清新优雅、开箱即用”为核心设计理念。提供角色权限精细化管理、多主题与暗黑模式切换、动态路由与页面缓存等功能,支持代码规范自动化校验及丰富组件库。通过模块化设计与前沿技术栈(Vite5/Pinia),显著提升开发效率,适合团队协作与长期维护。项目地址:[GitHub](https://github.com/WANG-Fan0912/SnowAdmin)。
865 5
|
25天前
|
JavaScript 安全
vue3使用ts传参教程
Vue 3结合TypeScript实现组件传参,提升类型安全与开发效率。涵盖Props、Emits、v-model双向绑定及useAttrs透传属性,建议明确声明类型,保障代码质量。
174 0
|
3月前
|
缓存 前端开发 大数据
虚拟列表在Vue3中的具体应用场景有哪些?
虚拟列表在 Vue3 中通过仅渲染可视区域内容,显著提升大数据列表性能,适用于 ERP 表格、聊天界面、社交媒体、阅读器、日历及树形结构等场景,结合 `vue-virtual-scroller` 等工具可实现高效滚动与交互体验。
361 1
|
3月前
|
缓存 JavaScript UED
除了循环引用,Vue3还有哪些常见的性能优化技巧?
除了循环引用,Vue3还有哪些常见的性能优化技巧?
194 0
|
4月前
|
JavaScript
vue3循环引用自已实现
当渲染大量数据列表时,使用虚拟列表只渲染可视区域的内容,显著减少 DOM 节点数量。
120 0
|
6月前
|
JavaScript 前端开发 API
Vue 2 与 Vue 3 的区别:深度对比与迁移指南
Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架,在过去的几年里,Vue 2 一直是前端开发中的重要工具。而 Vue 3 作为其升级版本,带来了许多显著的改进和新特性。在本文中,我们将深入比较 Vue 2 和 Vue 3 的主要区别,帮助开发者更好地理解这两个版本之间的变化,并提供迁移建议。 1. Vue 3 的新特性概述 Vue 3 引入了许多新特性,使得开发体验更加流畅、灵活。以下是 Vue 3 的一些关键改进: 1.1 Composition API Composition API 是 Vue 3 的核心新特性之一。它改变了 Vue 组件的代码结构,使得逻辑组
1602 0
|
2月前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
234 2