1.开发背景
最近有一个新的前后端分离的项目需求,之前虽然有维护前后端分离的项目,但是自己没有从0到1的经验。从框架的搭建,工具书写配置的经验。之前仅仅是书写了前端需求。而且真正开始做前后端分离的项目也才仅仅一年多,加之之前做的是以nodejs为基础的react语言的项目,本次公司使用的却是基于vue的开发。基于刚好自己也想尝试挑战的目的开始了。
一开始想着自己手写一套全新框架,后来经过文档的查询学习发现真的是太难了。没有基础一些filter的书写可能还是实现起来有些难度,询问了客户端部门的同学,发现公司刚好这两个月开始搞自己的前端框架,刚好可以使用已经起来的框,但是框架可能还存在缺陷,需要边写边发现问题去解决。
开发工具:visual studio code 轻量级开发工具。
使用插件:
Atom One Dark Theme(主题字体颜色啦)
Chinese (Simplified) Language Pack for Visual Studio Code(汉化)
ESLint+Prettier格式化工具
Git History Diff(很好用的查看文件历史记录提交记录和每行上次提交人的插件)
2.前期准备
2.1环境搭建
2.1.1安装nodejs,使用brew直接使用命令行安装$ brew install node。
node -v 查看版本
npm -v确认npm是否安装(现在安装nodejs内置了npm自动安装)如果没有直接安装npm
2.2项目搭建
2.2.1全局安装
安装脚手架
使用$yarn install /npm install 安装相关依赖包
使用$yarn dev /npm run start/npm run dev任一命令启动项目即可
2.3项目提交
新建本地项目需要提交到远程仓库。
1)初始化项目,git init
2)检查项目已更改的信息,git status
3)添加新文件,git add . 备注:(.是所有新增的文件) 或者 git add filename (文件名)
4)将所有修改的文件提交到本地仓库,git commit -am "注释信息" 备注:-a表示所有修改还没提交的文件
5)这时候远程仓库还没有项目,要去远程仓管新建一个项目,将项目的ssh地址复制下来
6)添加源地址,git remote add origin ssh地址
7)执行git remote -v
8)此时本地没有和远程仓库已有的文件合并,执行git fetch
9)将本地和远程的合并,git rebase origin/master
10)最后push到远程仓库,git push origin master :master
3.学习开发
本次项目主要使用vue+ElementUI的开发的脚手架。
首先可以观察一下官网https://cn.vuejs.org/v2/guide/进行学习。
另外在我看来主要的部分是:生命周期和组件的使用。
3.1前期必备技能
之前有做过相关开发,实践之中明白一种语言的书写是很方便的,但是难点是理解生命周期,以及灵活的运用,达到自己想要的目的。好的前端是能够极大程度通过控制生命周期达到控制所有组件出现的方式和时机的。
学习vue的生命周期可以参考官网的文档,还是可以粗略理解的。https://cn.vuejs.org/v2/guide/instance.html
一个新的vue的生成,则都要经过以上步骤。根据需要,可以在不同阶段控制方法的调用。
上图很清晰的表明了vue在生命周期的各个阶段做的事情,并且提供了生命周期的几个回调函数
beforeCreate 创建之前:已经完成了 初始化事件和生命周期
created 创建完成:已经完成了 初始化注册和响应
beforeMount 挂载之前:已经完成了模板渲染
mounted :挂载之后:已完成HTML虚拟化,创建了el节点 可以操作DOM了
beforeDestroy :摧毁之前:整个vue都处在实时监控空渲染和更新
destroyed: 已摧毁,已经摧毁了观察者,子元素和事件监听
所以,在完成HTML渲染之后,初始化请求数据是安全可靠的,也就是把vue初始化请求的数据放在mounted的钩子函数中比较好。
需要明确的是:
vue提供了生命周期的钩子函数,其值就是一个函数。既然是钩子函数,在该触发的时候,会自动调用,不需要我们手动调用。
方法一般写在methods内。这时候如何控制方法的触发实现,则可在生命周期内完成。
比如说列表页应该进入页面直接加载,便可在mounted、created直接调用列表查询接口的方法。在页面渲染前完成调用等。数据的加载则在render之后等等。
另外,配合一些监视器的使用,即可完成数据变动更新的实时监控等。
3.2ElementUI
首先是用这个组件库之前大概看一下都有什么组件,方便业务开发和布局中遇到需求能直接使用所需成品组件,无需自行设计实现。
该组件库能满足大部分表单和页面设计的全部需求。直接复制示例代码可直接使用,仅需手动实现方法,完成function的操作。如有各种情况,参考下方api使用即可~
官方网站:https://element.eleme.io/#/zh-CN/component/installation
3.3必须要会的技能
3.3.1子父组件嵌套
3.3.1.1组件
前后端分离的出现是为了项目解藕,同步开发。在开发过程中还是要注意代码的质量问题。
重复使用的部分或者某个逻辑功能都可抽取成自己设计的组件重复使用。开发中组件的书写能力,基本可以判定一个人代码的水平。
我比较菜了,只能写一些简单的表单或者页面抽取出来,比如一些通用弹框dialog的格式等等。
我们可以书写的比如说一些需要重复使用的选取人物的下拉框,比如某个表单需要一些审核人,符合人。这些都可以通用使用同样的接口,封装成组件。再比如下拉框同时支持模糊搜索的的公用组件、通用分页、通用多条件搜索查询模块等等。
自定义组件参考官方文档使用即可。https://cn.vuejs.org/v2/guide/components-custom-events.html
3.3.1.2子父组件传值
书写了组件即要学习子父组件如何传值问题,使用element-UI中的Dialog 对话框 + vue组件示例:
1)定义html
<div @click="MyAnalyze()">我的模块啦</div>
<el-dialog title="" :visible.sync="dialogBiomeVisible">
<NationalBiome :closeValue="'TypeBiome'" @closeMoule="closeMoule"></NationalBiome>
</el-dialog>
其中:<el-dialog> </el-dialog> 这是element-UI自带的标签,
:visible.sync="" 是用来控制显示或者隐藏状态,当dialogBiomeVisible的值为true的时候为显示,false的时候就是隐藏,
<NationalBiome></NationalBiome> 这个就是自己定义的组件名;
2)引入组件
<script>
import NationalBiome from './National_Biome'; //组件内部引入 ---编辑生态区
export default {
name: 'App',
components:{ //定义组件
NationalBiome, //编辑生态区
},
}
</script>
其中,components中用来定义组件名称,名称要和important的时候保持一致
3)传值--父组件传子组件 父组件中的定义 父组件向之组件传值的时候,需要在组件标签中定义一个自定义属性进行传值,可以传一个字符串,也可以传一个变量
子组件中的定义(取值) 子组件在export default{}中通过props来进行接收,使用的时候可以直接当变量使用,js中通过this.closeValue取值,html中{{closeValue}}
4)传值--子组件传父组件 子组件中的定义 子组件中通过触发某个事件,然后通过this.$emit()来进行传值,第一个值是事件名,第二个是传递的值
<!--关闭按钮-->
<div class="fr right_icon" @click="closeBtn()">
<s></s>
</div>
methods:{
//点击关闭的时候--给调用的父组件传值
closeBtn(){
if(this.closeValue == "TypeBiome"){
this.$emit('closeMoule','closeMoule1')
}
}
}
父组件定义(取值) 定义一个事件监听子组件的数据变化 closeMoule方法的参数就是子组件中closeMoule1的值
<SpeciesAnalyzed :closeValue="'TypeBiome'" @closeMoule="closeMoule"></SpeciesAnalyzed>
methods:{
//获取自组建传过来的值--关闭编辑生态区的弹框
closeMoule(e){
alert(e)
}
3.3.2路由的使用
首先学习一下官方文档:https://cn.vuejs.org/v2/guide/routing.html
路由的使用配置:https://router.vuejs.org/zh/guide/essentials/dynamic-matching.html
主要包括页面url的设置使用,页面跳转等等~使用方法参考上面官方。重点使用编程式路由。
使用实例:
跳转页面:
this.$router.push({
name: 'query',
params: {
id: id,
name: name
}
})
跳转后页面:
data() {
return {
id: this.$route.params.id,
name: this.$route.params.name
}
}
我想讲的重点就是关于传参问题~
1)简单来说明一下route的区别
//$router : 是路由操作对象,只写对象
//$route : 路由信息对象,只读对象
//操作 路由跳转
this.$router.push({
name:'hello',
params:{
name:'word',
age:'11'
}
})
//读取 路由参数接收
this.name = this.$route.params.name;
this.age = this.$route.params.age;
2)query传递参数
我看了很多人都说query传参要用path来引入,params传参要用name来引入,只是我测试了一下,query使用name来引入也可以传参,使用path也可以。
//query传参,使用name跳转
this.$router.push({
name:'second',
query: {
queryId:'20180822',
queryName: 'query'
}
})
//query传参,使用path跳转
this.$router.push({
path:'second',
query: {
queryId:'20180822',
queryName: 'query'
}
})
//query传参接收
this.queryName = this.$route.query.queryName;
this.queryId = this.$route.query.queryId;
3)params传递参数
注:使用params传参只能使用name进行引入
//params传参 使用name
this.$router.push({
name:'second',
params: {
id:'20180822',
name: 'query'
}
})
//params接收参数
this.id = this.$route.params.id ;
this.name = this.$route.params.name ;
//路由
{
path: '/second/:id/:name',
name: 'second',
component: () => import('@/view/second')
}
需要注意的是:
params是路由的一部分,必须要在路由后面添加参数名。query是拼接在url后面的参数,没有也没关系。
params一旦设置在路由,params就是路由的一部分,如果这个路由有params传参,但是在跳转的时候没有传这个参数,会导致跳转失败或者页面会没有内容。
如果路由后面没有 /:id/:name,地址栏没有参数。如果你刷新一下,就会发现页面失败,因为我们不可能让用户不要刷新,所以我们必须在路由后面加上 /:id/:name。
如果这时我们使用path进行传参的话,使用path传参什么效果都没有。
//params传参 使用path
this.$router.push({
path:'second',
params: {
id:'20180822',
name: 'query'
}
})
//params接收参数
this.id = this.$route.params.id ;
this.name = this.$route.params.name ;
以上,关于传参问题总结如下:
1.传参可以使用params和query两种方式。
2.使用params传参只能用name来引入路由,即push里面只能是name:’xxxx’,不能是path:’/xxx’,因为params只能用name来引入路由,如果这里写成了path,接收参数页面会是undefined!!!
3.使用query传参使用path来引入路由。
4.params是路由的一部分,必须要在路由后面添加参数名。query是拼接在url后面的参数,没有也没关系。
5.二者还有点区别,直白的来说query相当于get请求,页面跳转的时候,可以在地址栏看到请求参数,而params相当于post请求,参数不会再地址栏中显示。
下次再叙:
上传下载踩过的坑
解构赋值(es6)
props、state、$emit()
下次再续