Vue3快速入门【二】

news2024/11/28 15:22:37

Vue3快速入门

    • 一、传值
      • 父传子,子传父
      • v-model
    • 二、插槽
      • 2.1、匿名插槽
      • 2.2、具名插槽
      • 2.3、插槽作用域
      • 2.4、插槽作用域案例
        • 2.4.1、初始布局
        • 2.4.2、插槽使用
        • 2.4.3、点击编辑按钮获取本行数据(插槽作用域的使用)
        • 2.4.4、类型书写优化
        • 2.4.5、全局接口抽取和ts全局配置
    • 三、teleport传送门
    • 四、类型增强
    • 五、第三方类型声明
    • 六、配置项目路径别名

一、传值

父传子,子传父

父组件:

<template>
  <div>父组件</div>
  <Child :num="num" @fn="changNum"></Child>
</template>

<script setup lang='ts'>
import Child from './12son.vue'
import { ref } from 'vue';
let num = ref(20)
const changNum = () => {
  num.value++
}
</script>

<style scoped>

</style>

子组件:

<template>
  <div>子组件{{ num }}</div>
  <button @click="hdClick">按钮</button>
</template>

<script setup lang='ts'>
import { defineProps, defineEmits } from 'vue';
defineProps({
  num: {
    type: Number, // 类型
    default: 10 // 默认值
  }
})
const emit = defineEmits<{
  (event: 'fn'): void
}>()
const hdClick = () => {
  emit("fn")
}
</script>

<style scoped>

</style>

在这里插入图片描述
在这里插入图片描述

v-model

父组件:

<template>
  <div>父组件</div>
  <Son v-model:num="num"></Son>
</template>

<script setup lang='ts'>
import Son from "./14son.vue"
import { ref } from 'vue';

let num = ref(10)

</script>

<style scoped>

</style>

子组件:

<template>
  <div>子组件-{{ num }}</div>
  <button @click="hdClick">改变</button>
</template>

<script setup lang='ts'>
import { } from 'vue';
let props = defineProps({
  num: {
    type: Number,
    default: 100
  }
})

let sonNum = props.num
const emit = defineEmits<{
  // update固定写法 后面的变量是父组件中v-model:后面的变量
  (event: 'update:num', n: number): void
}>()
const hdClick = () => {
  // 上面event的值,要改变的值
  emit("update:num", ++sonNum)
}

</script>

<style scoped>

</style>

在这里插入图片描述
在这里插入图片描述

二、插槽

2.1、匿名插槽

父组件:

<template>
  <div></div>
  <Child>
    <a href="#">a标签</a>
    <p>层楼终究误少年 自由早晚乱余生</p>
  </Child>
</template>

<script setup lang='ts'>
import Child from "./16son.vue"
import { } from 'vue';

</script>

<style scoped>

</style>

子组件:

<template>
  <div></div>
  <slot></slot>
</template>

<script setup lang='ts'>
import { } from 'vue';

</script>

<style scoped>

</style>

2.2、具名插槽

父组件:

<template>
  <div></div>
  <Child>
    <!-- <template v-slot:link> -->
    <!-- 简写#link -->
    <template #link>
      <a href="#">a标签</a>
    </template>
    <template v-slot:paragraph>
      <p>可春色不过宛若江南</p>
    </template>

  </Child>
</template>

<script setup lang='ts'>
import Child from "./16son.vue"
import { } from 'vue';

</script>

<style scoped>

</style>

子组件:

<template>
  <div></div>
  <slot name="paragraph"></slot>
  <slot name="link"></slot>
</template>

<script setup lang='ts'>
import { } from 'vue';

</script>

<style scoped>

</style>

2.3、插槽作用域

父组件:

<template>
  <div></div>
  <Child>
    <!-- <template v-slot:link> -->
    <!-- 简写#link -->
    <template #link>
      <a href="#">a标签</a>
    </template>
    <template #paragraph="scope">
      <p>可春色不过宛若江南</p>
      <p>{{ scope.title }}</p>
    </template>

  </Child>
</template>

<script setup lang='ts'>
import Child from "./16son.vue"
import { } from 'vue';

</script>

<style scoped>

</style>

子组件:

<template>
  <div></div>
  <slot name="paragraph" title="空港曲"></slot>
  <slot name="link"></slot>
</template>

<script setup lang='ts'>
import { } from 'vue';

</script>

<style scoped>

</style>

2.4、插槽作用域案例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h1sS1OkS-1675953382900)(Vue3-day02.assets/1644863300382.png)]

2.4.1、初始布局

父组件:

<template>
  <MyTable :arr="state.arr">

  </MyTable>
</template>

<script lang='ts' setup>
import MyTable from "./18son.vue"
import { reactive } from "Vue"
let state = reactive({
  arr: [{
    name: "许巍",
    age: 18
  }, {
    name: "朴树",
    age: 20
  }]
})
</script>

子组件:

<template>
  <table>
    <tr>
      <th>姓名</th>
      <th>年龄</th>
      <th>操作</th>
    </tr>
    <tr v-for="item, index in arr" :key="index">
      <td>{{ item.name }}</td>
      <td>{{ item.age }}</td>
      <td>
        <button>编辑</button>
        <button>删除</button>
      </td>
    </tr>
  </table>
</template>

<script lang='ts' setup>

let props = defineProps({
  arr: {
    type: Array,
    default: []
  }
})
</script>
 
<style scoped>
table {
  border-collapse: collapse;
}

table,
th,
td {
  border: 1px solid #000;
}

th,
td {
  padding: 10px
}
</style>

2.4.2、插槽使用

需求:第一个表格只有编辑按钮,第二个表格有编辑和删除按钮

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-38f0fPgQ-1675953382901)(Vue3-day02.assets/1644863481486.png)]

父组件:

<template>
  <MyTable :arr="state.arr">
    <template #btns>
      <button>编辑</button>
    </template>
    <button>删除</button>
  </MyTable>
  <MyTable :arr="state.arr">
    <template #btns>
      <button>编辑</button>
      <button>删除</button>
    </template>
  </MyTable>
</template>

子组件:

      <td>
        <slot name="btns"></slot>
      </td>

2.4.3、点击编辑按钮获取本行数据(插槽作用域的使用)

父组件:

<template>
  <MyTable :arr="state.arr">
    <template #btns="scoped">
      <button @click="hdClick(scoped.index)">编辑</button>
    </template>
    <!-- 相当于let {index} = scope -->
    <!-- <template #btns="{index}">
      <button @click="hdClick(index)">编辑</button>
    </template> -->
    <button>删除</button>
  </MyTable>
  <MyTable :arr="state.arr">
    <template #btns>
      <button>编辑</button>
      <button>删除</button>
    </template>


  </MyTable>
</template>

<script lang='ts' setup>
import MyTable from "./18son.vue"
import { reactive } from "Vue"
let state = reactive({
  arr: [{
    name: "许巍",
    age: 18
  }, {
    name: "朴树",
    age: 20
  }]
})
const hdClick = (index: number) => {
  console.log(state.arr[index])
}
</script>

子组件:

<template>
  <table>
    <tr>
      <th>姓名</th>
      <th>年龄</th>
      <th>操作</th>
    </tr>
    <tr v-for="item, index in arr" :key="index">
      <td>{{ item.name }}</td>
      <td>{{ item.age }}</td>
      <td>
        <slot name="btns" :index="index"></slot>
      </td>
    </tr>
  </table>
</template>

<script lang='ts' setup>

let props = defineProps({
  arr: {
    type: Array,
    default: []
  }
})
</script>
 
<style scoped>
table {
  border-collapse: collapse;
}

table,
th,
td {
  border: 1px solid #000;
}

th,
td {
  padding: 10px
}
</style>

在这里插入图片描述

2.4.4、类型书写优化

在这里插入图片描述

子组件中上面的代码模板里面报错。所以可以做如下优化,

子组件中:

<template>
  <table>
    <tr>
      <th>姓名</th>
      <th>年龄</th>
      <th>操作</th>
    </tr>
    <tr v-for="item, index in arr2" :key="index">
      <td>{{ item.name }}</td>
      <td>{{ item.age }}</td>
      <td>
        <slot name="btns" :index="index"></slot>
      </td>
    </tr>
  </table>
</template>

<script lang='ts' setup>

