# vue项目实战
# 文件路径问题
如果我们的图片地址为<img slot="item-ico" src="../../assets/img/tabbar/category.svg" alt="">
,我们的文件结构目录为
那么现在我们更改代码位置,或者是其他的操作,都会引起图片资源位置的改变,导致图片不能加载,并且一直使用../
等的形式,特别不好看,那么我们可以用为资源路径起别名的方式,这样设置之后,我们就可以直接使用相对路径了
在配置(cli2)webpack.base.conf.js
中
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'@': resolve('src'),
'assets': resolve('src/assets'),
'component': resolve('src/components'),
'view': resolve('src/views')
}
}
2
3
4
5
6
7
8
9
那么我们现在对于../../assets/img/tabbar/category.svg
就可以使用~assets
代替../../assets
,最终地址就为~assets/img/tabbar/category.svg
# tabbar
# 大体布局
我们实现的最终效果为
实现这个的主要思想就是学会组件的抽取和封装,其目标是这个导航栏不仅在这个项目中,可以使用,在其他的项目中,我们也是可以使用,封装之后,可以根据我们的需求动态的更改
在做这个导航的时候,可以先画出大体结构图
从上面可以想到,我们应该有一个组件TabBar.vue
来作为整个导航栏的容器,每一个导航栏都是一个组件TabBarItem.vue
,
而且每一个item我们都不应该写死,其可以分为三层,也可以两层(img,img,文字),其中两个img,一张放激活状态的图片,一张放没有激活状态的文字,但是推荐使用三层,因为我们需要封装,如果是两层的话,假如有新的item假如,那么我们就需要额外的写css,并且使用js进行判断是否激活,但是如果是三层的话,我们就可以使用computed
计算属性,得到组件的激活状态,通过v-if
进行这两张图标是显示激活的,还是没有激活的,但是又要考虑到,每一个item都应该是动态的,比如图标下面的文字颜色,我们也不应该将激活状态的颜色写死,应该能够动态的根据输入来显示,所以就可以考虑为:style='xx'
来实现,应该需要动态,所以我们就需要用到具名插槽,最终实现如下
//TabBar.vue
<template>
<div id="tab-bar">
<slot></slot>
</div>
</template>
2
3
4
5
6
//TabBarItem.vue
<template>
<div class="tab-bar-item" @click="itemClick">
<div v-if="!isActive"><slot name="item-ico"></slot></div>
<div v-else><slot name="item-ico-active"></slot></div>
<div :style="activeStyle"><slot name="item-text"></slot></div>
</div>
</template>
<script>
export default {
name: "TabBarItem",
data() {
return {
}
},
computed: {
isActive() {
if (this.path == this.$route.path) {
return true
}
},
activeStyle() {
return this.isActive ? "color:" + this.activeColor : {}
}
},
props: {
path: String,
activeColor: String
},
methods: {
itemClick() {
if (this.$route.path != this.path) this.$router.replace(this.path)
}
}
}
</script>
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
//MainTabBar.vue
<template>
<tab-bar>
<tab-bar-item path="/home" activeColor="red">
<img slot="item-ico" src="~assets/img/tabbar/home.svg" alt="">
<img slot="item-ico-active" src="~assets/img/tabbar/home_active.svg" alt="">
<div slot="item-text">首页</div>
</tab-bar-item>
<tab-bar-item path="/category" activeColor="blue">
<img slot="item-ico" src="../../assets/img/tabbar/category.svg" alt="">
<img slot="item-ico-active" src="../../assets/img/tabbar/category_active.svg" alt="">
<div slot="item-text">分类</div>
</tab-bar-item>
<tab-bar-item path="/shop" activeColor="pink">
<img slot="item-ico" src="../../assets/img/tabbar/shopcart.svg" alt="">
<img slot="item-ico-active" src="../../assets/img/tabbar/shopcart_active.svg" alt="">
<div slot="item-text">购物车</div>
</tab-bar-item>
<tab-bar-item path="/profile">
<img slot="item-ico" src="../../assets/img/tabbar/profile.svg" alt="">
<img slot="item-ico-active" src="../../assets/img/tabbar/profile_active.svg" alt="">
<div slot="item-text">我的</div>
</tab-bar-item>
</tab-bar>
</template>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
我们现在只需要将MainTabBar
组件在App.vue
中显示就可以了
# 实现路由跳转
我们还需要实现路由跳转,并且点击每一个栏目,能够展示激活状态的图标,所以就可以为其绑定一个点击事件,可以通过在事件中使用this.$router.push()
进行跳转
//父组件
<tab-bar-item path="/home" activeColor="red">
<div class="tab-bar-item" @click="itemClick">
props: {
path: String,
activeColor: String
}
methods: {
itemClick() {
if (this.$route.path != this.path) this.$router.replace(this.path)
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 父子组件通信:path=“path”和path=“path”的区别
如果是 <tab-bar-item path="/home" activeColor="red">
,那么在子组件props中的path:String
,父组件会直接将/home
赋值给子组件的path
如果是 <tab-bar-item :path="/home" activeColor="red">
,如果使用:
,那么就表示,为该属性邦绑定某个组件中的某个属性值,在子组件props中的path:String
,父组件会直接将data中,属性为/home
的值赋值给子组件的path
,他们之间的区别就要看有没有:
,也就是v-bind
,如果没有,就是简单的传值,如果有,就是绑定属性中的值





