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

相关推荐
GHUIJS几秒前
【vue3】vue3.5
前端·javascript·vue.js
计算机学姐1 小时前
基于python+django+vue的家居全屋定制系统
开发语言·vue.js·后端·python·django·numpy·web3.py
Ripple1111 小时前
Vue源码速读 | 第二章:深入理解Vue虚拟DOM:从vnode创建到渲染
vue.js
秋沐1 小时前
vue中的slot插槽,彻底搞懂及使用
前端·javascript·vue.js
QGC二次开发1 小时前
Vue3 : Pinia的性质与作用
前端·javascript·vue.js·typescript·前端框架·vue
想退休的搬砖人3 小时前
vue选项式写法项目案例(购物车)
前端·javascript·vue.js
啥子花道3 小时前
Vue3.4 中 v-model 双向数据绑定新玩法详解
前端·javascript·vue.js
清灵xmf3 小时前
揭开 Vue 3 中大量使用 ref 的隐藏危机
前端·javascript·vue.js·ref
学习路上的小刘4 小时前
vue h5 蓝牙连接 webBluetooth API
前端·javascript·vue.js
&白帝&4 小时前
vue3常用的组件间通信
前端·javascript·vue.js