components:在项目中创建的一个文件夹,可以用来新建组件,然后通过使用组件名来使用
创建组件的步骤:
第一步:在项目中新建一个为components的文件
注意:文件名不能开错不然创建不了组件
第二步:
右键components文件,点击新建组件(如果文件名没打对,不会出现新建组件),操作完后点击创建即可。
我们可以在组件中写上需要的数据,然后根据组件名在vue文件中进行引用。
组件代码:
<template>
<view class="box">
<image src="../../static/pic1.jpg"></image>
<view>坤ge</view>
</view>
</template>
<script setup>
defineProps(['acvtar','username']);//传入的参数
</script>
<style lang="scss" scoped>
</style>
vue 文件代码:
<template>
<cay-header></cay-header><!-- 使用自定义组件 -->
</template>
效果图:
也可以通过为组件定义class之类定义的名字来,在vue页面赋值显示。
组件设置class
通过vue页面使用组件,在根据定义的class的名字赋值。
效果图:
如果我们要对传过来的的东西进行处理,可以使用一个const来接收一下,
注意:不能直接使用传过来的参数。
<script setup>
/*传入的参数
如果要对传过来的值进行处理 我们可以使用const来接收
*/
const props=defineProps(['acvtar','username']);
console.log(props);
</script>
当我们要对这个值进行改变时,如果直接对其进行改变时,浏览器的控制台就会,提示我们它是一个只读的,不能修改
如果要修改可以通过定义一个import {computed} from 'vue';使用computed来改变
注意要使用一个变量接收不然用不了
<script setup>
import {computed} from 'vue';
/*传入的参数
如果要对传过来的值进行处理 我们可以使用const来接收
*/
const props=defineProps(['acvtar','username']);
/*
定义一个computed使用箭头函数对参数进行改变
然后使用一个变量接收
*/
const myprops=props.username=computed(()=>props.username+="@")
</script>
当然前面的defineProps不能限制类型,如果我们想限制传过来的类型可以使用defineProps方法对象,当然在父组件传值时要在class名字前面加上“:”也就是v-bind
代码示例:
/*
可以限制类型
*/
const props=defineProps({
acvtar:String,
username:String,
})
一般情况下如果父组件没有传入值就是空的,页面没有显示就不好看,这种情况下我们可以给它设置默认值,把传过来的值改成对象然后可以使用default属性来设置默认值。
const props=defineProps({
acvtar:{
type:String,
},
username:{
type:String,
default:"匿名" //默认值
},
})
属性有:
default:设置默认值
required: 为true时必须穿值
type:设置传入值的类型,可以使用数组来使用多个类型,类型也可以是null
这样的话我们也可以传一个对象,但是对象的默认值就是另一种写法了。
首先我们需要再父组件定义一个对象,然后把这个对象传入到我们的子组件中。
<template>
<cay-header :obj="scoFInd"></cay-header><!-- 使用自定义组件 -->
<cay-header ></cay-header>
</template>
<script setup>
import { ref } from 'vue';
const scoFInd=ref({
username:"张三",acvtar:"../../static/logo.png"})
</script>
再定在子组件中定义一个default默认值时要打括号,而不是使用:,然后return返回。
const props=defineProps({
obj:{
type:Object,
//使用default方法来定义默认值
default(){
return {username:"匿名",acvtar:"../../static/logo.png"}
}
}
})
当我们有多个对象时,就需要用到我们的循环比如v-for
代码示例:
<template>
<cay-header v-for="(itme,index) in scoFInd" :obj="itme"></cay-header><!-- 使用自定义组件 -->
</template>
<script setup>
import { ref } from 'vue';
const scoFInd=ref(
[{username:"张三",acvtar:"../../static/logo.png"},
{username:"李四",acvtar:"../../static/pic1.jpg"},
])
</script>
<style lang="scss" scoped>
</style>
二,插槽Slots。
组件要如何接收模板内容呢?在某些场景中,我们可能想要为子组件传递一些模板片段,让子组件在它们的组件中渲染这些片段。
示例一
组键代码:
<view class="box">
<view class="header">头部区域</view>
<view class="main">中部区域</view>
<view class="footer">尾部区域</view>
</view>
页面一,二都加上:
<view class="box">
<cay-layout></cay-layout>
</view>
页面一,二效果图都是:
示例二,在示例一的基础上:
slot是一个插槽出口,标注了父元素的内容在哪了,没有提供 name 的 <slot> 出口会隐式地命名为“default”。
组件:
在外部没有任何内容的情况,可以为插槽指定默认内容,比如:
<view class="main">
<slot></slot>
</view>
页面:
页面一,二在组件中写入内容可以显示不同的效果,但是上下部分是共享的
<cay-layout>aaa</cay-layout>
效果图:
我们也可以 通过给slots插槽一个name属性来判断在哪插入
示例三:
给slot插槽设置name
<view class="box">
<!-- 头部 -->
<view class="header">
<slot name="header"></slot>
</view>
<!-- 主要部 -->
<view class="main">
<slot name="main"></slot>
</view>
<!-- 尾部 -->
<view class="footer">
<slot name="footer"></slot>
</view>
</view>
在外部使用组件 ,使用template组件根据#(是v-slot的简写)name名来写入不同位置的内容
<view class="box">
<cay-layout>
<!-- header main 是组件的name名 -->
<template #header>头部1</template>
<template #main>中部2</template>
<template #footer></template>
</cay-layout>
</view>
效果图:
template对根据内容大小不同来调整页面大小