# 组件定义
# 自定义组件
新建在/components/组件名.vue
文件
组件文档结构
<template>
<view>
......
</view>
</template>
<script>
export default {
name: "组件名称",
//属性自定义
props: {
属性名称: {
type: String, //属性类型
value: "值"
},
......
},
//组件生命周期
created: function(e) {
},
methods: {
函数名称: function(obj) {
},
}
}
</script>
<style>
组件样式
</style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
使用组件
1、引用组件
import 组件名称 from "../../components/组件名.vue";
2、注册组件
export default{
components:{
组件名称
},
}
3、在试图模板中使用组件
<组件名称 组件属性="对应的值"></组件名称>
2
3
4
5
6
7
8
9
10
# 全局注册
和vue
一样的方式去配置全局组件,需在main.js
里进行全局注册,注册后就可在所有页面里使用该组件。
1、main.js
里进行全局导入和注册
import Vue from 'vue'
import pageHead from './components/page-head.vue'
Vue.component('page-head',pageHead)
2
3
2、index.vue
里可直接使用组件
<template>
<view>
<page-head></page-head>
</view>
</template>
2
3
4
5
# 局部注册
1、传统vue
规范:在index.vue
页面中,通过import
方式引入组件 ,在components
选项中定义你想要使用的组件。
<!-- 在index.vue引入 uni-badge 组件-->
<template>
<view>
<uni-badge text="1"></uni-badge>
</view>
</template>
<script>
import uniBadge from '@/components/uni-badge/uni-badge.vue';
export default {
components: {
uniBadge
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
对于components
对象中的每个property
来说,其property
名就是自定义元素的名字,其property
值就是这个组件的选项对象。
在对象中放一个类似uniBadge
的变量名其实是缩写,即这个变量名同时是:
- 用在模板中的自定义元素的名称
- 包含了这个组件选项的变量名(仅支持驼峰法命名)
2、通过uni-app
的easycom
将组件引入精简为一步。只要组件安装在项目的components
目录下,并符合components/组件名称/组件名称.vue
目录结构。就可以不用引用、注册,直接在页面中使用。
<template>
<view>
<uni-badge text="1"></uni-badge>
</view>
</template>
<script>
// 这里不用import引入,也不需要在components内注册uni-badge组件。template里就可以直接用
export default {
data() {
return {}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
easycom
是自动开启的,不需要手动开启,有需求时可以在pages.json
的easycom
节点进行个性化设置- 不管
components
目录下安装了多少组件,easycom
打包后会自动剔除没有使用的组件,对组件库的使用尤为友好。
# props
props
可以是数组或对象,用于接收来自父组件的数据。props
可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义验证和设置默认值。
选项 | 类型 | 说明 |
---|---|---|
type | String、Number、Boolean、Array、Object、Date、Function、Symbol,任何自定义构造函数、或上述内容组成的数组 | 会检查一个 prop 是否是给定的类型,否则抛出警告 |
default | any | 为该 prop 指定一个默认值。如果该 prop 没有被传入,则换做用这个值。对象或数组的默认值必须从一个工厂函数返回 |
required | Boolean | 定义该 prop 是否是必填项 |
validator | Function | 自定义验证函数会将该 prop 的值作为唯一的参数代入。在非生产环境下,如果该函数返回一个 false 的值 (也就是验证失败),一个控制台警告将会被抛出 |
示例:子组件定义
<template>
<view>
<view>{{age}}</view>
</view>
</template>
<script>
export default {
props: {
// 检测类型 + 其他验证
age: {
type: Number,
default: 0,
required: true,
validator: function(value) {
return value >= 0
}
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
示例:父组件传递age
属性
<template>
<view>
<componentA :age="10"></componentA>
</view>
</template>
2
3
4
5
# 组件之间的数据传输
组件之间的数据传输,以及事件传递是比较常见的一个应用
# 事件注册/触发方式
客户端调用组件的时候,注册事件。组件触发注册的事件,达到向父组件传值的目的
子组件free-test.vue
<template>
<!-- <button type="default" @tap="$emit('openExtend')">{{title}}</button> -->
<button type="default" @tap="seeme">{{title}}</button>
</template>
<script>
export default {
name: "freeTs",
props: {
title: String,
default: ''
},
methods: {
seeme() {
this.$emit('openExtend', { name: 'wk', 'sex': 'male' })
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
父组件调用时注册事件
<template>
<view>
<free-test :title="title" @openExtend="openExtend"></free-test>
</view>
</template>
<script>
import freeTest from '../../components/free-test.vue'
export default {
components: {
freeTest
},
data() {
return {
title: 'haha'
}
},
methods: {
openExtend(obj) {
console.log(obj)
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 客户端调用组建引用方式
客户端为调用的组件设置引用别名,就可以调用其方法进行传值
子组件free-test.vue
<template>
<button type="default">{{title}}</button>
</template>
<script>
export default {
name: "freeTs",
props: {
title: String,
default: ''
},
methods: {
seeme(obj) {
console.log(obj)
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
父组件为组建设置引用别名,就可以调用其方法进行传值
<template>
<view>
<free-test :title="title" ref="free"></free-test>
<button type="default" @tap="seeData">test</button>
</view>
</template>
<script>
import freeTest from '../../components/free-test.vue'
export default {
components: {
freeTest
},
data() {
return {
title: 'haha'
}
},
methods: {
seeData() {
this.$refs.free.seeme({ title: '6666', created_at: '2020-09-19' });
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# ref
被用来给元素或子组件注册引用信息,引用信息将会注册在父组件的$refs
对象上。
如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例:
<!-- 非H5端不支持通过this.$refs.content来获取view实例 -->
<view ref="content">hello</view>
<!-- 支持通过this.$refs.child来获取child-component实例 -->
<child-component ref="child"></child-component>
2
3
4
5
尽管存在prop
和事件,有的时候你仍可能需要在JavaScript
里直接访问一个子组件。访问子组件实例或子元素,通过ref
为子组件赋予一个ID引用,在vue的js中可通过this.$refs.XXX
来获取到组件对象。
<base-input ref="usernameInput"></base-input>
你已经定义了这个ref
的组件里,你可以使用this.$refs.usernameInput
来访问这个<base-input>
实例
<!-- 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>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
允许父级组件通过下面的代码聚焦<base-input>
里的输入框
<!-- 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>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
注意
非H5端只能用于获取自定义组件,不能用于获取内置组件实例(如:view、text)
# 自定义事件
你可能有很多次想要在一个组件的根元素上直接监听一个原生事件。 这时,你可以使用 @ 事件的.native
修饰符
- 注意:在app、小程序端和h5端表现不一致,h5端获取到的是浏览器原生事件。
<template>
<view>
<!-- 我是父组件 -->
<componentA @click.native="clickComponentA" style="height: 200px;"></componentA>
</view>
</template>
<script>
export default {
methods: {
clickComponentA() {
console.log("clickComponentA");
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
<view>
<!-- 我是子组件 -->
<view type="default" @click.stop="open" style="height: 30px;">点击</view>
</view>
</template>
<script>
export default {
methods: {
open() {
console.log("open");
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# .sync 修饰符
当一个子组件改变了一个prop
的值时,这个变化也会同步到父组件中所绑定。.sync
它会被扩展为一个自动更新父组件属性的v-on
监听器。
<!-- 父组件 -->
<template>
<view>
<syncA :title.sync="title"></syncA>
</view>
</template>
<script>
export default {
data() {
return {
title: "hello vue.js"
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 子组件 -->
<template>
<view>
<view @click="changeTitle">{{title}}</view>
</view>
</template>
<script>
export default {
props: {
title: {
default: "hello"
},
},
methods: {
changeTitle() {
// 触发一个更新事件
this.$emit('update:title', "ruoyi-app")
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 命名限制
在uni-app
中以下这些作为保留关键字,不可作为组件名。
a、canvas、cell、content、countdown、datepicker、div、element、embed、header、image、img、indicator、input、link、list、loading-indicator、loading、marquee、meta、refresh、richtext、script、scrollable、scroller、select、slider-neighbor、slider、slot、span、spinner、style、svg、switch、tabbar、tabheader、template、text、textarea、timepicker、transition-group、transition、video、view、web
注意
- 除以上列表中的名称外,标准的 HTML 及 SVG 标签名也不能作为组件名。
- 在百度小程序中使用时,不要在 data 内使用 hidden ,可能会导致渲染错误。
- methods中不可使用与生命周期同名的方法名。