vue作为当下前端主流开发框架之一,也是前端初学者必备的一个技能点,此处省略好多好多废话,我们直接上重点,点进去就知道了,包你满意。

通讯录组件

该组件可以实现按姓名首字母定位,点击联系人拨打电话等功能,效果如下

Mail.vue

1
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<template>
<view id="list">
<ul class="list_user" ref="listUser">
<li v-for="(item, index) in userData" :key="index">
<p>{{ item.index }}</p>
<ul>
<li v-for="(item, index) in item.user" :key="index" @click.stop="addName(item.name)">
{{ item.name }}
</li>
</ul>
</li>
</ul>
<ul class="list_index" ref="Po" >
<li
v-for="(item, index) in userIndex"
:key="index"
@click="setScroll(item)"
>{{item}}</li>
</ul>
</view>
</template>

<script>
export default {
name: "Mail",
data() {
return {};
},
props: {
userData: {
type: Array,
default: function () {
return [];
},
},
},
//计算属性
computed: {
userIndex: function () {
return this.filterIndex(this.userData);
console.log(this.filterIndex());
},
},
//右侧导航数据的调取
methods: {
filterIndex(data) {
var result = [];
for (var i = 0; i < data.length; i++) {
if (data[i].index) {
result.push(data[i].index);
}
}
return result;
},
//右侧导航的距离位置
diweiPo() {
var dw = this.$refs.Po.offsetHeight;
this.$refs.Po.style.marginTop = -dw / 2 + "px";
},
//设置点击位置的值
setScroll(ev) {
// alert(ev)
// console.log(ev)
var setzhi = this.$refs.listUser.getElementsByTagName("p");
for (var i = 0; i < setzhi.length; i++) {
if (setzhi[i].innerHTML == ev) {
document.body.scrollTop = setzhi[i].offsetTop;//移动端获取滚动条的位置
// document.documentElement.scrollTop = setzhi[i].offsetTop;//pc端获取滚动条的位置
}
}
},
//点击姓名
addName(e){
uni.navigateTo({
url:"/pages/volunteer/newTask/newTask?name="+e
})
console.log(e)
}
},
mounted() {
this.diweiPo();
// console.log(11111111)
},
};
</script>

<style scoped>
* {
padding: 0;
margin: 0;
}
li {
list-style-type: none;
}
#list {
position: relative;
top: 100rpx;
}
#list .list_user p,
#list .list_user ul {
padding: 0 20rpx;
}
#list .list_user p {
height: 40rpx;
background: #F6F7FA;
line-height: 40rpx;
font-size: 24rpx;
}
#list .list_user ul li {
height: 80rpx;
height: 80rpx;
line-height: 80rpx;
border-bottom:2rpx solid #E5E5E5 ;
font-size: 28rpx;
}
#list .list_index {
position: fixed;
top: 50%;
right: 40rpx;
z-index: 999;
}
#list .list_index li{
height: 40rpx;
}
</style>

index.vue

1
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<template>
<view>
<view class="top">
<view class="search">
<image src="../../../static/image/search.png" mode=""></image>
<input type="text" placeholder="搜索">
<text @click="click()">搜索</text>
</view>
</view>
<Mail :userData='userData'></Mail>
</view>
</template>

<script>
// import Tabar from "@/components/gobalComponents/Tabar";
import Mail from "@/components/gobalComponents/Mail";
export default {
// name: "SearchTask",
components: {
// Tabar,
Mail
},
data() {
return {
title: "通讯录",
userData:[
{
'index':'A',
'user':[
{'name':'a1','tel':'123456789'},
{'name':'a2','tel':'123456789'},
{'name':'a3','tel':'123456789'},
]
},
{
'index':'B',
'user':[
{'name':'b1','tel':'123456789'},
{'name':'b2','tel':'123456789'},
{'name':'b3','tel':'123456789'},
]
},
{
'index':'C',
'user':[
{'name':'c1','tel':'123456789'},
{'name':'c2','tel':'123456789'},
{'name':'c3','tel':'123456789'},
]
},
{
'index':'D',
'user':[
{'name':'d1','tel':'123456789'},
{'name':'d2','tel':'123456789'},
{'name':'d3','tel':'123456789'},
]
},
{
'index':'E',
'user':[
{'name':'e1','tel':'123456789'},
{'name':'e2','tel':'123456789'},
{'name':'e3','tel':'123456789'},
]
},
{
'index':'F',
'user':[
{'name':'f1','tel':'123456789'},
{'name':'f2','tel':'123456789'},
{'name':'f3','tel':'123456789'},
]
},
]
};
},
methods: {
click(){
alert(111)
}

},
created(){
// alert(222)
// ZWJSBridge.setTitle({ title: '通讯录'}) .then((result) => { console.log(result); }).catch((error) => { console.log(error); });
}
};
</script>

