我是靠谱客的博主 贪玩乌龟,这篇文章主要介绍Vue3 开发的避坑经验 对比Vue2,现在分享给大家,希望可以做个参考。

1. vue3 生命周期变化,使用script-setup模式

2.x生命周期3.x生命周期执行时间说明
beforeCreatesetup组件创建前执行
createdsetup组件创建后执行
beforeMountonBeforeMount组件挂载到节点上之前执行
mountedonMounted组件挂载完成后执行
beforeUpdateonBeforeUpdate组件更新之前执行
updatedonUpdated组件更新完成之后执行
beforeDestroyonBeforeUnmount组件卸载之前执行
destroyedonUnmounted组件卸载完成后执行
errorCapturedonErrorCaptured当捕获一个来自子孙组件的异常时激活钩子函数
复制代码
1
2
3
4
5
6
7
8
9
<script setup lang="ts"> import { ref, onMounted } from "vue"; const count = ref<number>(0); onMounted(() => { count.value = 1; }) </script>

2. vue3 使用 vite 引用本地图片

  1. 使用import
复制代码
1
2
3
4
5
6
7
8
<template> <img :src="xxx"> </template> <script setup lang="ts"> import xxx from '@/assets/images/xxx.png'; </script>
  1. 在assets前面加一个src
复制代码
1
2
3
4
5
6
7
8
<template> <img :src="xxxIcon"> </template> <script setup lang="ts"> const xxxIcon = new URL(`/src/assets/images/xxx.png`, import.meta.url).href; </script>

