vue内置组件、特殊元素、组件api详解

8 篇文章 0 订阅

vue3移动端项目搭建,vue3+vant+vite+axios+pinia+sass完整版代码下载:
https://download.csdn.net/download/randy521520/88820174
vue3移动端项目构建TS,vue3+vant+vite+axios+pinia+sass+typescript完整版代码下载:
https://download.csdn.net/download/randy521520/88820178
vue3 PC端项目构建,vue3+antd+vite+pinia+axios+sass完整版代码下载:
https://download.csdn.net/download/randy521520/88820523
vue3 PC端项目构建TS,vue3+antd+vite+axios+pinia+sass+typescript完整版代码下载:
https://download.csdn.net/download/randy521520/88845681

一、简介

Vue.js 是一个流行的前端 JavaScript 框架,用于构建用户界面和单页面应用程序(SPA)。Vue.js 的设计目标是通过简单、灵活的 API 提供高效的数据驱动视图层渲染。本文主要针对script setup讲解
以下是 Vue.js 的一些特点和优势:
1.简洁易用:Vue.js 的 API 简单易懂,容易上手,使开发者能够快速构建交互性强、动态的用户界面。
2.响应式数据绑定:Vue.js 使用双向数据绑定和虚拟 DOM 技术,能够自动追踪数据变化并更新视图,使开发者能够更容易地管理和维护应用的状态。
3.组件化开发:Vue.js 支持组件化开发,将页面拆分为多个独立的组件,每个组件负责自己的视图和逻辑,有利于代码复用和维护。
4.灵活性:Vue.js 提供了诸多灵活的特性,如指令、计算属性、过滤器等,使开发者能够根据需求选择合适的工具进行开发。
5.生态系统丰富:Vue.js 生态系统庞大丰富,拥有大量的插件、工具和第三方库,能够满足各种不同需求。
6.性能优化:Vue.js 通过虚拟 DOM 和 diff 算法优化了页面渲染性能,同时提供了一些性能优化的工具和指导,帮助开发者提升应用的性能。

二、vue内置组件之Transition

Transition 会在一个元素或组件进入和离开 DOM 时应用动画。
1.基本使用

<template>
  <div>
    <button @click="show = !show">Toggle</button>
    <Transition>
      <p v-if="show">hello</p>
    </Transition>
  </div>
</template>
<style lang="scss" scoped>
.v-enter-active,
.v-leave-active {
  transition: opacity 0.5s ease;
}

.v-enter-from,
.v-leave-to {
  opacity: 0;
}
</style>
<script setup>
import {ref} from "vue";

const show = ref(false);
</script>

2.相关class

  • v-enter-from:进入动画的起始状态。在元素插入之前添加,在元素插入完成后的下一帧移除。
  • v-enter-active:进入动画的生效状态。应用于整个进入动画阶段。在元素被插入之前添加,在过渡或动画完成之后移除。这个 class 可以被用来定义进入动画的持续时间、延迟与速度曲线类型。
  • v-enter-to:进入动画的结束状态。在元素插入完成后的下一帧被添加 (也就是 v-enter-from 被移除的同时),在过渡或动画完成之后移除。
  • v-leave-from:离开动画的起始状态。在离开过渡效果被触发时立即添加,在一帧后被移除。
  • v-leave-active:离开动画的生效状态。应用于整个离开动画阶段。在离开过渡效果被触发时立即添加,在过渡或动画完成之后移除。这个 class 可以被用来定义离开动画的持续时间、延迟与速度曲线类型。
  • v-leave-to:离开动画的结束状态。在一个离开动画被触发后的下一帧被添加 (也就是 v-leave-from 被移除的同时),在过渡或动画完成之后移除。
    3.过渡效果命名,name可以说动态的
<template>
  <div>
    <button @click="show = !show">Toggle</button>
    <Transition name="test">
      <p v-if="show">hello</p>
    </Transition>
  </div>
</template>
<style lang="scss" scoped>
.test-enter-active,
.test-leave-active {
  transition: opacity 0.5s ease;
}

.test-enter-from,
.test-leave-to {
  opacity: 0;
}
</style>
<script setup>
import {ref} from "vue";

const show = ref(false);
</script>

