Vue学习记录之基础篇——vue3基础之语法及新增特性

39 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

vue2 -- vue3 的升级 可以拆分成几个方面,我们可以从这几点开分析, 响应式、DIFF、语法(API)、新增特性、生态, 下面咱们就先逐一查看他都更新了哪些东西, 不过有一些是 破坏式更新,咱们可以留到最后一起搞他

语法

vue3 的语法大部分其实还是复用了 vue2 的语法, 我们主要从下面这几个点 开进行学习

  • ref ref 可以创建一个响应式对象,需要通过 .value 访问原始值, 当我们传入复杂数据类型的时候, 底层会调用 reactive
  • isRef() 检测某个值是否为 ref
  • toRef() 基于响应式对象 创建一个对应的 ref, 相当于解构响应式对象里面的某一个属性,而不破坏响应式
  • reactive

不论是哪种写法,我们都可以在 script 上 增加 lang="ts” 用以支持我们的 ts

组合式 API

  • 组合式 有两种写法
  • 写法一:
<template>
    <div class="app">
    </div>
</template>

<script lang="ts">
import { defineComponent,ref } from 'vue';
export default defineComponent({
    name:'' // 组件名
    props:{ 
    type: String,
    size: [Number, String],
    source: {
            type: Object,
            required: true,
        },
    }
    components: {
        ,
    },
    setup(props,context){
        // 代码逻辑
        const count = ref(0)
        reutrn{
        // 需要再模板中访问的数据
         count
        }
    }
});
</script>

这种写法也是需要配置的,包括我们的 组件, watch ,computed 等,这其中 refreactive 的区别 我会在后面的进阶篇中和大家分享

  • 写法二:
<script setup> 
import { ref } from 'vue' const count = ref(0) 
import empty from '@/components/common/empty/index.vue';

</script>

这种写法不需要我们 进行配置, 导入的组件也不需要注册,我们声明的变量直接可以在模板中使用, 如果使用 vue2 开发的时间比较长,可以先使用写法一进行过渡

注意点

    1. 在 setup 中是没有 this 的, 其中的 this 是 undefined
    1. 解构 props 会丢失响应式,可以使用 点语法访问,或使用 toRef
    1. setup 的第二个参数 context 上下文对象包含了 emit slots attrs 和 expose 四种属性(非响应式)
    1. setup 可以返回渲染函数,这一点在其源码上,对返回值的类型做了判断,如果返回的是一个函数,就会执行这个函数,返回的是对象,就会将对象中的key进行包装(响应式),后面我们进阶的时候会重点分享一下这里,这里也可以实现 jsx 的配合

生命周期

<script setup> 
import { ref, onUpdated } from 'vue' 
const count = ref(0) 
onUpdated(() => { 
console.log(document.getElementById('count').textContent) }) 
</script> 
<template> <button id="count" @click="count++">{{ count }}</button> 
</template>
  • 组合式API 中的生命周期不同于之前 vue2 的, 没有了 beforeCreate 和 created, 因为这两个生命周期的执行时机 就相当于我们 setup 函数,其他的生命周期需要我们引入,语法上前面加了 on开头, 我们在写接口请求的时候, 是可以直接写在 setup 上的, 可以使用 then 语法, 也可以使用 await, 下面看一下如何在 setup 中使用 await:
// 第一种方式,我们可以生命一个函数,这个函数使用 async , watch 的回调也可以是 async
setup(){
    const demo = asynv () => { await *** }
    watch(count,async () => { await *** })
}
// 第二种方式 IIFE
setup(){
    (async () => {
        const data = await getDraftTotalApi({
            sourceId: 2,
        });
        draft_sum.value = data.total;
    })();
}
// 第三种方式 顶层 await
这种方式只能在我们的语法糖中使用 结果代码会被编译成 `async setup()`:, async setup 的写法,只能与 suspense 内置组件组合使用,且处于实验阶段。
<script setup> 
await P
</script>

选项式 API

<script setup>
import { mapState, mapMutations } from 'vuex'
import { Fold } from '@element-plus/icons-vue';
defineProps({
  msg: {
    type: String,
    required: true
  }
})
export default {
  data() {
    return {
      squareUrl: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
    }
  },
  components: {
    Fold
  },
  computed: {
    ...mapState(['username'])
  },
  methods: {
    ...mapMutations(['updateUsername', 'updataRole', 'updateCheckedkeys']),
    loginOut() {
    }
  }
}
</script>

选项式的这种写法 其实和 vue2 基本上就没有什么区别了,生命周期的配置也是没有改变的

新增特性

  • Teleport 内置组件 可以将一个组件内部的一部分模板“传送”到该组件的 DOM 结构外层的位置去。 听起来很简单,使用的时候,应用在模态框的场景可能会多一下,比如我们封装了一个弹窗,这个弹窗在我们封装的组件文件中,但我们最终想让这个弹窗层级实在 body下面, 就可以通过这个内置组件来实现,但是一般在我们使用 组件库的时候,组件库的 model 都会带这种配置项。
// `to` 的值可以是一个 CSS 选择器字符串,也可以是一个 DOM 元素对象。
<button @click="open = true">打开弹窗</button> 
<Teleport to="body"> 
<div v-if="open" class="modal"> 
<p>通过 to 指定父级的弹窗</p>
<button @click="open = false">关闭</button>
</div>
</Teleport>
  • Fragments 片段 vue2 不支持多根节点, vue3 的模板中则可以使用多个, 可以 显式定义 attribute, 多跟节点不能进行透传(比如 calss, 会自行继承 合并), 链接: cn.vuejs.org/guide/compo…
  • 单文件组件中状态驱动的 css 变量(style 中的 v-bind)
<script setup>
const theme = { color: 'red' } 
</script> 
<template> <p>hello</p> 
</template>
<style scoped> 
p { color: v-bind('theme.color'); } 
</style>

还有一些新特性我们在项目中不常用到 大家可以访问链接自行查看
v3-migration.vuejs.org/zh/