3. vue3 怎么使用this.$refs.xxx的使用

  1. 第一种方式
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<template> <div ref="test"> this is test </div> </template> <script setup lang="ts"> import { ref, onMounted } from "vue"; const test = ref(null); onMounted(() => { console.log(test.value); // <div>this is test</div> }); </script>
  1. 第二种方式
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template> <div v-for="(item, idx) in list" :ref="(el) => getCurRefs(el, `xxx_${idx}`)" @click="onClick(idx)"> {{ item }} </div> </template> <script setup lang="ts"> import { ref, reactive } from 'vue'; const list = ref([1, 2, 3]); const refArr = reactive({}); const getCurRefs = (el: any, id: string) => { refArr[id] = el; }; const onClick = (idx) => { console.log(refArr[`xxx_${idx}`]); }; </script>

4. vue3 组件传值

<script setup> 中必须使用 definePropsdefineEmits API 来声明 props 和 emits ,它们具备完整的类型推断并且在 <script setup> 中是直接可用的

子组件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<script setup lang="ts"> // 1.接收父组件传值 const props = defineProps<{ foo: string, bar?: number, }>(); // 2.想要设置默认值,通过 withDefaults 编译器宏 interface Props { msg?: string, labels?: string[], }; const props = withDefaults(defineProps<Props>(), { msg: 'hello', labels: () => ['one', 'two'], }); console.log(props.msg) // hello // 抛出事件 const emit = defineEmits<{ (e: 'change', id: number): void, (e: 'update', value: string): void, }>(); const click = () => { emit('change', 1); emit('update', 'abc'); }; const name = ref("xxxx"); defineExpose({ name }); // 显式暴露的数据,父组件才可以获取 </script>
复制代码
1
2
3
4
5
6
7
8
9
<script setup> // 非ts const props = defineProps({ foo: String, }) const emit = defineEmits(['change', 'delete']); </script>

父组件:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template> <div> <child ref="child" :msg="'传递的值'" @change="change"/> </div> </template> <script setup lang="ts"> let child = ref(null); console.log(child.value.name); //获取子组件中 name 的值为 xxxx const change = (val: number) => { console.log(val); }; </script>

5. vue3 的 ref 和 reactive

  • reactive() 函数接收一个普通的对象,返回出一个响应式对象。
  • ref() 函数可以根据给定的值来创建一个响应式的数据对象,返回值是一个对象,且只包含一个 .value 属性。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
<script setup lang="ts"> import { ref, reactive } from 'vue'; const count = ref(0); const arr = ref([]); const user = reactive({ id: 110, name: 'xxxx', }); </script>
  1. 在 setup() 函数内,由 ref() 创建的响应式数据返回的是对象,所以需要用 .value 来访问;而在 setup() 函数外部则不需要 .value ,直接访问即可。
  2. 可以在 reactive 对象中访问 ref() 函数创建的响应式数据。
  3. 新的 ref() 会覆盖旧的 ref()。

6. vue3 的 computed

复制代码
1
2
3
4
5
6
7
8
9
10
<script setup lang="ts"> import { computed } from 'vue'; const count = ref(1); const bigCount = computed(() => count.value + 1); console.log(bigCount.value) // 输出 2 bigCount.value++ // error 不可写 </script>

7. vue3 的 watch

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script setup lang="ts"> import { watch } from 'vue'; // 侦听一个 getter const state = reactive({ count: 0 }); watch(() => state.count, (count, prevCount) => { console.log(count, prevCount); }, ); // 直接侦听一个 ref const count = ref(0); watch(count, (count, prevCount) => { console.log(count, prevCount); }); </script>

8. 配置全局自定义参数

在 Vue2.x 中我们可以通过 Vue.prototype 添加全局属性 property。但是在 Vue3.x 中需要将 Vue.prototype 替换为 config.globalProperties 配置

复制代码
1
2
3
4
5
6
7
8
9
// Vue2.x Vue.prototype.$api = axios; Vue.prototype.$eventBus = eventBus; // Vue3.x const app = createApp({}); app.config.globalProperties.$api = axios; app.config.globalProperties.$eventBus = eventBus;

使用时需要先通过 vue 提供的 getCurrentInstance 方法获取实例对象:
警告:尽量不要使用 getCurrentInstance

复制代码
1
2
3
4
5
6
7
8
9
10
<script setup lang="ts"> import { ref, onMounted, getCurrentInstance } from "vue"; onMounted(() => { const instance = <any>getCurrentInstance(); const { $api, $eventBus } = instance.appContext.config.globalProperties; // do something }) </script>

9. v-model 变化

当我们在使用 v-model 指令的时候,实际上 v-bindv-on 组合的简写,Vue2.x 和 Vue3.x 又存在差异。

  • Vue2.x
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script> export default { model: { prop: 'value', event: 'change', }, props: { value: { type: [Array, String], required: true, }, }, methods: { xxx() { this.$emit('change', 'test); }, }, }; </script>
  • Vue3.x
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script setup lang="ts"> import { ref, onMounted, watch } from "vue"; const emit = defineEmits(['update:modelValue']); let curValue = ref(''); let props = withDefaults(defineProps<{ modelValue: string; }>(), { modelValue: '', }) onMounted(() => { // 先将 v-model 传入的 modelValue 保存 curValue.value = props.modelValue; }) watch(curValue, (newVal, oldVal) => { // 当 curValue 变化,则通过 emit 派发更新 emit('update:modelValue', newVal); }) </script>

10. router

  • Vue2.x
复制代码
1
2
3
4
5
const { path, params, query } = this.$route; this.$router.go(-1); this.$router.push('/');
  • Vue3.x
复制代码
1
2
3
4
5
6
7
8
<script setup lang="ts"> import { useRoute, useRouter } from 'vue-router'; const { path, params, query } = useRoute(); const router = useRouter(); router.push('/'); </script>

11. env环境变量

  • Vue2.x
复制代码
1
2
process.env.VUE_APP_BACKEND_DOMAIN
  • Vue3.x
  1. 使用方式一:
复制代码
1
2
3
4
<script setup lang="ts"> const domain = import.meta.env.VITE_APP_BACKEND_DOMAIN; </script>
  1. 使用方式二:
    vite.config.ts 使用方式为loadEnv(mode, process.cwd()).VITE_APP_SERVER_URL
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import { defineConfig, loadEnv } from 'vite'; import vue from '@vitejs/plugin-vue'; import { resolve } from 'path'; export default defineConfig(({ mode }) => { const VITE_APP_BACKEND_DOMAIN: string = loadEnv(mode, process.cwd()).VITE_APP_BACKEND_DOMAIN; return { plugins: [vue()], resolve: { //设置别名 alias: { '@': resolve(__dirname, './src'), }, }, server: { port: 8080, //启动端口 hmr: { host: '127.0.0.1', port: 8080, }, // 设置 https 代理 proxy: { '/api': { target: VITE_APP_BACKEND_DOMAIN, // 后端 api 地址 changeOrigin: true, rewrite: (path: string) => path.replace(/^/api/, ''), }, }, }, }; });
  1. 使用方式三:如果想在文件中继续使用process.env,可以在vite.config.ts 中进行配置
复制代码
1
2
3
4
5
6
7
8
9
import { defineConfig, loadEnv } from 'vite'; // https://vitejs.dev/config/ export default defineConfig(({ mode }) => { define: { 'process.env': loadEnv(mode, process.cwd()), }, });

使用如下

复制代码
1
2
const domain = process.env.VITE_APP_BACKEND_DOMAIN;

最后

以上就是贪玩乌龟最近收集整理的关于Vue3 开发的避坑经验 对比Vue2的全部内容,更多相关Vue3内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(72)

评论列表共有 0 条评论

立即
投稿
返回
顶部