一、组件结构
组件与vue页面结构一致,包括:
- template:组件的模板内容
- script:组件的脚本代码
- style:组件的样式
组件代码示例:
//组件基本代码
<template>
<view>
<view>{{userName}}</view>
</view>
</template>
<script>
export default {
//`props` 可以是数组或对象,用于接收来自父组件的数据。
props:{
age:{//父组件传入的值
type:Number,//prop类型
default:0,//默认值
required:true,//是否必填项
validator: function(value) {//验证函数
return value >= 0
}
}
},
//组件方法
methods:{
changeTitle(){
//触发一个更新事件
this.$emit('update:title',"uni-app")
}
},
//组件数据
data() {
return {
"userName":"foo",
"userName":this.age,//这个 `prop` 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 `prop` 数据来使用。在这种情况下,最好定义一个本地的 `data property` 并将这个 `prop` 用作其**初始值**
}
}
}
</script>
<style>
</style>
通过ref获取组件对象
<!-- index 父组件页面 -->
<template>
<view>
<base-input ref="usernameInput"></base-input>
<button type="default" @click="getFocus">获取焦点</button>
</view>
</template>
<script>
export default {
methods:{
getFocus(){
//通过组件定义的ref调用focus方法
this.$refs.usernameInput.focus()
}
}
}
</script>
<!-- base-input子组件页面 -->
<template>
<view>
<input :focus="isFocus" type="text" placeholder="请输入内容" />
</view>
</template>
<script>
export default {
name:"base-input",
data() {
return {
"isFocus":false
};
},
methods:{
focus(){
this.isFocus = true
}
}
}
</script>
插槽
将 slot 元素作为承载分发内容的出口,当组件渲染的时候,<slot></slot> 将会被替换为“Your Profile”。
<template>
<view>
<!-- 我是子组件componentA -->
<view >{{title}}</view>
<slot></slot>
</view>
</template>
<template>
<view>
<!-- 我是父组件 -->
<componentA>
<view>Your Profile</view>
<!-- 添加一个 uni-icons 图标 -->
<uni-icons type="contact" size="30"></uni-icons>
</componentA>
</view>
</template>
插槽内容
//将“Submit”作为后备内容,我们可以将它放在 `<slot>` 标签内
<button type="submit">
<slot>Submit</slot>
</button>
<!-- 父级组件:不提供任何插槽内容-->
<submit-button></submit-button>
<!-- 子组件:后备内容 “Submit” 将会被渲染: -->
<button type="submit">
Submit
</button>
<!-- 父级组件:提供插槽内容-->
<submit-button>
Save
</submit-button>
<!-- 子组件:则这个提供的内容将会被渲染从而取代后备内容: -->
<button type="submit">
Save
</button>
具名插槽
<template>
<view class="container">
<header>
<!-- 我们希望把页头放这里 -->
<slot name="header"></slot>
</header>
<main>
<!-- 我们希望把主要内容放这里 -->
<slot></slot>
</main>
<footer>
<!-- 我们希望把页脚放这里 -->
<slot name="footer"></slot>
</footer>
</view>
</template>
<template>
<view>
<!-- 父组件使用子组件`<base-layout>`,节点上使用slot特性: -->
<base-layout>
<template v-slot:header>
<view>Here might be a page title</view>
</template>
<template v-slot:default>
<view>A paragraph for the main content.</view>
<view>And another one.</view>
</template>
<template v-slot:footer>
<view>Here's some contact info</view>
</template>
</base-layout>
</view>
</template>
具名插槽缩写
<template>
<view>
<!-- 父组件使用子组件`<base-layout>`,节点上使用slot特性: -->
<base-layout>
<template #header>
<view>Here might be a page title</view>
</template>
<view>A paragraph for the main content.</view>
<view>And another one.</view>
<template #footer>
<view>Here's some contact info</view>
</template>
</base-layout>
</view>
</template>
作用域插槽
在作用域插槽内,父组件可以拿到子组件的数据。子组件可以在 slot 标签上绑定属性值。
<!-- 子组件 <current-user>-->
<template>
<view>
<slot :user="user">{{user.lastName}}</slot>
</view>
</template>
<script>
export default {
data() {
return {
user:{
"lastName":"bar",
"firstName":"foo"
}
}
}
}
</script>
<!--父组件-->
<template>
<view>
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
</view>
</template>