1. 标签的ref属性

  1. 作用:用于注册模板引用
  • 用在普通DOM标签上,获取的使DOM节点
  • 用在组件标签上,获取的是组件实例对象

用在子组件上,父组件想要访问子组件内的数据,需要使用defineExpose暴露

  1. 用在普通DOM标签上:
<template>
  <div>
    <h2>哈哈</h2>
    <h2 ref="test">呵呵呵呵</h2>
    <h2>这是第三行了</h2>
    <button @click="showLog">修改高度</button>
  </div>
</template>
<script lang="ts" setup name="Person234">
import { ref } from 'vue'
let test = ref()
function showLog(){
  console.log(test.value)
}
</script>
  1. 用在组件标签上:
  1. 因为保护机制,父组件访问子组件的,得到的时无法直接使用数据的对象
  2. 要想父组件访问子组件的数据,必须使用defineExpose 导出想要被访问的数据 defineExpose({a, b, c})
// 子组件内 Person.vue
<template>
  <div>
    <h2>哈哈</h2>
    <h2 ref="test">呵呵呵呵</h2>
    <h2>这是第三行了</h2>
    <button @click="showLog">修改高度</button>
  </div>
</template>
<script lang="ts" setup name="Person234">
import { ref } from 'vue'
let test = ref()
function showLog(){
  console.log(test.value)
}

let a = ref(0)
let b = ref(2)
let c = ref(3)
// 要想父组件访问子组件的数据,必须使用defineExpose 导出想要被访问的数据
defineExpose({a, b, c})
</script>

// 父组件内 App.vue
<template>
  <button @click="showChild">显示组件ref</button>
  <Person ref="child"/>
</template>
<script lang="ts" setup name="App">
import Person from './components/Person.vue'
import { ref } from 'vue'
let child = ref()
function showChild(){
  // 直接打印出子组件实例对象,
  // 但是因为保护机制,所以想要访问子组件内的数据,还需要在子组件内使用defineExpose导出想要访问的数据
  console.log(child.value)
}
</script>

2. props父=>子传参

  1. 使用defineProps接收参数
  2. 使用withDefaults函数将defineProps接收的props参数作为第一个参数包裹起来,并第二个参数里设置默认值
  3. definexxx的函数可以不用引入
  4. defineProps可以直接使用泛型
  • 结合ts来写props案例
  1. ts文件内:(App.vue同级新建文件types\index.ts
export interface PersonInter {
  id: string,
  name: string,
  age: number
}
// export type persons = Array<PersonInter>
export type Persons = PersonInter[]
  1. App.vue文件中
<template>
  <Person a="9" :list="personList"/>
</template>
<script lang="ts" setup name="App">
import Person from './components/Person.vue'
import { reactive } from 'vue'
import { type Persons} from '@/types'

let personList = reactive<Persons>([
  {id: '1', name: '张三', age: 19},
  {id: '2', name: '李四', age: 20},
  {id: '3', name: '王五', age: 21},
])

<!--let personList:Persons = reactive([
  {id: '1', name: '张三', age: 19},
  {id: '2', name: '李四', age: 20},
  {id: '3', name: '王五', age: 21},
])-->

// let personList = reactive([
//   {id: '1', name: '张三', age: 19},
//   {id: '2', name: '李四', age: 20},
//   {id: '3', name: '王五', age: 21},
// ])

</script>
  1. Person.vue文件中:
<template>
  <div>
    <ul>
      <li v-for="p in list" :key="p.id">
        {{ p.name }} - {{ p.age }}
      </li>
    </ul>
  </div>
</template>
<script lang="ts" setup name="Person234">
import {type Persons} from '@/types'
// define+xxx的方法可以默认不做import导入,可以直接使用
import { defineProps, withDefaults } from 'vue'

// 1. 默认接收props数据
// defineProps(['list'])
/*
*   2. 加入ts之后的props
*/
// 2-1. defineProps可以加ts限制传入的值的类型
//  defineProps函数有返回值,返回所接收的props的集合
// let c = defineProps<{list:Persons,a:string}>()
// console.log(c.list, 'cc')

// 2-2. 接收传入的值,+限制类型, +必填项, +默认值
// ts的?限制是否必填
// withDefaults设置默认值
withDefaults(defineProps<{list?: Persons}>(), {
  list: ()=> [{id: 'sdadsa', name: '这是默认de', age: 99}]
})

</script>