4.使用css的transition

<template>
  <div>
    <button @click="show = !show">Toggle</button>
    <Transition name="slide-fade">
      <p v-if="show">hello</p>
    </Transition>
  </div>
</template>
<style lang="scss" scoped>
.slide-fade-enter-active {
  transition: all 0.3s ease-out;
}

.slide-fade-leave-active {
  transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);
}

.slide-fade-enter-from,
.slide-fade-leave-to {
  transform: translateX(20px);
  opacity: 0;
}
</style>
<script setup>
import {ref} from "vue";

const show = ref(false);
</script>

5.使用css的 animation

<template>
  <div>
    <button @click="show = !show">Toggle</button>
    <Transition name="bounce">
      <p v-if="show" style="text-align: center;">
        Hello here is some bouncy text!
      </p>
    </Transition>
  </div>
</template>
<style lang="scss" scoped>
.bounce-enter-active {
  animation: bounce-in 0.5s;
}
.bounce-leave-active {
  animation: bounce-in 0.5s reverse;
}
@keyframes bounce-in {
  0% {
    transform: scale(0);
  }
  50% {
    transform: scale(1.25);
  }
  100% {
    transform: scale(1);
  }
}
</style>
<script setup>
import {ref} from "vue";

const show = ref(false);
</script>

6.自定义过渡 class

  • enter-from-class:进入动画的起始状态
  • enter-active-class:进入动画的生效状态
  • enter-to-class:进入动画的结束状态
  • leave-from-class:离开动画的起始状态
  • leave-active-class:离开动画的生效状态
  • leave-to-class:离开动画的结束状态
<Transition
  name="custom-classes"
  enter-active-class="animate__animated animate__tada"
  leave-active-class="animate__animated animate__bounceOutRight"
>
  <p v-if="show">hello</p>
</Transition>

7.相关事件

  • before-enter:在元素被插入到 DOM 之前被调用,用这个来设置元素的 “enter-from” 状态
  • enter:在元素被插入到 DOM 之后的下一帧被调用,用这个来开始进入动画
  • after-enter:当进入过渡完成时调用。
  • enter-cancelled:当进入过渡在完成之前被取消时调用
  • before-leave:在 leave 钩子之前调用,大多数时候,应该只会用到 leave 钩子
  • leave:在离开过渡开始时调用,用这个来开始离开动画
  • after-leave:在离开过渡完成,且元素已从 DOM 中移除时调用
  • leave-cancelled:仅在 v-show 过渡中可用
    8.Transition 组件属性,除了上述提到的属性还包括以下属性
  • appear: 是否在初始渲染时使用过渡。
  • css: 是否使用CSS过渡类。
  • type: 过渡模式,可以是"transition"或"animation"。
  • mode: 控制元素在过渡过程中的行为。in-out新元素先进行过渡,完成后移除旧元素;out-in旧元素先进行过渡,完成后移除新元素。
  • duration: 过渡持续时间,可以是一个数字或一个包含enter和leave属性的对象。
三、vue内置组件之TransitionGroup

TransitionGroup是一个内置组件,用于对 v-for 列表中的元素或组件的插入、移除和顺序改变添加动画效果。TransitionGroup支持和 Transition>基本相同的 props、CSS 过渡 class 和 JavaScript 钩子监听器,但有以下几点区别:

  • 默认情况下,它不会渲染一个容器元素。但可以通过传入 tag prop 来指定一个元素作为容器元素来渲染。
  • 过渡模式在这里不可用,因为不再是在互斥的元素之间进行切换。
  • 列表中的每个元素都必须有一个独一无二的 key attribute。
  • CSS 过渡 class 会被应用在列表内的元素上,而不是容器元素上。
<template>
  <div>
    <button @click="insert">添加</button>
    <button @click="remove">删除</button>
    <button @click="shuffle">重新排序</button>

    <TransitionGroup tag="ul" name="fade">
      <li v-for="item in items" :key="item">
        {{ item }}
      </li>
    </TransitionGroup>
  </div>
</template>
<style lang="scss" scoped>

/* 1. 声明过渡效果 */
.fade-move,
.fade-enter-active,
.fade-leave-active {
  transition: all 0.5s cubic-bezier(0.55, 0, 0.1, 1);
}

