引言
如今前端框架也越来越丰富,学习成本也在逐渐加深,我作为纯后端Java开发人员,也学习了一下目前前端比较火的vue,并将学习的第一阶段成果以一个高可用,可自定义内容的,自己手动撸的一个封装好的一个tabbar组件。本章关于里面用到的知识点的原理不会过多的去讲解,主要作为一次初级入门的实践示例来分享。
封装好的tabbar作用
这是我第一个小实践示例。主要用到 @vue/cli4.x+vue2.x+vue-router(路由)
来实现。实现好的效果如下图展示:
封装好下面的tabbar,跳转不同的路径显示不同的vue页面,下面的按钮个数可以自定义,点击的效果颜色也可以自定义,以及图标跟文字都是可以实现类似参数传递的功能来高度自定义tabbar的内容。
- @vue/cli4.x: 这是vue原生的官方脚手架。具体的详细的介绍我不多说了,你可以理解为用它可以创建一个vue的项目的架子,相当于建房子的一个框架,把一些最基本的东西给你生成好了,你只需要去具体实现你自己的业务代码。你也可以查看官网的介绍点这里
-
vue2.x:
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。
摘抄自官网,曾今我有很长时间都读错了它。 -
vue-router: 是
vue.js
官方的路由管理器。它和vue.js的核心深度集成。
应用
开发正式开始之前,需要准备的工作
- WebStorm 2019.3.2 x64开发工具的安装
- node.js的安装
1、在webstorm的命令行窗口或者cmd窗口安装官网提供的最新脚手架@vue/cli
。我这里直接在webstorm命令行窗口进行安装演示,如图:
点击Terminal是打开命令行的操作。
npm install -g @vue/cli
安装命令中-g
表示全局安装。其实我之前已经在我电脑上安装过了,这里为了演示。2、使用脚手架创建tabbar项目。执行
vue create tabbar
命令后会弹出如下选择界面:default表示它给你推荐的默认配置
- babel:
babel是一个JavaScript编译器;
babel是一个工具链,主要用于将ECMAScript2015+版本的代码转换为向后兼容的JavaScript语法,以便能够在当前和旧版本的浏览器或其它环境中运行
-
eslint: 可以理解为质量检查工具,让你可以对自己有个相对规范的开发
如果我们选择 manually select features,那么脚手架会提供更多个性化的配置让我们选择如何初始化项目。
上下键选择,空格键确认选择。这里我简单描述下每个配置选项
- typescript: 使用下一代Javascript的typescript语法,可以理解为更新的脚本语言,如果不熟练的话不推荐使用。
- Progressive Web App (PWA) Support: 我在知乎上找到这样一段描述
Progressive Web App其实严格说来不是一个产品,而是一种理念,或者叫打包产品,因为他是把众多能让WEB产品APP化的能力的一个集合。
从Google官方网站介绍内容提炼一下,PWA的三大基本能力分别是:1、 类APP交互 2、消息推送 3、离线缓存
我的理解是将我们的应用可以整的类似app的交互体验,即webapp。
- Router: 是否安装路由
- Vuex: 是否安装全局状态管理器
- CSS Pre-processors: 选择CSS 预处理类型
- Linter / Formatter :一种规范类型
- Unit Testing:选择Unit测试方式
- E2E Testing: 端到端的测试,E2E是end to end 的简写
当你选择完这个个性化的配置后,他会提示你是否保存这个默认配置,方便下次使用。我的项目是选择了默认的配置
生成后的项目如图:
我们主要是在
src
目录下进行开发。3、安装vuerouter路由
然后我们在vue中安装vuer-outer,配置我们的页面
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from "./routes"
//1、先在vue中安装router路由
Vue.use(VueRouter);
//2、创建router实例,然后传入‘routers’配置
const router = new VueRouter({
routes, //传入写好的路由页面配置
mode: 'history' //可以使得页面跳转时不带#号
})
//3、导出路由对象
export default router;
代码中有详细的注释、关于为什么用import、export这种概念性的不做过多描述
其中路由的页面配置
//定义路由
const routes = [
{
path: '',
redirect: '/home'
},
{
path: '/home',
meta: {
title: '首页'
},
component: ()=>import("views/home/Home")
},
{
path: '/category',
meta: {
title: '分类'
},
component: ()=>import("views/category/Category")
},
{
path: '/cart',
meta: {
title: '购物车',
},
component: ()=>import("views/cart/Cart")
},
{
path: '/profile',
meta: {
title: '我的'
},
component: ()=>import("views/profile/Profile")
}
]
export default routes;
将配置好的路由放入vue实例中去
views文件夹下创建我们的业务所需页面
脚手架的文件夹命名是有规范的,页面文件一般建立在views下面,router即路由的文件所在位置
里面的资源可以在我的gitee代码仓库中进行下载。
4、敲黑板,重点来了,组件的创建
我们将tabbar看作一个整体,封装第一层组件
TabBar.vue:
<template>
<div id = "tab-bar">
<!--定义一个插槽,里面的内容由外部来定义-->
<slot></slot>
</div>
</template>
<script>
export default {
name: "TabBar"
}
</script>
<style scoped>
#tab-bar {
display: flex;
background-color: #f6f6f6;
position: fixed;
left: 0;
right: 0;
bottom: 0;
box-shadow: 0 -3px 1px rgba(100,100,100,.2);
}
</style>
TabBar.vue页面中我只定义了一个插槽,这个插槽可以放任何我们业务需要的东西进去,首先将tabbar的大筐筐的样式和布局来定义好
slot
插槽的内容外部来定义。TabBarItem.vue:针对每个按钮的封装实现
<template>
<div class="tab-bar-item" @click="tabBarItemClick">
<!--图片区域-->
<!--未点击图片显示状态-->
<div v-if = "!isActive">
<slot name="item-icon"></slot>
</div>
<!--点击图片显示状态-->
<div v-else>
<!--创建一个具名插槽-->
<slot name="item-icon-active"></slot>
</div>
<!--文字区域-->
<div :style = "isActiveColor">
<slot name="item-text"></slot>
</div>
</div>
</template>
<script>
export default {
name: "TabBarItem",
//接收来自父组件的参数
props: {
path: String, //第一种写法 参数:类型
activeColor: { //第二种写法,用对象来接收。可以不光定义接收的参数类型,还可以定义默认值
type: String,
default: 'red'
}
},
data() {
return {
}
},
//定义我们需要的计算属性
computed: {
isActive() {
//判断当前点击的是否与路由的路径一致
return this.$route.path == this.path;
},
isActiveColor() {
return this.isActive ? {color: this.activeColor} : {}
}
},
methods: {
tabBarItemClick() {
console.log('path===' + this.path);
//进行切换路由页面
this.$router.replace(this.path);
}
}
}
</script>
<style scoped>
.tab-bar-item {
flex: 1;
text-align: center;
height: 49px;
font-size: 14px;
}
.tab-bar-item img {
width: 24px;
height: 24px;
margin-top: 3px;
vertical-align: middle;
margin-bottom: 2px;
}
</style>
props: props用来接收父级传过来的参数
来定义父级传过来的参数,
path: 父级定义好的跳转路径
activeColor: 定义父级传过来的点击的切换颜色
此页面定义了三个具名插槽slot
:<slot name="item-icon"></slot> :没有被点击的图片插槽,这里的插槽使得图片的定义由父级来定义
<slot name="item-icon-active"></slot>:被点击的图片插槽,这里的插槽使得图片的定义由父级来定义
-
<slot name="item-text"></slot>:文字区域插槽
MainTabBar.vue:父级页面,传入业务需要的图标参数与文字到子页面的插槽中
<template>
<tab-bar>
<!--path和activeColor相当于父组件向子组件传递的参数,子组件用props来接收-->
<tab-bar-item path="/home" activeColor="deepPink">
<img slot="item-icon" src="~assets/img/tabbar/home.svg" alt="">
<img slot="item-icon-active" src="~assets/img/tabbar/home_active.svg" alt="">
<div slot="item-text">首页</div>
</tab-bar-item>
<tab-bar-item path="/category" activeColor="deepPink">
<img slot="item-icon" src="~assets/img/tabbar/category.svg" alt="">
<img slot="item-icon-active" src="~assets/img/tabbar/category_active.svg" alt="">
<div slot="item-text">分类</div>
</tab-bar-item>
<tab-bar-item path="/cart" activeColor="deepPink">
<img slot="item-icon" src="~assets/img/tabbar/shopcart.svg" alt="">
<img slot="item-icon-active" src="~assets/img/tabbar/shopcart_active.svg" alt="">
<div slot="item-text">购物车</div>
</tab-bar-item>
<tab-bar-item path="/profile" activeColor="deepPink">
<img slot="item-icon" src="~assets/img/tabbar/profile.svg" alt="">
<img slot="item-icon-active" src="~assets/img/tabbar/profile_active.svg" alt="">
<div slot="item-text">我的</div>
</tab-bar-item>
</tab-bar>
</template>
<script>
import TabBar from "components/tabbar/TabBar";
import TabBarItem from "components/tabbar/TabBarItem";
export default {
name: "MainTabBar",
components: {
TabBar,
TabBarItem
}
}
</script>
<style scoped>
</style>
封装好这个组建后,vue主页面进行引用
<template>
<div id="app">
<router-view/>
<MainTabBar></MainTabBar>
</div>
</template>
<script>
import MainTabBar from "components/tabbar/MainTabBar";
export default {
name: 'App',
components: {
MainTabBar
}
}
</script>
<style>
@import "assets/css/base.css";
</style>
<router-view/>
放入我们配置好的路由页面。
最后我们输入 npm run serve
我们输入
npm run serve
命令是由package.json页面配置决定的注意:页面中的路径在 vue.config.js进行了别名配置,项目用到的资源和导入页面组件时所以才可以不用写绝对路径。
module.exports = {
configureWebpack: {
resolve: {
alias: {
'assets': '@/assets',
'components': '@/components',
'views': '@/views'
}
}
}
}
这里的 @
表示项目的src目录,vue以及帮我们定义好了,这里定义好目录别名后。项目内部用到图片路径就可以直接用我们配置好的别名路径代替全局路径了
- 1、import导入页面的时候可以直接用配置好的别名
- 2、html标签,vue页面模板用到的时候需要在配置好的别名路径前加
~
作者:金哲一(jinzheyi)【笔名】
本文代码地址:https://gitee.com/jinzheyi/vue
本文链接:https://www.jianshu.com/p/b2ae3e903300