Vue3+vite+Ts+pinia—第七章 props

7.1 defineProps接收参数

props最主要的作用就是接收父组件的传参,在Vue2里直接使用props接收参数即可,而在vue3需要依赖defineProps来接参。

这里举一个简单的例子,父组件传一个数组给子组件渲染出来。下面分别对比一下2和3的语法:

父组件Person.vue:

xml 复制代码
<template>
  <div class="person">
    <Child :list="personList"></Child>
  </div>
</template>

<script lang="ts" setup name="Person">
  import Child from './Child.vue'

  let personList = [
    {id:'asyud7asfd01',name:'张三',age:60},
    {id:'asyud7asfd02',name:'李四',age:18},
    {id:'asyud7asfd03',name:'王五',age:5}
  ]
</script>

子组件Child.vue:

css 复制代码
<template>
  <div class="child">
    <ul>
      <li v-for="p in list" :key="p.id">
        {{ p.name }} -- {{ p.age }}
      </li>
    </ul>
  </div>
</template>

1、Vue2

Vue2的接参方式是把参数放在props里。

xml 复制代码
<script>
export default {
  props: {
    list: null
  }
}
</script>

这里先不限定接参的类型,在后面会详细讲解。

2、Vue3

Vue3的接参方式有点不同,它需要依赖defineProps函数。它里面传入一个数组,里面的每一项是接参的参数名。

xml 复制代码
<script lang="ts" setup>
  defineProps(['list'])
</script>

7.2 使用props参数

对Vue2来说,props的参数跟定义在data里的属性一样,直接使用this.即可读取;但是Vue3相对麻烦一些,它需要先把props存起来,然后再使用。

1、Vue2

xml 复制代码
<script>
export default {
  props: {
    list: null
  },
  mounted() {
    console.log(this.list);
  }
}
</script>

2、Vue3

Vue3可得注意一下,不能直接使用props里的参数,必须先定义一个变量把props存起来,然后再使用。我们先打印一下整个props的结构:

xml 复制代码
<script lang="ts" setup>
  const propParam = defineProps(['list'])
  console.log(propParam)
</script>

实际上它帮我们包裹成一个对象,我们如果要使用,就以键值对来读取即可,例如上面读取list参数,那就是propParam.list。

7.3 限制props参数类型

1、Vue2

Vue2添加类型限制有两种方式,一种是直接在冒号:后面加类型,一种是通过对象里的type进行设置。

xml 复制代码
<script>
export default {
  props: {
    /* 第一种 */
    // list: Array,
    
    /* 第二种 */
    list: {
      type: Array
    }
  }
}
</script>

2、Vue3

Vue3的类型限制是通过defineProps的泛型实现。它里面传入一个对象,通过键值对的方式对每一个参数进行设置。

ini 复制代码
<script lang="ts" setup>
  const propParam = defineProps<{list: Array<object>}>();
</script>

当然如果想使用ts的接口或者自定义类型来进行设置也是可以的,用法一样。

src/types/index.ts:

typescript 复制代码
// 定义一个接口,用于限制person对象的具体属性
export interface PersonInter {
  id:string,
  name:string,
  age:number
}

/* 一个自定义类型 */
export type Persons = PersonInter[]

src/components/child.vue:

xml 复制代码
<script lang="ts" setup>
  import {type Persons} from '@/types'
  const propParam = defineProps<{list: Persons}>();
</script>

注意:使用了泛型来限制参数类型之后,defineProps方法里就不要传数组了,因为它通过泛型就已经知道你要接收的参数了。例如没有添加限制的写法是defineProps(['list']),添加类型限制后就写成defineProps<{list: Persons}>()。

7.4 限制是否必传

1、Vue2

vue2限制参数必传是通过设置required为true,它默认值是非必传的。

xml 复制代码
<script>
export default {
  props: {
    list: {
      type: Array,
      required: true
    }
  }
}
</script>

2、Vue3