/* 2. 声明进入和离开的状态 */
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
  transform: scaleY(0.01) translate(30px, 0);
}

/* 3. 确保离开的项目被移除出了布局流
      以便正确地计算移动时的动画效果。 */
.fade-leave-active {
  position: absolute;
}
</style>
<script setup>
import {ref} from 'vue'

const getInitialItems = () => [1, 2, 3, 4, 5]
const items = ref(getInitialItems())
let id = items.value.length + 1

function insert() {
  const i = Math.round(Math.random() * items.value.length)
  items.value.splice(i, 0, id++)
}

function shuffle() {
  items.value = items.value.sort((a, b) => a - b);
}

function remove(item) {
  const i = items.value.indexOf(item)
  if (i > -1) {
    items.value.splice(i, 1)
  }
}
</script>
四、vue特殊元素之component

component​用于渲染动态组件或元素的“元组件”。
1.绑定普通标签

<template>
  <div>
    <component :is="href ? 'a' : 'span'" :href="href">
    {{ href ? 'Click me' : 'Not a link' }}
    </component>
  </div>
</template>
<script setup>
const href = 'https://www.baidu.com';
</script>

2.绑定组件

<template>
  <component :is="Math.random() > 0.5 ? Foo : Bar"/>
</template>
<script setup>
import Foo from './Foo.vue'
import Bar from './Bar.vue'
</script>
五、vue内置组件之KeepAlive

KeepAlive 是一个内置组件,它的功能是在多个组件间动态切换时缓存被移除的组件实例。KeepAlive包裹动态组件时,会缓存不活跃的组件实例,而不是销毁它们

<KeepAlive include="a,b" exclude="c,d" max="10">
  <component :is="view"></component>
</KeepAlive>

1.include: 如果指定,则只有与 include 名称匹配的组件才会被缓存,可以使用正则
2.exclude: 任何名称与 exclude匹配的组件都不会被缓存,可以使用正则
3.max: 最多可以缓存多少组件实例

六、vue内置组件之Suspense

Suspense是一个内置组件,用来在组件树中协调对异步依赖的处理。可以在组件树上层等待下层的多个嵌套异步依赖项解析完成,并可以在等待时渲染一个加载状态,Suspense是一项实验性功能。它不一定会最终成为稳定功能,并且在稳定之前相关 API 也可能会发生变化,而且Suspense组件自身目前还不提供错误处理,不过你可以使用 onErrorCaptured() 钩子,在使用到Suspense的父组件中捕获和处理异步错误。
1.子组件

<template>
  <div>
    <h1>{{ data.message }}</h1>
  </div>
</template>

<script setup>
let fn = ()=>{
  return new Promise( (resolve,reject)=>{
    setTimeout(async() => {
      // reject({'message':'数据获取成功'})
      resolve({'message':'数据获取成功'})
    }, 2000);
  })
}
let data =  await fn();

</script>

2.父组件

<template>
  <Suspense @resolve="onResolve"
            @pending="onPending"
            @fallback="onFallback">
      <Demo/>
    <template #fallback>
      Loading...
    </template>
  </Suspense>
</template>
<script setup>
import Demo from "@components/Demo.vue";

const onResolve = ()=>{
  console.log('异步组件加载成功')
}
const onPending = ()=>{
  console.log('异步组件加载中')
}

const onFallback = ()=>{
  console.log('异步组件加载回调')
}
</script>
七、vue内置组件之Teleport

Teleport是一个内置组件,它可以将一个组件内部的一部分模板“传送”到该组件的 DOM 结构外层的位置去
1.基本使用,该模态框会被渲染到body中

<template>
  <button @click="open = true">Open Modal</button>

  <Teleport to="body">
    <div v-if="open" class="modal">
      <p>Hello from the modal!</p>
      <button @click="open = false">Close</button>
    </div>
  </Teleport>
</template>
<style lang="scss" scoped>
.modal {
  position: fixed;
  z-index: 999;
  top: 20%;
  left: 50%;
  width: 300px;
  margin-left: -150px;
}
</style>
<script setup>
import {ref} from "vue";

const open = ref(false);
</script>

