vue3新特性

--

teleport可以指定元素渲染到某一元素下;

如:

<teleport to="body">
  <div>父级teleport</div>
</teleport>

emits自定义事件

emits: ['inFocus', 'submit'] // 会覆盖原生事件
emits: {
    // 没有验证
    click: null,

    // 验证 submit 事件
    submit: ({ email, password }) => {
      if (email && password) {
        return true
      } else {
        console.warn('Invalid submit event payload!')
        return false
      }
    }
  }

v-module可以绑定多个值

<user-name
  v-model:first-name="firstName"
  v-model:last-name="lastName"
></user-name>

自定义v-model修饰符:

<div id="app">
  <my-component v-model.capitalize="myText"></my-component>
  {{ myText }}
</div>
app.component('my-component', {
  props: {
    modelValue: String,
    modelModifiers: {
      default: () => ({})
    }
  },
  emits: ['update:modelValue'],
  methods: {
    emitValue(e) {
      let value = e.target.value
      if (this.modelModifiers.capitalize) {
        value = value.charAt(0).toUpperCase() + value.slice(1)
      }
      this.$emit('update:modelValue', value)
    }
  },
  template: `<input
    type="text"
    :value="modelValue"
    @input="emitValue">`
})

<script setup>语法糖

声明的方法、变量、组件 可以直接在模板中使用;不用显示return出来

动态组件:

<script setup>
import Foo from './Foo.vue'
import Bar from './Bar.vue'
</script>

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

递归组件、组件别名

例如:名为 FooBar.vue 的组件可以在其模板中用 <FooBar/> 引用它自己。

为了避免组件名和变量冲突,可以使用组件别名

import { FooBar as FooBarChild } from './components'

命名空间组件(引入多个组件时非常方便):

<script setup>
import * as Form from './form-components'
</script>

<template>
  <Form.Input>
    <Form.Label>label</Form.Label>
  </Form.Input>
</template>

使用自定义指令:

这里有一个需要注意的限制:必须以 vNameOfDirective 的形式来命名本地自定义指令,以使得它们可以直接在模板中使用。

<script setup>
const vMyDirective = {
  beforeMount: (el) => {
    // 在元素上做些操作
  }
}
</script>
<template>
  <h1 v-my-directive>This is a Heading</h1>
</template>
<script setup>
  // 导入的指令同样能够工作,并且能够通过重命名来使其符合命名规范
  import { myDirective as vMyDirective } from './MyDirective.js'
</script>

defineProps 和 defineEmits

在 <script setup> 中必须使用 defineProps 和 defineEmits API 来声明 props 和 emits ,它们具备完整的类型推断并且在 <script setup> 中是直接可用的:

<script setup>
const props = defineProps({
  foo: String
})

const emit = defineEmits(['change', 'delete'])
// setup code
</script>

defineExpose

使用 <script setup> 的组件是默认关闭的,也即通过模板 ref 或者 $parent 链获取到的组件的公开实例,不会暴露任何在 <script setup> 中声明的绑定。

为了在 <script setup> 组件中明确要暴露出去的属性,使用 defineExpose 编译器宏:

<script setup>
import { ref } from 'vue'

const a = 1
const b = ref(2)

defineExpose({
  a,
  b
})
</script>

useSlots 和 useAttrs

在 <script setup> 使用 slots 和 attrs 的情况应该是很罕见的,因为可以在模板中通过 $slots 和 $attrs 来访问它们。在你的确需要使用它们的罕见场景中,可以分别用 useSlots 和 useAttrs 两个辅助函数:

<script setup>
import { useSlots, useAttrs } from 'vue'

const slots = useSlots()
const attrs = useAttrs()
</script>

useSlots 和 useAttrs 是真实的运行时函数,它会返回与 setupContext.slots 和 setupContext.attrs 等价的值,同样也能在普通的组合式 API 中使用

与普通的 <script> 一起使用

...

 

顶层 await

<script setup> 中可以使用顶层 await。结果代码会被编译成 async setup()

<script setup>
const post = await fetch(`/api/post/1`).then(r => r.json())
</script>

 

状态驱动的动态 CSS

单文件组件的 <style> 标签可以通过 v-bind 这一 CSS 函数将 CSS 的值关联到动态的组件状态上:

<template>
  <div class="color1">父级teleport</div>
</template>

<script setup>
import { ref } from 'vue'
const theme = ref({
  color: 'red'
})
setInterval(() => {
  if(theme.value.color == 'red') {
    theme.value.color = 'green'
  } else {
    theme.value.color = 'red'
  }
}, 500)
</script>
<style>
.color1{
  color: v-bind('theme.color');
}
</style>

SFC <style scoped> 现在可以包含全局规则或只针对插槽内容的规则

<style scoped>
/* deep selectors */
::v-deep(.foo) {}
/* shorthand */
:deep(.foo) {}

/* targeting slot content */
::v-slotted(.foo) {}
/* shorthand */
:slotted(.foo) {}

/* one-off global rule */
::v-global(.foo) {}
/* shorthand */
:global(.foo) {}
</style>

 .sync修饰符的替换

<ChildComponent :title.sync="pageTitle" />

<!-- 替换为 -->

<ChildComponent v-model:title="pageTitle" />

<template v-for> 的key用该设置在template标签上

vue3中的v-if比v-for的优先级高,与vue2相反

v-bind="object" 和一个相同的独立 attribute覆盖可以控制,写在后面的覆盖前面的

 $listeners 被移除或整合到 $attrs

 $attrs 现在包含 class 和 style attribute

 ...

 

--

 

posted @ 2022-02-06 14:45  古墩古墩  Views(102)  Comments(0Edit  收藏  举报