Vue3 新特性

1 篇文章 0 订阅

目录

组合式 API (Composition API)

什么是组合式API

 组合式 API 全景

独立的组合式函数

End


都有哪些新增特性 

序号特性解析
1Composition API组合式 API 类似 React Hooks
2Tree shaking support支持摇树优化按需编译,体积更加轻量化
3Better TypeScript support对 Ts 提供了更好的支持
4Performance性能上比 Vue2.x 快1.3 - 2 倍
5Custom Renderer API暴露了自定义渲染 API
6Fragment, Teleport, Suspense新增的更先进组件
7Provide / Inject依赖注入变更
8一些其他变更模板指令、生命周期、移除 API、全局API

组合式 API (Composition API)

什么是组合式API

  • Composition API 主要灵感来源于 React Hooks,目的是通过一组低侵入式的、函数式的 API,使得能够更灵活地「组合」组件的逻辑。
  • 不再传入 data、methods、mounted 等参数,通过引入的 ref、onMounted 等方法实现数据的双向绑定、生命周期函数的执行

为什么需要

        在组件比较复杂的情况下,代码被选项式API 强行分隔、下面来自官方的一张对比图:

 

  • 上图在大型组件的示例中,其中逻辑关注点按颜色进行分组, 这种碎片化使得理解和维护复杂组件变得繁琐。选项的分离掩盖了潜在的逻辑问题。此外,在处理单个逻辑关注点时,我们必须不断地“跳转”相关代码的选项块。

  • 更好的进行复用、使用组合式 API 能够将同一个逻辑关注点相关代码收集在一起, 所有的方法都是引入的,可以将单独某个逻辑进行封装。

  • 更好的typescript支持。不会再往vue原型上添加很多内容,而是通过引入的方式,类型定义会更清晰。

怎么使用

        新增一个全新的属性 setup 它是在组件创建之前执行、一旦 props 被解析,就将作为组合式 API 的入口

        Vue2.x 实际上等价于 版本的 beforeCreate 和 Created 这两个生命周期,setup 返回的是一个对象,里面的所有被返回的属性值,都会被合并到 Vue2.x 的 render 渲染函数里面

        setup 选项接收 props 和 context 参数的函数

        props 是父子组件传递的参数、第二个参数是上下文对象在Vue2.x 中需要通过 this 才能访问到、需要注意的是在setup中是不可以使用 this。

 组合式 API 全景

Vue 组合式 API 可以分为五大块:

  1. 数据响应(引用类型):响应性 API 基础,支持复杂对象 Object、Array 的数据响应;

  2. 数据响应(基础类型):内部值指 JS 内置的简单数据结构,包括 String、Number 等;

  3. computed 和 watch:基于 Ref 的数据计算与监听;

  4. 生命周期:对原生命周期封装;

  5. 其他 API:重要支持性 API;

// Vue3.0
export default {
  components: { RepositoriesList },
  props: {
    user: {
      type: String,
      required: true
    }
  },
  
  setup(props) {
    const { user } = toRefs(props);
    const count = ref('lulu');
    const members = reactive({
    	name: 'lucy',
      	age: 14
    })
    
    // watch
    watch([count, members], (next, prev) => {
    	console.log("next", next, "prev", prev);
    },{ deep: true });

    // computed
    const double = computed(() => {
      return count.value * 2;
    });
    
    const fn = ()=>{ console.log('函数')};
    
    return {
      	user,
    	count,
      	members,
      	double,
      	fn
    }
  }
}
ref
  • 用于基础类型的数据

  • ref是对元数据的拷贝,修改响应式数据时不会影响之前的数据,视图会更新

reactive
  • 引用类型的数据

  • 经过 Proxy 的加工变为一个响应式的对象

toRef
  • toRef 用于为源响应式对象上的属性新建一个ref,从而保持对其源对象属性的响应式连接。接收两个参数:源响应式对象和属性名,返回一个ref数据。例如使用父组件传递的props数据时,要引用props的某个属性且要保持响应式连接时就很有用。

  • toRef是对原始数据的引用,修改toRef数据时,原始数据也会发生改变,但是视图并不会更新。

toRefs
  • 可以用来为源响应式对象上的某个 property 新创建一个 ref。然后,ref 可以被传递,它会保持对其源 property 的响应式连接。

  • 传过来的props的数据需要通过toRefs解构,否则响应式数据会失效

  • toRefs后的ref数据不是原始数据的拷贝,而是引用,改变结果数据的值也会同时改变原始数据

  • 作用其实和 toRef 类似,只不过 toRef 是一个个手动赋值,而 toRefs 是自动赋值