2.使用组件,Teleport>只改变了渲染的 DOM 结构,它不会影响组件间的逻辑关系

  • 子组件

<template>
  <div class="modal">
    {{message.text}}
  </div>
</template>

<style lang="scss" scoped>
.modal {
  position: fixed;
  z-index: 999;
  top: 20%;
  left: 50%;
  width: 300px;
  margin-left: -150px;
}
</style>

<script setup>
import {inject} from "vue";

const message = inject('message')
</script>

3.父组件

<template>
  <button @click="open = true">Open Modal</button>

  <Teleport to="body">
    <Demo v-if="open"/>
  </Teleport>
</template>
<script setup>
import {provide, ref} from "vue";
import Demo from "@components/Demo.vue";

const open = ref(false);

provide('message',{'text':'依赖注入'})
</script>

4.组件属性

  • to: 指定目标容器,可以是选择器或实际元素
  • disabled: 当值为 true 时,内容将保留在其原始位置
八、vue特殊元素之slot

slot>元素可以使用 name attribute 来指定插槽名。当没有指定 name 时,将会渲染默认插槽。传递给插槽元素的附加 attributes 将作为插槽 props,传递给父级中定义的作用域插槽。
1.子组件

<template>
  <slot name="demo"></slot>
  <slot></slot>
</template>

2.父组件

<template>
  <Demo>
    <template v-slot>
      默认
    </template>
    <template v-slot:demo>
      demo
    </template>
  </Demo>
</template>
<script setup>
import Demo from "@components/Demo.vue";
</script>

3.使用钩子访问插槽和插槽属性,useSlots() 和 useAttrs()

<template>
  <slot name="demo"></slot>
  <slot></slot>
</template>
<script setup>
import {useAttrs, useSlots} from "vue";

console.log(useSlots().default())
console.log(useSlots().demo())
console.log(useAttrs())
</script>
九、vue特殊元素之template。

当想要使用内置指令而不在 DOM 中渲染元素时,template 标签可以作为占位符使用,可以在使用的指令:v-if、v-else-if、v-else、v-for、v-slot。如果这些指令都不存在,那么它将被渲染成一个原生的 template 元素。带有 v-for 的 template 也可以有一个 key 属性。所有其他的属性和指令都将被丢弃,因为没有相应的元素,它们就没有意义

<template>
  <Demo>
    <template v-slot>
      默认
    </template>
    <template v-slot:demo>
      demo
    </template>
  </Demo>
</template>
<script setup>
import Demo from "@components/Demo.vue";
</script>
十、自定义组件相关之定义组件props:defineProps()

1.子组件

<template>
  <div>{{ props.message }}</div>
</template>

<script setup>

const props = defineProps({
  message: {
    type: String,
    default: 'default'
  },
})

</script>

2.父组件

<template>
  <Demo message="parent"/>
</template>
<script setup>
import Demo from "@components/Demo.vue";
</script>

3.defineProps相关属性配置

  • type:指定 props 的类型,可以是一个构造函数或一个包含多个可能类型的数组。
  • required:指定该 prop 是否是必需的,如果设置为 true,则必须传入该 prop。
  • default:设置 props 的默认值,当 prop 未被传入时,使用默认值。
  • validator:自定义验证函数,用于验证传入的 prop 是否符合特定要求。
十一、自定义组件相关之事件绑定、双向数据绑定:defineEmits()

1.绑定事件

  • 子组件
<template>
  <div @click="onClick">Demo组件</div>
</template>

<script setup>
const emit = defineEmits(['onClick']);
const onClick = () => {
  emit('onClick', '子组件defineEmits')
};

</script>

  • 父组件
<template>
  <Demo @on-click="onDemoClick"/>
</template>
<script setup>
import Demo from "@components/Demo.vue";

const onDemoClick = (value)=>{
  console.log(value)
}
</script>

2.双向数据绑定

  • 子组件
<template>
  <input :value="props.modelValue" @input="onModelValueChange"/>
  <input :value="props.customModel" @input="onCustomModelChange"/>
</template>

<script setup>
const props = defineProps({
  modelValue: [String, Number],
  customModel: String
})
const emit = defineEmits(['update:modelValue','update:customModel']);
const onModelValueChange = (events)=>{
  emit('update:modelValue',events.target.value)
}