let props = defineProps({
  arr: {
    type: Array,
    default: []
  }
})

interface UserType {
  name: string,
  age: number
}
let arr2 = props.arr as UserType[]
</script>
 
<style scoped>
table {
  border-collapse: collapse;
}

table,
th,
td {
  border: 1px solid #000;
}

th,
td {
  padding: 10px
}
</style>

2.4.5、全局接口抽取和ts全局配置

项目目录下,新建types文件夹,其中新建table.d.ts文件:
在这里插入图片描述

interface UserType{
    name:string;
    age:number;
}

在tsconfig.json中补充:

  "include": [
    ...,
    "types/**/*.d.ts"
  ],

在你的项目中,如果table.d.ts文件中已经export,例如:

export interface UserType{
    name:string;
    age:number;
}

则需要在组件中引入之后,才可以使用这个接口:

import {UserType} from "../../types/table"

三、teleport传送门

Vue3提供的新组件,它可以把组件传送到指定位置(传送到指定标签内部的最后)

<template>
  <Teleport to="#app">
    <p>
      在歌舞升平的城市
      忍不住回头看我的城池
      在我手的将要丢失
      他的幼稚我的固执
      都成为历史
    </p>
  </Teleport>

  <MyTable :arr="state.arr">
    <template #btns="scoped">
      <button @click="hdClick(scoped.index)">编辑</button>
    </template>

    <button>删除</button>
  </MyTable>
  <MyTable :arr="state.arr">
    <template #btns>
      <button>编辑</button>
      <button>删除</button>
    </template>


  </MyTable>
</template>

<script lang='ts' setup>
import MyTable from "./18son.vue"
import { reactive } from "Vue"
let state = reactive({
  arr: [{
    name: "许巍",
    age: 18
  }, {
    name: "朴树",
    age: 20
  }]
})
const hdClick = (index: number) => {
  console.log(state.arr[index])
}
</script>

在这里插入图片描述

四、类型增强

index.html

<script>
    var globalVar = 'globalVar变量';
    var globalObj = { name: '', age: 20 };
    function fn(str) {
      console.log('fn函数' + str);
    }
</script>

组件中:

console.log(globalVar, globalObj);
fn("")

如果上面几个变量和函数没有在全局做声明,会报红线,所以我们在types文件夹中创建common.d.ts文件:

declare var globalVar: string;
type ObjType = { name: string; age: number }
declare var globalObj: ObjType;
// 声明函数fn类型
declare function fn(s?: string): void;

五、第三方类型声明

在index.html中做jquery全局引入:

<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>

在组件中使用:

console.log($("#app"));
$.ajax()

此时没有在全局声明的话,上面的写法也会报红线,在types文件夹中创建jquery.d.ts文件:

declare function $(n: string):any;
/* declare let $: object;   重复报红*/
declare namespace $ {
    function ajax():void;
}

拓展关于namespace:

// 全局变量的声明文件主要有以下几种语法:
declare var 声明全局变量
declare function 声明全局方法
declare class 声明全局类
declare enum 声明全局枚举类型
declare namespace 声明(含有某方法的)全局对象
interface  type 声明全局类型

六、配置项目路径别名

目前ts对@指向src目录的提示是不支持的,vite默认也是不支持的。

所以需要手动配置@符号的指向

tsconfig.json中:添加两项配置

"compilerOptions": {
    ...
    "baseUrl": "./",
    "paths": {
      "@/*": [
        "src/*"
      ],
      "#/*": [
         "types/*"
      ]
    }
},

添加完后就有提示了import MyTable from "@/components/03-AppChild.vue",但这仅仅是ts的提示支持,去运行案例还会报错。这是因为vite默认不认识@符号的意思。

这时候就需要在vite.config.ts中添加配置(参考网址https://vitejs.cn/config/#resolve-alias)

import path from 'path';

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      "@": path.join(__dirname, 'src'),
      "#": path.join(__dirname, 'types')
    }
  }
})

这时候引入的会path模块报红,但其实我们已经有node,所以就已经有path模块,只是缺少ts的一些声明配置。

所以需要安装关于node这个库的ts声明配置

npm i -D @types/node

安装成功就没有报红了,如果import后面的path报红,就把引入换成 import * as path from 'path';

