当前位置: 首页 > news >正文

vue3学习四

七 标签ref属性

设置标签ref属性,类似于设置标签id。

普通标签

<template name="test4">
<p ref="title" id="title" @click="showinfo">VIEW4</p>
<View3/><script lang="ts" setup>
import { ref } from 'vue';
let title = ref();
function showinfo(){console.log("ref:"+title.value.innerHTML)console.log("id: "+document.getElementById("title").innerHTML)
}
</script>

 点击后输出

ref:VIEW4
id: VIEW4

不建议使用id,因为有id冲突的时候,根据加载顺序会选用先加载的。

使用ref不会有这种现象。

View4

<script lang="ts" setup>
import { ref } from 'vue';
import View3 from '@/components/View3.vue';
let title = ref();
function showinfo(){console.log("ref:"+title.value.innerHTML)console.log("id: "+document.getElementById("title").innerHTML)
}
</script>
<template name="test4">
<p ref="title" id="title" @click="showinfo">VIEW4</p>
<View3/>
</template>

 View3

<script lang="ts" setup>
import {ref,reactive,watch} from 'vue'let title=ref();
function showinfo(){console.log("ref:"+title.value.innerHTML)console.log("id: "+document.getElementById("title").innerHTML)
}</script>
<template><p ref="title" id="title" @click="showinfo">VIEW3</p>
</template>

 点击VIEW4输出

ref:VIEW4
id: VIEW4

 点击VIEW3输出

ref:VIEW3
id: VIEW4

view4引入vew3,所以view4先加载,点击VIEW3时用id取数据则返回错误数据。

组件标签

和放到普通标签组件不同。

普通标签返回dom元素,组件返回实例。

实例中可获取的属性,根据子组件用defineExpose()方法暴露的内容。

View4

<script lang="ts" setup name="test4">
import { ref } from 'vue';
import View3 from '@/components/View3.vue';
let view4 = ref()
function showinfo2(){console.log(view4.value)console.log(view4.value.title.innerHTML)
}
</script>
<template>
<button @click="showinfo2">showinfo2</button>
<hr>
<View3 ref="view4"/>
</template>  

 View3

<script lang="ts" setup>
import {ref,reactive,watch} from 'vue'let title=ref();
function showinfo(){console.log("ref:"+title.value.innerHTML)console.log("id: "+document.getElementById("title").innerHTML)
}
defineExpose({title,title3:title})
</script>
<template><p ref="title" id="title" @click="showinfo">VIEW3</p>
</template>

 输出内容

 defineExpose()暴露的内容中,默认使用变量名,也可以自定义变量名,比如title3:title。

defineExpose() 不用引入。

八 局部样式

style标签设置scoped防止样式冲突。

View4

<script lang="ts" setup>
import View3 from '@/components/View3.vue';
</script>
<template name="test4">
<p class="title">VIEW4</p>
<p class="title2">VIEW4</p>
<View3/>
</template><style scoped>.title{color: red;}
</style>
<style>
.title2{background-color:red;color: white;
}
</style>   

 View3

<script lang="ts" setup>
</script>
<template><p class="title">VIEW3</p><p class="title2">VIEW3</p>
</template>
<style scoped>
.title{color: saddlebrown;
}
</style>
<style>
.title2{background-color:saddlebrown;color: white;
}
</style>

 实际效果

View4中设置的title2样式,影响到了View3中。

title样式对应的style设置了scoped,所以仅对于其定义的页面起作用。

九 TS接口&泛型&自定义类型

便于对象结构统一。

定义

文件: /src/types/index.ts

export interface Book {id:number,edition:number,name:string,author:string,publication_time:string,test?:string
}// export type Books = Array<Book> 
export type Books = Book[]

 暴露变量:

  1. 默认暴露
  2. 分别暴露
  3. 统一暴露

代码中例子为分别暴露。

test?表示该属性非必填,即对象属性中不是必须包含。

使用

import {type Book,type Books} from '@/types'

加type表示引入接口,而不是变量。

使用类型定义普通数据

let book:Book={id:1,edition:2,name:"test1",author:"tedst1",publication_time:"2024-01-01",test:"test"
}let book2:Book={id:"qq",//编译器报错edition:2,name:"test1",author:"tedst1",publication_time:"2024-01-01"
}

使用泛型定义响应式数据

let book3 = reactive<Book>({id:1,edition:2,name:"test1",author:"tedst1",publication_time:"2024-01-01"
});

当对象结构错误或属性值错误时会报错。

let books1:Array<Book> = [book,book2]//泛型
let books2:Books=[book,book2]

 定义数组,可以使用泛型,也可以使用引入定义好的数组类型。

十 props

父组件向子组件传值。

父组件定义传递的数据,子组件接收数据。

父组件

