vue3对编程写法的探讨

375 阅读2分钟

学习笔记

vue2的optionsApi之后,vue3迎来了Vue3 的 Composition API,用了好长时间,才从options的思维转变到Composition上来

Composition API

image.png

  • 按照vue的升级之后,就会发现,在一个界面里划分了各种小区域,以前写vue2的时候,全部写在一起,现在vue3的开发方式,建议我们把每种业务场景的数据进行统一规划,变成独立的个体,让他们相互独立,互不相属。
  • 这样划分区域后,你就可以只关心某一区域的逻辑就行了,把整体的代码复杂度降低,让代码更易阅读 在vue2中
<template>
    <div>
        <p>{{ person.name }}</p>
        <p>{{ car.name }}</p>
    </div>
</template>
<script>
    export default { 
        name: "Person", 
        data() { 
            return { 
                person: { 
                    name: "小明", sex: "male", 
                }, 
                car: { name: "宝马", price: "40w", }
            }
        }, 
        watch:{
            'person.name': (value) => { 
                console.log(`名字被修改了, 修改为 ${value}`)
            }, 
            'person.sex': (value) => { 
                console.log(`性别被修改了, 修改为 ${value}`) 
            } 
        }, 
        methods: { 
            changePersonName() { this.person.name = "小浪"; }, 
            changeCarPrice() { this.car.price = "80w"; } 
        }
   } 
</script>

在vue3中就变成了这样

<template>
  <p>{{ person.name }}</p>
  <p>{{ car.name }}</p>
</template>

<script lang="ts" setup>
import { reactive, watch } from "vue";

/**
 * person的逻辑
 */
const person = reactive<{ name: string; sex: string }>({
  name: "小明",
  sex: "male",
});
watch(
  () => [person.name, person.sex],
  ([nameVal, sexVal]) => {
    console.log(`名字被修改了, 修改为 ${nameVal}`);
    console.log(`名字被修改了, 修改为 ${sexVal}`);
  }
);
function changePersonName() {
  person.name = "小浪";
}

/**
 * car的逻辑
 */
const car = reactive<{ name: string; price: string }>({
  name: "宝马",
  price: "40w",
});
function changeCarPrice() {
  car.price = "80w";
}
</script>

把每一步都拆解开来,可是这样写代码,理论上应该是很清晰了,随着开发的开展又造成很难理解,因为每个程序员的经验的素质不一样,在统一个界面很容易出现混乱,导致更不容易阅读,随之又进行了改进,利用了官网的自定义hooks

<template>
  <p>{{ person.name }}</p>
  <p>{{ car.name }}</p>
  <p>{{ animal.name }}</p>
</template>

<script lang="ts" setup>
import { usePerson, useCar, useAnimal } from "./hooks";

const { person, changePersonName } = usePerson();

const { car } = useCar();
</script>

// usePerson.ts
import { reactive, watch } from "vue";

export default function usePerson() {
  const person = reactive<{ name: string; sex: string }>({
    name: "小明",
    sex: "male",
  });
  watch(
    () => [person.name, person.sex],
    ([nameVal, sexVal]) => {
      console.log(`名字被修改了, 修改为 ${nameVal}`);
      console.log(`名字被修改了, 修改为 ${sexVal}`);
    }
  );
  function changePersonName() {
    person.name = "小浪";
  }
  return {
    person,
    changePersonName,
  };
}

// useCar.ts
import { reactive } from "vue";

export default function useCar() {
  const car = reactive<{ name: string; price: string }>({
    name: "宝马",
    price: "40w",
  });
  function changeCarPrice() {
    car.price = "80w";
  }
  return {
    car,
    changeCarPrice,
  };
}

对比完之后,我们会发现,Vue3 可以让我们更好组织代码。personcar的逻辑都被单独放置在一块

仅仅是代码组织的优势吗?不不不,我们再看看模板中的一些变化

  • <template>标签中起始便签可以不用<div>标签,因为Vue3提供了片段的能力,使用Vue-detools中查看,可以看到有fragment的标记
    image.png
  • Watch也不需要罗列多个了,Vue3中支持侦听多个源
  • 很自然的使用TypeScript,类型约束更加简单

性能方面

Vue3 主要在这几个方面进行了提升

  1. 编译阶段。对 diff 算法优化、静态提升等等
  2. 响应式系统。Proxy()替代Object.defineProperty()监听对象。监听一个对象,不需要再深度遍历,Proxy()就可以劫持整个对象
  3. 体积包减少。Compostion API 的写法,可以更好的进行 tree shaking,减少上下文没有引入的代码,减少打包后的文件体积
  4. 新增片段特性。Vue 文件的<template>标签内,不再需要强制声明一个的<div>标签,节省额外的节点开销