如有不足,请多指教,
未完待续,持续更新!
大家一起进步!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/335509.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

云计算|OpenStack|社区版OpenStack安装部署文档(十一--- 如何获取镜像---Rocky版)

前言&#xff1a; 前面我们使用虚拟机搭建了一个openstack集群&#xff0c;也就是在VM虚拟机的基础上模拟了一个简单的基于openstack社区版Rocky的私有云&#xff0c;但&#xff0c;不管任何部署安装工作&#xff0c;最后其实都是需要有实际的应用的&#xff0c;也就是常说的实…

拿来就用的Java海报生成器ImageCombiner(一)

背景如果您是UI美工大师或者PS大牛&#xff0c;那本文一定不适合你&#xff1b;如果当您需要自己做一张海报时&#xff0c;可以立马有小伙伴帮您实现&#xff0c;那本文大概率也不适合你。但是&#xff0c;如果你跟我一样&#xff0c;遇上到以下场景&#xff0c;最近公司上了不…

新手小白适合做跨境电商吗?

今天的跨境电商已经逐渐成熟&#xff0c;靠运气赚钱的时代早已过去&#xff0c;馅饼不可能从天上掉下来&#xff0c;尤其是你想做一个没有货源的小白劝你醒醒。做跨境电商真的不容易&#xff0c;要想做&#xff0c;首先要分析自己是否适合做。米贸搜整理了以下资料&#xff0c;…

硬件设计—高性能ADC前端电路

高性能模数转换器&#xff08;ADC&#xff09;一般对系统的性能有非常高的要求&#xff0c;而AD芯片的“前端”的输入电路设计对ADC系统的的性能有非常大的影响。以下主要介绍了ADC芯片前端输入使用放大器和变压器各自的优势。 1、放大器和变压器根本区别 放大器是有源器件&am…

Docker进阶 - 8. docker network 网络模式之 container

目录 1. container 模式概述 2. 使用Alpine操作系统来验证 container 模式 1. container 模式概述 container网络模式新建的容器和已经存在的一个容器共享一个网络ip配置而不是和宿主机共享。新创建的容器不会创建自己的网卡&#xff0c;配置自己的IP&#xff0c;而是和一个…

ChatGPT注册+微信自动回复

ChatGPT注册微信自动回复1 注册OpenAI1.1 科学上网1.2 准备用于注册OpenAI的邮箱1.3 准备用于验证OpenAI的手机号1.4 注册OpenAI1.5 使用OpenAI2 基于ChatGPT微信实现自动回复2.1 原理2.2 实现ChatGPT是OpenAI基于GPT-3模型构建的自然语言处理模型&#xff0c;近几天ChatGPT突然…

这款浏览器火了,能快速使用ChatGPT,简单一看就会

当下ChatGPT很火&#xff0c;影响的人数非常广泛。作为聊天机器人模型&#xff0c;ChatGPT能完成写论文、编代码、写新闻、画画等高难度要求。那么&#xff0c;如何使用ChatGPT呢&#xff1f;下面介绍一下几个使用方法。值得一提的&#xff0c;目前已经有浏览器支持使用ChatGPT…

C++程序设计——多态:虚函数、抽象类、虚函数表

注&#xff1a;以下示例均是在VS2019环境下 一、多态的概念 通俗来讲&#xff0c;多态就是多种形态&#xff0c;当不同的对象去完成某个行为时&#xff0c;会产生出不同的状态。即不同继承关系的类对象&#xff0c;去调用同一函数时&#xff0c;产生不同的行为。 比如”叫“这…

【React】course

《千锋HTML5实战就业班React课程体系V16版本》课程资料 一、关于React 英文官网&#xff1a;https://reactjs.org/ 中文官网&#xff1a;https://zh-hans.reactjs.org/ React 起源于 Facebook 的内部项目&#xff0c;因为该公司对市场上所有 JavaScript MVC 框架&#xff0c…

JAVA工具篇--1 Idea中 Gradle的使用

前言&#xff1a; 既然我们已经使用Maven 来完成对项目的构建&#xff0c;为什么还要使用Gradle 进行项目的构建&#xff1b;gradle和maven都可以作为java程序的构建工具&#xff0c;但两者还是有很大的不同之处的&#xff1a;1.可扩展性&#xff0c;gradle比较灵活&#xff0c…

