zoukankan      html  css  js  c++  java
  • vue3.2版本新特性

    Vue 3.2 版本包括许多重要的新功能和性能改进,但并不包含重大更改。
    Vue 3.2 原文链接

    https://blog.vuejs.org/posts/vue-3.2.html

    主要更新如下:

    1. 新的单文件组件功能
    <script setup> 是一种编译时语法糖,可在 SFC 内使用 Composition API 时极大地提升工作效率。
    <style> v-bind 在 SFC 标签中启用组件状态驱动的动态 CSS 值。<style>

    起初 vue3.0 暴露变量必须 return 出来,template中才能使用

    <script>
    import Foo from './Foo.vue'
    import Bar from './Bar.vue'
    export default {
    setup (props) {
    console.log(props)
    return {
    ok: Math.random(),
    Foo,
    Bar
    }
    }
    }
    </script>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    vue3.2 中 只需要在 script 标签上加上 setup 属性,组件在编译的过程中代码运行的上下是 setup() 函数中。所有ES模块导出都被认为是暴露给上下文的值,并包含在 setup() 返回对象中。

    <template>
    <Foo/>
    <Bar/>
    <component :is="ok ? Foo : Bar"/>
    </template>

    <script setup="props">
    export { default as Foo } from './Foo.vue'
    export { default as Bar } from './Bar.vue'
    export const ok = Math.random()
    console.log(props)
    </script>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    其实 script setup 就相当于在编译运行是把代码放到了 setup 函数中运行,然后把导出的变量定义到上下文中,并包含在返回的对象中。

    style v-bind 使用如下:

    <template>
    <button @click="color = color === 'red' ? 'green' : 'red'"> Color is: {{ color }} </button>
    </template>

    <script setup>
    import { ref } from 'vue'
    export const color = ref('red')
    </script>

    <style scoped>
    button { color: v-bind(color);}
    </style>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    2. 网页组件
    Web Components 是一套不同的技术,允许您创建可重用的自定义元素——将它们的功能与代码的其余部分封装在一起——并在您的 Web 应用程序中使用它们。

    Vue 3.2 引入了一种使用 Vue 组件 API 轻松创建原生自定义元素的新方法:defineCustomElement

    import { defineCustomElement } from 'vue'

    const MyVueElement = defineCustomElement({
    // normal Vue component options here
    })

    // Register the custom element.
    // After registration, all `<my-vue-element>` tags
    // on the page will be upgraded.
    customElements.define('my-vue-element', MyVueElement)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    更多网页组件学习:
    Web_Components
    web-components-examples

    3. 性能改进
    主要表现在界面渲染速度的提升和内存使用减少上:

    更高效的 ref 实现(约 260% 的读取速度/约 50% 的写入速度)
    约 40% 更快的依赖跟踪
    内存使用量减少约 17%
    模板编译器也得到了一些改进:
    创建普通元素 VNode 的速度提高了约 200%
    最后,有一个新v-memo指令提供了记忆模板树的一部分的能力。一v-memo允许Vue跳过虚拟DOM版本比较,创建新的虚拟节点。虽然很少需要,但它提供了一个逃生舱,以在某些情况下(例如大型v-for列表)挤出最大性能。

    4.服务端渲染
    3.2 中的包现在提供了一个 ES 模块构建,它也与 Node.js 内置模块分离。这使得捆绑和利用非 Node.js 运行时(例如 CloudFlare Workers 或 Service Workers)成为可能。@vue/server-renderer

    @vue/server-renderer

    5. 效果范围 API
    3.2 引入了一个新的 Effect Scope API (effectScope、getCurrentScope、onScopeDispose等),用于直接控制反应性效果(计算和观察者)的处理时间。它可以更轻松地在组件上下文之外利用 Vue 的响应式 API,并且还解锁了组件内部的一些高级用例。


    function effectScope(detached?: boolean): EffectScope
    interface EffectScope {
    run<T>(fn: () => T): T | undefined // undefined if scope is inactive
    stop(): void
    }


    const scope = effectScope()
    scope.run(() => {
    const doubled = computed(() => counter.value * 2)

    watch(doubled, () => console.log(doubled.value))

    watchEffect(() => console.log('Count: ', doubled.value))
    })

    // to dispose all effects in the scope
    scope.stop()


    function getCurrentScope(): EffectScope | undefined

    function onScopeDispose(fn: () => void): void
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    6. 一些属性使用变更
    (1)useContext API 被弃用
    在原先,可以通过该 API 来获取组件的上下文信息,包含了 attrs 、slots 、emit、expose 等父子组件通信数据和方法。
    该 API 将在 3.2 版本之后删除,context 里面的数据,会用新的 useSlots 和 useAttrs API 来代替。

    useAttrs:

    // 导入 useAttrs 组件
    import { useAttrs } from "vue";

    // 获取 attrs
    const attrs = useAttrs();

    // attrs是个对象,和 props 一样,需要通过 key 来得到对应的单个 attr
    console.log(attrs.msg);
    1
    2
    3
    4
    5
    6
    7
    8
    useSlots:

    import { defineComponent, useSlots } from "vue";

    const ChildTSX = defineComponent({
    setup() {
    // 获取插槽数据
    const slots = useSlots();

    // 渲染组件
    return () => (
    <div>
    // 渲染默认插槽
    <p>{slots.default ? slots.default() : ""}</p>
    // 渲染命名插槽
    <p>{slots.msg ? slots.msg() : ""}</p>
    </div>
    );
    },
    });

    export default ChildTSX;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    defineExpose:

    原expose使用示例:

    // 导入 useContext 组件
    import { useContext } from "vue";

    // 启用expose组件
    const { expose } = useContext();

    // 定义一个想提供给父组件拿到的数据
    const msg: string = "Hello World!";

    // 显示暴露的数据,才可以在父组件拿到
    expose({
    msg,
    });
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    3.2 版本后通过defineExpose暴露

    // 导入 defineExpose 组件
    import { defineExpose } from "vue";

    // 定义数据
    const msg: string = "Hello World!";

    // 暴露给父组件
    defineExpose({
    msg,
    });
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    defineEmits:

    // 导入 defineEmits 组件
    import { defineEmits } from "vue";

    // 获取 emit
    const emit = defineEmits(["say-hi", "chang-name"]);

    // 调用 emit 打招呼
    emit("say-hi", "Hello!");

    // 调用 emit 改名
    emit("chang-name", "Tom");
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    新增withDefaults:

    import { defineProps, withDefaults } from "vue";

    withDefaults(
    defineProps<{
    size?: number;
    labels?: string[];
    }>(),
    {
    size: 3,
    labels: () => ["default label"],
    }
    );
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    (2) 顶级 await 的支持
    不必再配合 async 就可以直接使用 await 了,这种情况下,组件的 setup 会自动变成 async setup

    <script setup lang="ts">
    const post = await fetch(`/api/post/1`).then((r) => r.json());
    </script>
    1
    2
    3
    它转换成标准组件的写法就是:

    <script lang="ts">
    import { defineComponent, withAsyncContext } from "vue";

    export default defineComponent({
    async setup() {
    const post = await withAsyncContext(
    fetch(`/api/post/1`).then((r) => r.json())
    );

    return {
    post,
    };
    },
    });
    </script>

  • 相关阅读:
    Cisco网络模拟器踩坑记录
    PAT甲级1009水题飘过
    PAT甲级1011水题飘过
    springmvc中项目启动直接调用方法
    Eclipse中Java文件图标由实心J变成空心J的问题
    mysql求时间差
    maven常用命令
    java单例模式(两种常用模式)
    mybatis一对多,多对一
    mybatis简介
  • 原文地址:https://www.cnblogs.com/onesea/p/15541228.html
Copyright © 2011-2022 走看看