toRef和toRefs区别
  • toRef修改的是对象的某个属性,toRefs修改的是整个对象
watch
  • 监听属性 (可侦听多个数据源 数组)

  • 想要侦听的响应式引用或 getter 函数

  • 回调

  • 可选的配置选项 (尝试检查深度嵌套对象或数组中的 property 变化时,配置deep 选项设置为 true。)

computed
  • 计算属性接受 getter 函数并为 getter 返回的值返回一个不可变的响应式 ref 对象。
watchEffect

与watch区别

  • 不需要手动传入依赖

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

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

         看到这里可能就有疑惑了,这跟我在data和methods中写没什么区别么,不就是把他们放到setup中整合到一起么?下面的复用代码事例来说明

// vue2.x的代码结构
<template>
  <button @click="increment">
    Count is: {{ count }}, double is: {{ double }}
  </button>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    };
  },

  computed: {
    double() {
      return this.count * 2;
    }
  },

  methods: {
    increment() {
      this.count++;
    }
  }
};
</script>
// vue2.x复用组件方式
// mixins
import CounterMixin from './mixins/counter'
export default {
  mixins: [CounterMixin]
}

// slot插槽
<template>
  <Counter v-slot="{ count, increment }">
     {{ count }}
    <button @click="increment">Increment</button> 
  </Counter> 
</template>

mixin 、slot 存在的问题 :

  • 渲染上下文中暴露的 property 来源不清晰。例如在阅读一个运用了多个 mixin 的模板时,很难看出某个 property 是从哪一个 mixin 中注入的。

  • 命名空间冲突。mixin 之间的 property 和方法可能有冲突。

  • 可重用性是有限的:我们不能向 mixin 传递任何参数来改变它的逻辑,这降低了它们在抽象逻辑方面的灵活性。

  • 我们只能在模板中访问,而且只能在Counter组件作用域中使用。

针对上方情况可以将setup中的功能进行提取分割成一个个独立函数,每个函数还可以在不同的组件中进行逻辑复用:

独立的组合式函数


import { computed, reactive } from "vue";

export function useCounter(num: number) {
  const state: { count: number; double: number } = reactive({
    count: num || 0,
    double: computed(() => state.count * 2),
  });

  function increment() {
    state.count++
  }

  return {
    state,
    increment,
  };
}
// vue3.0 使用
<script lang="ts">
import { defineComponent } from "vue";
import { useCounter } from "./getCount";

export default defineComponent({
  name: "Demo",
  setup() {
    const { state, increment } = useCounter(2);
    return {
      state,
      increment,
    };
  },
});
</script>

更加优雅了,相比较而言:

  • 暴露给模板的 property 来源十分清晰,因为它们都是被组合逻辑函数返回的值。

  • 不存在命名空间冲突,可以通过解构任意命名

  • 不再需要仅为逻辑复用而创建组件实例或者mixin注入

  • 仅依赖它的参数和 Vue 全局导出的 API,而不是依赖其微妙的 this 上下文

当然 Composition API 的引入也存在一定的弊端。

  • 组合式 API 在代码组织方面提供了更多的灵活性,但它也需要开发人员更多地自我克制来 “正确地完成它”

  • 组合式 API 会让没有经验的人编写出面条代码。

Vue2.x 中在 Options API 中实际上形成了一种强制的约定:

  • props 里面设置接收参数

  • data 里面设置变量

  • computed 里面设置计算属性

  • watch 里面设置监听属性

  • methods 里面设置事件方法

        这些我们会发现 Options API 都约定了我们该在哪个位置做什么事,这在一定程度上也强制我们进行了代码分割。 现在用 Composition API,不再这么约定了,代码组织非常灵活,如果作为一个新手,那么在逻辑越来越复杂的情况下,setup 代码量越来越多,同样 setup 里面的 return 越来越复杂

期望的是 setup() 函数现在只是简单地作为调用所有组合函数的入口

        针对这个弊端,官方也有一定的接纳策略,Vue 3.0 里 Composition API 并不是默认的方案,而是沿用 Vue 2.X 的 Options API, Composition API 将被定为为高级特性,因为它宗旨在解决在大型应用程序问题。

End

以上组合式 API 分享就到这里,之后在分享其他新特性。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值