<script lang="ts" setup name="test4">
import { ref,reactive } from 'vue';
import View3 from '@/components/View3.vue';
import {type Book,type Books} from '@/types'
let book:Book={id:1,edition:2,name:"test1",author:"tedst1",publication_time:"2024-01-01",test:"test"
}let book2:Book={id:"qq",edition:2,name:"test1",author:"tedst1",publication_time:"2024-01-01"
}
let books2:Books=[book,book2]
</script><template>
<View3 ref="view4" :books="books2" book="book"/>
</template>

子组件

无限制接收数据

<script lang="ts" setup>
import {ref,reactive,watch} from 'vue'
let getprops = defineProps(['books','book','test'])
console.log(getprops)
</script><template><div>{{books}}</div>
</template>

输出内容

父组件传book属性没有绑定变量,所以传递的一个字符串。

父组件未传递test属性,所以接收数据为undefined。

有限制接收数据

<script lang="ts" setup>
import {ref,reactive,watch,withDefaults} from 'vue'
let getprops = withDefaults(defineProps<{books:Books,book:Book,test?:string}>(),{books:()=>[{id:3,edition:1,name:"test3",author:"tedst3",publication_time:"2024-10-01",test:"test"},{id:4,edition:2,name:"test3", author:"tedst3",publication_time:"2024-10-02",}],book:()=>{return {id:4,edition:2,name:"test3", author:"tedst3",publication_time:"2024-10-02",}},test:()=>"empty"
})
console.log(getprops)
</script>
<template><div>{{books}}</div>
</template>

限制books属性为Books类型,book属性为Book类型,test属性可不传。

每个属性都有默认值。

在使用 withDefaults 时,默认值为可变引用类型 (如数组或对象) 应该封装在函数中,以避免意外修改和外部副作用。

这样可以确保每个组件实例都获得默认值的自己的副本。

在使用默认值解构时,这是必要的

 此时父组件再使用book="book"会报错,因为数据类型错误。

已下写法会报错

import { type Book,type Books} from "@/types"
let book1:Book ={id:3,edition:1,name:"test3",author:"tedst3",publication_time:"2024-10-01",test:"test"
}
let book2:Book ={id:4,edition:2,name:"test3", author:"tedst3",publication_time:"2024-10-02",
}
let books1:Books=[book1,book2]
let getprops = withDefaults(defineProps<{books:Books,book:Book,test?:string}>(),{books:()=>books1,book:()=>book1,test:"empty"
})let getprops1 = defineProps<{books:Books,book:Book,test?:string}>()
let getprops = withDefaults(defineProps<{books:Books,book:Book,test?:string}>(),{books:()=>books1,book:()=>book1,test:()=>"empty"
})

报错内容:

`defineProps()` in <script setup> cannot reference locally declared variables because it will be hoisted outside of the setup() function. If your component options require initialization in the module scope, use a separate normal <script> to export the options instead. 


<script setup>中的‘ defineProps() ’不能引用本地声明的变量,因为它将被提升到setup()函数之外。如果你的组件选项需要在模块作用域中初始化,那就使用单独的<script>来导出这些选项。

大概意思:定义的属性会被全局使用,所以不能使用已被定义的值,得在设置默认值时重新定义。

输出内容

 

http://www.lryc.cn/news/534156.html

相关文章:

  • C# LiteDB 使用教程
  • Python Pandas(3):DataFrame
  • 使用通义灵码 ai编程 来提高开发效率
  • 【OpenCV】入门教学
  • 大数据项目4:基于spark的智慧交通项目设计与实现
  • netcore openTelemetry+prometheus+grafana
  • Spring Boot接入Deep Seek的API
  • Git、Github和Gitee完整讲解:丛基础到进阶功能
  • MyBatis的工作流程是怎样的?
  • Maven 安装配置(完整教程)
  • 分享如何通过Mq、Redis、XxlJob实现算法任务的异步解耦调度
  • 发布:大彩科技DN系列2.8寸高性价比串口屏发布!
  • 集合类不安全问题
  • 【基于SprintBoot+Mybatis+Mysql】电脑商城项目之上传头像和新增收货地址
  • AI知识库和全文检索的区别
  • 20240817 联想 笔试
  • IntelliJ IDEA 安装与使用完全教程:从入门到精通
  • 【JVM详解一】类加载过程与内存区域划分
  • 250207-MacOS修改Ollama模型下载及运行的路径
  • Win10 部署llama Factory 推荐教程和遇到的问题
  • 如何在Android Studio中开发一个简单的Android应用?
  • ubuntu下迁移docker文件夹
  • 嵌入式面试题 C/C++常见面试题整理_7
  • 使用OBS推流,大华摄像头 srs服务器播放
  • CSS 组合选择符详解与实战示例
  • Window系统通过Docker本地安装ollama和deepseek
  • 镜头放大倍率和像素之间的关系
  • P3413 SAC#1 - 萌数
  • [RabbitMQ] RabbitMQ常见面试题
  • Java运行时数据区