vue3分两种情况:第一种是没有限制类型,把数组传入到defineProps里,比如defineProps('list'),那么它默认是非必传的;第二种是使用泛型限制参数类型,比如defineProps<{list: Persons}>(),则它默认是必传的。如果想设置它为非必传,则在限制类型的冒号:前加一个?,写成?:,这也是ts的一种语法。

(1)第一种情况:不限制类型

xml 复制代码
<script lang="ts" setup>
  defineProps(['list'])
</script>

(2)第二种情况:使用泛型限制类型

xml 复制代码
<script lang="ts" setup>
  import {type Persons} from '@/types'
  const propParam = defineProps<{list: Persons}>()
</script>

我们通过?:即可设置成非必传属性。

xml 复制代码
<script lang="ts" setup>
  import {type Persons} from '@/types'
  const propParam = defineProps<{list?: Persons}>()
</script>

7.5 设置默认值

1、Vue2

Vue2的默认值是通过default进行设置的,它同样有两种情况,一种是基本类型,一种是引用类型。基本类型直接写入默认值,而引用类型需要通过函数返回的形式设置默认值。

xml 复制代码
<script>
export default {
  props: {
    // 基本类型
    num: {
      type: Number,
      default: 123
    },
    // 对象类型
    obj: {
      type: Object,
      default: () => {
        return {id: 123, name: 'test'}
      }
    },
    // 数组类型
    list: {
      type: Array,
      default: () => [{id: 123, name: 'test'}]
    },
    // 函数类型
    fn: {
      type: Function,
      default: () => {
        console.log(123)
      }
    }
  }
}
</script>

2、Vue3

Vue3的默认值需要依赖withDefaults函数,withDefaults函数需要传入两个参数,第一个参数把整个defineProps的内容传进去,第二个参数用来设置默认值,它是一个对象,通过键值对的方式对每个属性进行设置。

注意:Vue3跟Vue2对基本类型和引用类型的设置是一样的,基本类型可以直接设置,引用类型需要包裹一个函数返回,像上述代码没有包裹函数则提示警告,只需要添加函数返回即可。

xml 复制代码
<script lang="ts" setup name="Person">
  import {type Persons} from '@/types'
  
  const propParam = withDefaults(defineProps<{list?:Persons}>(), {
    list: () => [{id:'ausydgyu01',name:'康师傅·王麻子·特仑苏',age:19}]
  })
</script>

父组件Person.vue:

xml 复制代码
<template>
  <div class="person">
    <Child></Child>
  </div>
</template>

7.6 示例代码

源码地址:gitee.com/huang_jing_...

文件目录:src_07_props

相关推荐
林焱_RPAAI5 小时前
影刀RPA技术深度:CSS选择器高级实战指南——伪类属性选择器与性能对比完全解析
vue.js·react.js
陳陈陳7 小时前
🚀 前端流式输出革命:SSE + BFF 架构从零到一实战指南
vue.js·架构·node.js
黄泉路醉s11 小时前
在Vant+Vue+TypeScript的H移动前端使用UnoCSS
前端·vue.js·typescript
我要两颗404西柚13 小时前
Stage three:VUE工程化与实战工具
前端·javascript·vue.js
看昭奚恤哭15 小时前
基于 RuoYi-Vue-Pro 定制了一个后台管理系统 magic-admin , 开源出来!
前端·vue.js·开源
妙码生花1 天前
从 PHP 到 AI + Golang,程序员自救转型手记(四十五):前端远程下拉输入组件
前端·javascript·vue.js
Listen·Rain1 天前
AGENTS.md — Vue 3 Frontend Development
前端·javascript·vue.js
南风知我意啊1 天前
Vue3图片缩放拖拽组件全攻略
前端·javascript·vue.js
万亿少女的梦1681 天前
基于Spring Boot、Vue.js与MySQL的流浪猫狗救助系统设计与实现
vue.js·spring boot·mysql·javaweb·权限管理
早睡早起身体好1231 天前
Vue 3 路由与懒加载入门:从零完成一个迷你学习中心
javascript·vue.js·学习