vue3新特性

137 阅读1分钟

1. 组合式api

  • 更好的代码组织: 逻辑关注点分离
  • 逻辑复用(组合式函数), Mixins替代方案

mixins: 命名冲突、数据源不清晰

// Children.vue
import dataGet from './dataGet.js';
export default {
    props: {
        title: String,
    },
    // 组件创建之前执行,执行在beforeCreate之前,this实例无法访问
    setup(props, context) {
        // 保留响应性
        const { title } = toRefs(props);
        const { xxx } = dataGet();
        // ...

        // 返回的内容会暴露给组件的其余部分包括模板
        return { xxx };
        // 或者返回一个渲染函数, 此时需要使用expose暴露组件内部的方法/属性以供父组件访问
        context.expose({ xxx });
        return () => h('div', 'test composite-api');
    }
}

// SFC中使用组合式api的语法糖, 代码预编译为setup函数的内容
<script setup>
function foo() {}
// ......
// defineProps, defineEmits, defineExpose(暴露setup中声明的绑定,便于通过模板引用获取实例调用)
defineExpose({
  foo,
});
// 不支持渲染函数
// ......
</script>

----------------------------------------------------------------------------------------

// Parent.vue
childRef.value.foo()   // 调用子组件声明的绑定

----------------------------------------------------------------------------------------
// 与普通<script>标签区别
<script>:模块作用域,执行一次

<script setup>:setup函数作用域,内部代码编译为组件 `setup()` 函数的内容,每次实例被创建时执行

同选项式api比较:

选项式api: 以“组件实例”的概念为中心, 面向对象,易于上手

组合式api: 灵活自由,更好的代码组织和逻辑复用

2. Teleport

控制模板的渲染位置, 只改变了渲染的 DOM 结构,它不会影响组件间的逻辑关系

常见使用场景:模态框、对话框

app.component('modal-button', {
  template: `
    <button @click="modalOpen = true">
        Open full screen modal!
    </button>
	
	// 将模态框内容渲染至body元素下
    <teleport to="body">
      <div v-if="modalOpen" class="modal">
        <div>
          I'm a teleported modal! 
          (My parent is "body")
          <button @click="modalOpen = false">
            Close
          </button>
        </div>
      </div>
    </teleport>
  `,
  data() {
    return { 
      modalOpen: false
    }
  }
})

3. 片段

多根节点

// 2.x
// 结合inheritAttrs: false绑定$attrs到非根节点, 默认情况下自动绑定到根节点
<template>
  <div>
    <header>...</header>
    <main v-bind="$attrs">...</main>
    <footer>...</footer>
  </div>
</template>
<script>
export default {
    inheritAttrs: false,
}
</script>

// 3.x
// 支持多根节点,需要显示绑定$attrs
<template>
  <header>...</header>
  <main v-bind="$attrs">...</main>
  <footer>...</footer>
</template>

4. SFC中状态驱动的css(v-bind)

// 使用v-bind
<script setup>
const theme = {
  color: 'red'
}
</script>

<template>
  <p>hello</p>
</template>

<style scoped>
p {
  color: v-bind('theme.color');
}
</style>

// 组合式api中使用`useCssModule`访问注入的class

5. emits组件选项

// 使用对象语法可以进行事件验证
app.component('custom-form', {
  emits: {
    // 没有验证
    click: null,

    // 验证 submit 事件
    submit: ({ email, password }) => {
      if (email && password) {
        return true;  // 生效
      } else {
        console.warn('Invalid submit event payload!')
        return false
      }
    }
  },
  methods: {
    submitForm(email, password) {
      this.$emit('submit', { email, password })
    }
  }
})

6. Suspense

协调组件树中批量异步依赖的处理

一般搭配异步组件或者带有异步setup钩子的组件使用