const onCustomModelChange = (events)=>{
  emit('update:customModel',events.target.value)
}

</script>

  • 父组件
<template>
  <Demo v-model="modelValue" v-model:custom-model="customModelValue"/>
  <div>默认双向数据绑定: {{ modelValue }}</div>
  <div>自定义数据双向绑定: {{ customModelValue }}</div>
</template>
<script setup>
import Demo from "@components/Demo.vue";
import {ref} from "vue";

const modelValue = ref('默认双向数据绑定');
const customModelValue =  ref('自定义数据双向绑定');

</script>

十二、自定义组件相关之双向数据绑定props:defineModel() ,defineModel会自动触发update事件

1.子组件

<template>
  <input v-model="modelValue"/>
  <input v-model="customModel"/>
</template>

<script setup>
const modelValue = defineModel();
const customModel= defineModel("customModel", { type: Number, default: 0 })

</script>

2.父组件

<template>
  <Demo v-model="modelValue" v-model:custom-model="customModelValue"/>
  <div>默认双向数据绑定: {{ modelValue }}</div>
  <div>自定义数据双向绑定: {{ customModelValue }}</div>
</template>
<script setup>
import Demo from "@components/Demo.vue";
import {ref} from "vue";

const modelValue = ref('默认双向数据绑定');
const customModelValue =  ref('自定义数据双向绑定');

</script>

3.defineModel(name,options)相关属性配置

  • type:指定 props 的类型,可以是一个构造函数或一个包含多个可能类型的数组。
  • required:指定该 prop 是否是必需的,如果设置为 true,则必须传入该 prop。
  • default:设置 props 的默认值,当 prop 未被传入时,使用默认值。
  • validator:自定义验证函数,用于验证传入的 prop 是否符合特定要求。
十三、自定义组件相关之暴漏组件属性:defineExpose()

1.子组件

<template>
  demo组件
</template>

<script setup>
import {ref} from "vue";

const count = ref(0);

defineExpose({
  count: count,
  countChange:()=>{
    count.value++
  }
})

</script>

2.父组件

<template>
  <Demo ref="demoRef"/>
  <button @click="demoRef?.countChange">点击改变count</button>
  <div>DemCount:{{ demoRef?.count}}</div>
</template>
<script setup>
import Demo from "@components/Demo.vue";
import {ref} from "vue";

const demoRef= ref();

</script>
十四、组件其他API

1.defineComponent():用于定义一个基本的 Vue 组件。

const MyComponent = defineComponent({
    name: 'MyComponent', // 组件名称
    props: {
        msg: String
    },
    data() {
        return {
            count: 0
        };
    },
    methods: {
        increment() {
            this.count++;
        }
    },
    template: `
    <div>
      <h1>{{ msg }}</h1>
      <p>Count: {{ count }}</p>
      <button @click="increment">Increment</button>
    </div>
  `
});
app.component('my-component', MyComponent);

2.defineAsyncComponent(options):定义异步组件,即在需要时才加载组件。

  • loader:异步组件加载器函数,用于加载异步组件的内容。
  • loadingComponent:加载组件时显示的组件。
  • errorComponent:在异步组件加载过程中发生错误时显示的组件。
  • delay:延迟加载组件的时间(毫秒)。
  • timeout:加载组件的超时时间(毫秒)。
  • suspensible:是否支持暂停挂起异步组件加载。
  • onError:处理异步组件加载错误的回调函数,接受错误对象、重试函数、失败函数和尝试次数作为参数。
<template>
  <Demo/>
</template>
<script setup>
import {defineAsyncComponent} from "vue";

const Demo = defineAsyncComponent(()=>import('@components/Demo.vue'));
</script>

3.defineOptions():定义组件配置项

<template>
  <Demo/>
</template>
<script setup>
import Demo from "@components/Demo.vue";

defineOptions({
  name: 'home',
  mounted() {
    console.log('组件已挂载')
  }
})
</script>

4.defineSlots():提供插槽名称和 props 类型检查的类型提示

<script setup lang="ts">
const slots = defineSlots<{
  default(props: { msg: string }): any
}>()
</script>
  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值