<style lang="scss" scoped>
.top{
position: fixed;
left: 0;
right: 0;
height: 100rpx;
background: #fff;
z-index: 99999999;
box-shadow: 0rpx 0rpx 14rpx 0rpx rgba(51, 51, 51, 0.13);
}
.search{
width: 672rpx;
height: 52rpx;
margin: 24rpx auto;
// margin-top: 24rpx;
background: #F6F7FA;
border-radius: 26rpx;
image{
display: inline-block;
vertical-align: middle;
width: 26rpx;
height: 26rpx;
margin-left: 15rpx;
}
input{
display: inline-block;
width: 400rpx;
height: 48rpx;
border: none;
font-size: 24rpx;
color: #999;
margin-left: 20rpx;
background: #F6F7FA;
vertical-align: middle;
line-height: 48rpx;
}
text{
// display: inline-block;
width: 104rpx;
height: 52rpx;
background: #FFB243;
border-radius: 22rpx;
font-size: 24rpx;
font-family: PingFang SC;
font-weight: 500;
color: #FFFFFF;
text-align: center;
line-height: 52rpx;
vertical-align: top;
float: right;
}
}
</style>

Layout布局组件

三栏布局

左右两栏固定宽度,中间自适应,懒得放图了,自行YY

layout.vue——子组件

1
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
31
32
33
<template>
<div class="layout_content">
<div class="left">
<slot name="left"></slot>
</div>
<div class="main">
<slot name="main"></slot>
</div>
<div class="right">
<slot name="right"></slot>
</div>
</div>
</template>

<script>
export default {

}
</script>

<style scoped lang="scss">
.layout_content{
display: flex;
width: 100%;
height: 100%;
.left,.right{
flex: 0 0 auto;
}
.main{
flex: 1 1 auto;
}
}
</style>

test.vue——父组件

1
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
31
32
33
34
35
36
37
38
39
40
41
42
43
<template>
<div class="test_content">
<Layout>
<template #left>
<div class="left"></div>
</template>
<template #main>
<div class="main"></div>
</template>
<template #right>
<div class="right"></div>
</template>
</Layout>
</div>

</template>

<script>
import Layout from "../components/layout.vue";
export default {
components: {
Layout,
},
};
</script>

<style scoped lang="scss">
.test_content{
width: 100%;
height: 600px;
}
.left,
.right {
width: 200px;
height: 100%;
background: cadetblue;
}
.main {
width: 100%;
height: 100%;
background: chocolate;
}
</style>
圣杯布局

头部导航栏,底部footer区域,中间是三栏基本布局

layout.vue——子组件

1
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<template>
<div class="layout_content">
<header>
<slot name="header"></slot>
</header>
<main>
<div class="left">
<slot name="left"></slot>
</div>
<div class="main">
<slot name="main"></slot>
</div>
<div class="right">
<slot name="right"></slot>
</div>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>

<script>
export default {};
</script>

<style scoped lang="scss">
header,
footer {
width: 100%;
height: 100%;
}
main {
display: flex;
width: 100%;
height: 100%;
.left,
.right {
flex: 0 0 auto;
}
.main {
flex: 1 1 auto;
}
}
</style>

test.vue——父组件

1
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<template>
<div class="test_content">
<Layout>
<template #header>
<div class="header"></div>
</template>
<template #left>
<div class="left"></div>
</template>
<template #main>
<div class="main"></div>
</template>
<template #right>
<div class="right"></div>
</template>
<template #footer>
<div class="footer"></div>
</template>
</Layout>
</div>

</template>

<script>
import Layout from "../components/layout.vue";
export default {
components: {
Layout,
},
};
</script>

<style scoped lang="scss">
.test_content {
width: 100%;
height: 100%;
}
.header,
.footer {
height: 50px;
width: 100%;
background: cyan;
}
.left,
.right {
width: 200px;
height: 600px;
background: cadetblue;
}
.main {
width: 100%;
height: 100%;
background: chocolate;
}
</style>

组件递归——实现目录结构

当我们不知道后端的大兄弟返给我们的数据有多少个层级时,可以考虑使用组件的递归,render渲染后面介绍。
test.vue——父组件

1
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
31
32
33
34
35
36
37
38
39
<template>
<Catalogue :list="list" @select="seletClick"></Catalogue>
</template>

<script>
import Catalogue from "../components/Catalogue.vue";
export default {
components: {
Catalogue,
},
data(){
return{
list:[
{name:'a',isSelect:false},
{name:'b',isSelect:false},
{name:'c',isSelect:false,children:[
{name:'c-1',isSelect:false},
{name:'c-2',isSelect:false},
{name:'c-3',isSelect:false,children:[
{name:'c-3-1',isSelect:false},
{name:'c-3-2',isSelect:false},
{name:'c-3-3',isSelect:false},
]},
]},
{name:'d',isSelect:false},
]
}
},
methods:{
seletClick(e){
console.log(e)
}
}
};
</script>

<style scoped lang="scss">

</style>

Catalogue.vue——子组件

1
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
<template>
<ul>
<li v-for="(item,index) in list" :key="index" :class="{active:item.isActive}" @click="handleClick(item)">
{{item.name}}
<Catalogue :list="item.children" @click="handleClick(item)"></Catalogue>
</li>
</ul>
</template>

<script>
export default {
name:'Catalogue',
props:{
list:{
type:Array,
default:()=>[]
}
},
methods:{
handleClick(item){
this.$emit('select',item)
}
}
}
</script>

<style>

</style>

最后更新: 2021年12月27日 16:48

原始链接: https://corn0124.cn/2021/11/30/vue%E5%90%84%E7%A7%8D%E7%BB%84%E4%BB%B6/

× 我是好人
打赏二维码