vue3造轮子项目总结

2021-05-21  本文已影响0人  RickyWu585

事件传递

父组件:<Switch :value="y" @input="y = event"> 子组件:context.emit('input',!props.value)event就是!props.value,input事件也对应了

image.png
vue3没有.sync了
image.png

属性继承

子组件明确继承属性:
子组件:{ inheritAttrs :false }
<button v-bind="$attrs"></button>
这样父组件传什么属性,都会明确地绑定给子组件的button上


image.png

vue3插槽

vue3具名插槽:可以使用其他标签改变样式
父组件:

<template v-slot:content>
      <div>hi</div>
      <div>hi2</div>
    </template>
<template v-slot:title>
      <strong>加粗的标题</strong>
</template>

子组件:

 <header>
          <slot name="title"/>
</header>
<main>
          <slot name="content"/>
</main>

新组件:Teleport

<Teleport to="body">
    //把下面的内容指定放到body下面,防止内容被遮挡
 ...
</Teleport>

语法简化:函数存在就执行

props.ok && props.ok() !== false相当于 props.ok?.()!==false

检查子组件类型

<component :is="SwitchDemo">相当于<SwitchDemo />

<template>
  <div>
    Tabs组件
    <component v-for="c in defaults" :is="c"/>
  </div>
</template>
<script lang="ts">
import Tab from './Tab.vue';

export default {
  setup(props, context) {
    let defaults = context['slots'].default();  //获取插槽内容
    defaults.forEach((tag) => {
      if (tag.type !== Tab) {
        throw new Error('Tabs 子标签必须是 Tab');
      }
    });
    return {defaults};
  }
};

js选中template里面的指定标签

<template>
 <div    :class="{selected:t===selected}"
           v-for="(t,index) in titles" :key="index"
           :ref="el=>{if(el) navItems[index]=el}"
           @click="select(t)">{{ t }}
 </div>
<div ref="indicator"></div>
</template>
<script lang="ts">
const navItems = ref<HTMLDivElement[]>([]);
const indicator = ref<HTMLDivElement>(null);
onMounted(() => {
      const divs = navItems.value;
      const result = divs.filter(div => div.classList.contains('selected'))[0];
      const {width} = result.getBoundingClientRect();  //获取宽高
      indicator.value.style.width = width + 'px';
    });
</script>

Typescript 泛型

const selectedItem = ref<HTMLDivElement>(null);

watchEffect 代替 onMounted和onUpdated,不过要在外面包一层onMounted,因为watchEffect 会在onMounted之前也执行一次

image.png
上一篇下一篇

猜你喜欢

热点阅读