RabbitMQ-消息应答

一、介绍为了保证消息在发送过程中不丢失&#xff0c;rabbitmq引入消息应答机制&#xff0c;消息应答就是&#xff1a;消费者在接收到消息并且处理该消息之后&#xff0c;告诉rabbitmq它已经处理了&#xff0c;rabbitmq可以把该消息删除了。二、自动应答消息发送之后立即被认为…

pytest-fixture

fixture是pytest特有的功能&#xff0c;它用pytest.fixture标识&#xff0c;定义在函数前面。在编写测试函数的时候&#xff0c;可以将此函数的名称作为传入参数&#xff0c;pytest会以依赖注入方式将该函数的返回值作为测试函数的传入参数。fixture主要的目的是为了提供一种可…

从C语言向C++过渡

文章目录前言1.命名空间1.域的概念2.命名空间的使用2.C输入&输出3.缺省参数1.概念2.分类3.注意事项4.函数重载5.引用1.概念2.使用注意事项3.引用使用场景4.指针和引用的区别6.内联函数7.auto关键字8.nullptr前言 C被成为带类的C,本文由C语言向C过度&#xff0c;将会初步介…

电子器件系列32:逻辑与门芯片74LS11

一、编码规则 先看看这个代码的意思&#xff1a;74LS11 74是一个系列&#xff08;74 表示为工作温度范围&#xff0c;74: 0 ~ 70度。&#xff09; ls的意思就是工艺类型&#xff08;Bipolar(双极)工艺&#xff09; 11是代码 什么是74系列逻辑芯片&#xff1f; - 知乎 什么是…

【MyBatis】第八篇:一级,二级缓存

其实缓存字面的意思就是将一些内容缓存下来&#xff0c;等下次使用的时候可以直接调用&#xff0c;通过数据库得到数据&#xff0c;有时候会使用相同的数据&#xff0c;所以mybatis自然也支持缓存。 而mybatis按照缓存的效果可以分两大类&#xff1a;一级缓存和二级缓存。 一…

node.js下载和vite项目创建以及可能遇到的错误

目录 一、node.js的下载 1、去官网下载 节点.js (nodejs.org) 2、下载过程 第一步&#xff1a; 第二步&#xff1a; 第三步&#xff1a; 第四步&#xff1a; 第五步: 二、vite项目的创建&#xff08;使用的工具是Hbuilder x&#xff09; 第一步&#xff1a; 出现报错…

基于matlab多功能相控阵雷达资源管理的服务质量优化

一、前言此示例说明如何为基于服务质量 &#xff08;QoS&#xff09; 优化的多功能相控阵雷达 &#xff08;MPAR&#xff09; 监控设置资源管理方案。它首先定义必须同时调查的多个搜索扇区的参数。然后&#xff0c;它介绍了累积检测范围作为搜索质量的度量&#xff0c;并展示了…

低代码开发平台|制造管理-工艺工序搭建指南

1、简介1.1、案例简介本文将介绍&#xff0c;如何搭建制造管理-工艺工序。1.2、应用场景先填充工序信息&#xff0c;再设置工艺路线对应的工序&#xff1b;工序信息及工艺路线列表报表展示的是所有工序、工艺路线信息&#xff0c;可进行新增对应数据的操作。2、设置方法2.1、表…

权限管理实现的两种方式(详解)

登录的接口请求的三个内容&#xff1a;1. token2. 用户信息、角色信息3. 菜单信息第一种&#xff1a;基于角色Role的动态路由管理 (不推荐&#xff0c;但市场用的比较多)首先列出枚举每个角色对应几个路由&#xff0c;然后根据用户登录的角色遍历枚举出来的角色动态注册对应的路…

4年功能测试经验,裸辞后找不到工作怎么办?

软件测试四年&#xff0c;主要是手动测试&#xff08;部分自动化测试和性能测试&#xff0c;但是用的是公司内部自动化工具&#xff0c;而且我自动化方面是弱项。&#xff09; 现在裸辞三个月了&#xff0c;面试机会少而且面试屡屡受挫。总结就是自动化&#xff0c;性能&#…