vue(vue-cli+vue-router)+babel+webpack项目搭建入门(三)开发实战
vue(vue-cli+vue-router)+babel+webpack项目搭建入门<三>
本系列文章将介绍基于vue+webpack的前端项目的构建过程。文章分为四章内容,第一章介绍开发环境的部署,第二章介绍项目的构建,第三章以一个登陆-主界面的纯前端项目为示例进行实战开发,第四章介绍项目打包部署以及部署上线时可能遇到的问题。本系列文章主要介绍项目构建的流程,旨在为不了解现代前端项目开发过程的读者提供一个流程介绍,不会在一些细节上深究讲解,因此本文适合初学者使用阅读。
本系列文章中使用的配套示例代码请在示例代码下载地址进行下载。本文的实战项目可在项目在线地址进行浏览观看。
在编写本系列文章时,各框架插件版本号如下:
- nodejs v10.4.1;
- npm v6.1.0;
- vue v2.5.2;
- vue-cli v2.9.6;
- vue-router v3.0.1;
- vuex v3.1.0;
- babel v6.5.2;
- babel-polyfill v6.23.0;
- webpack v3.6.0;
开发功能-实战示例
成功启动项目之后,让我们来为这个项目填充一些内容。对于本文的示例项目“点客论坛”,他有一个登录界面Login;有一个主界面Main,主界面中有两个子界面:一个登录日志界面LogInfo和一个论坛内容界面HomePage;最后有一个404界面NotFound。现在让我们来实现他们。想要了解项目的具体结构,请查看项目的在线浏览地址。
根据项目安装插件依赖
在初始化项目时,vue-cli的脚手架模板已经为项目安置了一些插件依赖。但有时为了实现项目的需求,需要不断的增加插件,点客论坛也不例外。在这个项目中我们需要增加vuex和babel-polyfill两个额外的插件依赖。首先修改package.json文件中的dependencies项,添加两个依赖项,修改后结果如下:
"dependencies": {
"vue": "^2.5.2",
"vue-router": "^3.0.1",
"vuex": "^3.1.0",
"babel-polyfill": "^6.26.0"
}
我们为项目增加了vuex v3.1.0和babel-polyfill v6.26.0两个插件依赖,其中vuex为项目提供状态管理服务,babel-polyfill为babel默认不支持的一些ES6语法进行转义。因为这两个插件都是运行时插件,所以需要将他们放置在dependencies中。
插件的版本符号
在package.json中,可以为dependencies和devDependencies插件依赖的版本号进行指定,有如下几种符号:
1.version必须完全和version一致,如1.2.2;
2.>version、>=version大于或大于等于version;
3.<version、<=version小于或小于等于version;
4.version小版本号不低于version。比如1.2.2,表示安装1.2.x的最新版本(不低于1.2.2),但是不安装1.3.x,也就是说安装时不改变大版本号和次要版本号;
5.^version中间版本号不低于version。比如ˆ1.2.2,表示安装1.x.x的最新版本(不低于1.2.2),但是不安装2.x.x,也就是说安装时不改变大版本号。
6.*所有;
7.latest最新版本;
一般来说,一个插件(或框架)的大版本号(版本号分三位:大版本.中版本.小版本)不变的话,其API和使用方式是不会发生太大的变化。所以通常情况下,package.json中的版本号只要保证大版本号相同即可。
在项目的根目录路径下(D:\WebStorm\workspace\dk-bbs),用cmd执行”npm install”命令,安装新增的两个插件。npm执行一段时间之后,插件下载并安装完成。此时重启项目,用cmd在项目根目录路径下(D:\WebStorm\workspace\dk-bbs)执行”npm start”,启动项目。
如果之前已经用cmd启动了项目,有两种简单的方式停止项目的运行:
1.直接关闭cmd命令行窗口就可以停止已经运行的项目;
2.使用ctrl+c快捷键,来终止当前正在执行的任务,从而停止项目的运行;
项目内的配置代码
安装完了额外的插件,让我们开始真正开发这个程序。首先编写配置代码。
vue-router路由配置
点客论坛这个项目包含5个界面路由:登录页、主页面、主页面下的两个子页面、404页面。根据这样的路由结构,我们可以写出一个vue-router页面结构配置。找到vue-router配置文件,这个配置文件在vue-cli生成项目时已经存在了,其目录位置在:D:\WebStorm\workspace\dk-bbs\src\router\index.js,修改后代码如下:
import Vue from 'vue'
import Router from 'vue-router'
import Login from "@/components/Login.vue";
import Main from "@/components/Main.vue";
import HomePage from "@/components/HomePage.vue";
import LogInfo from "@/components/LogInfo.vue";
import NotFound from "@/components/NotFound.vue";
Vue.use(Router)
export default new Router({
routes: [
{
path: "/",
redirect:"/login"
},
{
path:"/login",
name:"Login",
component:Login
},
{
path: "/main",
name: "Main",
component: Main,
children: [
{
path:"homepage",
name:"HomePage",
component:HomePage
},
{
path:"loginfo",
name:"LogInfo",
component:LogInfo
}
]
},
//404
{
path: '*',
name:"NotFound",
component:NotFound
}
]
})
可以看到,因为项目模块不多,我们将所有的vue单文件都放在了components目录下。实际产品开发时,涉及到项目模块太多时,不能简单的将所有页面文件都暴露在components下,应该按照模块进行份文件目录存储。否则会造成不方便阅读查找的维护困难。
在vue-router配置文件中,首先用import
语句引入各个模块依赖,然后通过Vue.use(Router)
的方式来加载插件,接着导出一个Router对象,用来控制项目的路由关系。
登录页面Login、主界面Main页面以及404页面都是最外层的(其中404页面的路径配置成了“*”,这也就代表着只要前面的路由都未匹配成功,就进入404页面),而HomePage界面和LogInfo界面作为Main界面的两个子页面存在。
对于vue-router配置文件有一点需要开发人员注意,子路由(children)的路径(path)不能带"/“符号,带了”/"符号就变成一个绝对路径了,将会引起子路由失败。例如本项目中homepage是一个子路由,不要写成path:”/homepage”,正确的写法是path:”homepage”,这是vue-router插件的一个规定。
vuex状态控制配置
点客论坛项目中,需要在各个模块之间共享的数据有:记录用户行为、当前用户名。因此我们需要将他们配置进vuex的配置文件中。
首先,因为vuex是我们额外引入的插件,所以vue-cli脚手架并没有直接使用他,需要开发人员手工配置使用vuex。在D:\WebStorm\workspace\dk-bbs\src\目录位置 新建一个名为“store”的文件夹,并在store文件夹中新建一个index.js文件。向index.js文件加入如下内容:
import Vue from 'vue';
import Vuex from "vuex";
Vue.use(Vuex);
const store=new Vuex.Store({
state: {
username:"",
logs:[]
},
mutations: {
login:(state,data)=>{
state.username=data;
},
pushLog:(state,data)=>{
state.logs.push(data);
}
}
});
export default store;
可以观察到,vuex与vue-router配置文件的风格非常接近。都是先引入依赖,使用Vue.use(Vuex)
来加载插件,接着导出一个配置文件。在D:\WebStorm\workspace\dk-bbs\src\store\index.js文件中,我们初始化了两个状态量:username和logs。分别代表全局的用户名和全局的用户操作日志。接着我们定义了两个触发器:login和pushLog来对状态量进行修改。
完成了vuex的配置,需要让整个项目来读取这份配置文件。修改D:\WebStorm\workspace\dk-bbs\src\main.js文件。修改后文件内容如下:
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
其中修改的内容是:引入了vuex配置文件store\index.js和在new Vue()中部署store。
编写完以上这些项目内的配置代码,我们就可以着手开始业务代码的开发。
项目内的业务代码
登录页面Login
登录界面由一个输入框和一个按钮组成,输入框用来输入用户名,按下按钮之后就进入主界面。相应的程序会开始记录用户信息。
登录页的代码很简单,如下:
<template>
<div class="login-content">
<form action="" onsubmit="return false">
<input ref="username" type="text" name="username">
<input type="submit" value="登录" v-on:click="login">
</form>
</div>
</template>
<script>
export default {
name: 'Login',
data () {
return {};
},
methods:{
login:function(){
this.$router.push("main");
this.$store.commit("login",this.$refs.username.value);
this.$store.commit("pushLog",`用户:${this.$refs.username.value}在中国时间:${new Date()}登录系统`);
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
主界面Main
主界面的头部有导航栏,导航栏将路由到项目内各个页面。在每个导航栏按钮都绑定了事件,去记录用户的行为操作。该页面代码如下:
<template>
<div class="main-content">
<header class="header">
<nav v-for="item in navs" v-on:click="toPage(item.url)">{{item.name}}</nav>
</header>
<div>
<transition>
<router-view></router-view>
</transition>
</div>
</div>
</template>
<script>
export default {
name: 'Main',
data () {
return {
navs:[
{url:"login",name:"登录页"},
{url:"homepage",name:"首页"},
{url:"loginfo",name:"日志信息"},
{url:"notfound",name:"404页面"}
]
}
},
methods:{
toPage:function(url){
if(url==='login'){
this.$router.push('/login');
}else{
this.$router.push(`/main/${url}`);
}
this.$store.commit("pushLog",`${this.$store.state.username}进入了${url}页面`);
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.main-content .header{
border-bottom:1px solid;
}
</style>
主界面的子界面HomePage和LogInfo
HomePage界面展示一句欢迎登录的文本信息。代码如下:
<template>
<div class="homepage-content">
<p>{{msg+username}}</p>
</div>
</template>
<script>
export default {
name: 'HomePage',
data () {
return {
msg:"欢迎登录点客论坛,"
}
},
computed:{
username:function(){
return this.$store.state.username;
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
LogInfo从vuex管理的store对象中获取日志信息,将所有日志展示出来。代码如下:
<template>
<div class="loginfo-content">
<ul>
<li v-for="item in logs">{{item}}</li>
</ul>
</div>
</template>
<script>
export default {
name: 'LogInfo',
data () {
return {};
},
computed:{
logs:function(){
return this.$store.state.logs;
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
从这两个页面的代码中可以观察到,在页面中使用store中存储的状态时,需要将变量放在computed中作为函数的返回值来返回。只有这样,才可以保证每次触发器(mutation)改变store中的值时,页面可以监听到该变化。同样的,使用watch也是可行的。
404界面NotFound
该界面展示一张图片,用来提示用户当前路由错误。同时提供一个按钮用来返回主页。页面引用的图片放置在D:\WebStorm\workspace\dk-bbs\static\img路径下。代码如下:
<template>
<div class="notfound-content">
<p v-on:click="toPage('homepage')">{{msg}}</p>
<img v-bind:src="picUrl">
</div>
</template>
<script>
export default {
name: 'NotFound',
data () {
return {
msg:"返回首页",
picUrl:" /static/img/404.png"
}
},
methods:{
toPage:function(url){
this.$router.push(`/main/${url}`);
this.$store.commit("pushLog",`${this.$store.state.username}进入了${url}页面`);
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
开发总结
至此,我们就完成了整个项目的实现。下图就是点客论坛中的“日志信息”页面,这个页面将会记录进入网站后的所有操作行为。
因为基于vue-cli+webpack启动的项目是有热重载机制的,因此开发人员在修改项目代码之后,变化会自动生效到页面内容中。可以看到,此时的项目已经在开发环境运行良好。
虽然这个示例项目的内容非常简单,模块也非常的少(只有五个页面路由),但是我相信这个示例项目已经很好的把基于Vue生态构建的单页应用下,各个插件在项目中的作用和关联体现了出来。对于初学者来说,一定要仔细理解项目中各个环节的作用。对于需要更加深入学习的读者来说,插件官网以及插件源码为各位开发人员提供了更加清晰的说明和解释。
前端单页应用url哈希值介绍
url的锚(**#后面的内容)指示浏览器显示页面的哪个部分。锚的其他常见名字是:书签或哈希。锚总是以#**符号开头,如http://localhost:8080/#/login。
传统的锚的用法是,开发人员使得用户能很容易地在一个很长的文档页面的各个章节中“跳转”。比如,在网页的顶部有一个目录,所有的章节标题链向他们在文档中对应的章节。每个章节的最后可能有一个“回到顶部”的链接。博客和论坛仍然很广泛的使用这种机制。
锚的一个独特功能是,在它改变的时候,浏览器不会重新加载页面。因此锚是保存应用状态的理想地方,这也是单页应用使用最广泛的技巧。但同时要注意,正因为锚的改变不会引起页面刷新,因此单页应用在切换页面时,不会刷新滚动条。
最后让我们简要的回顾一下本章中,我们做了些什么:
1.引入额外的插件依赖,并用npm install安装,之后重启项目;
2.要让额外引入的插件能用起来,需要新增/修改一些配置文件,插件的使用方法在插件官网都会有详细的介绍;
3.根据项目需要,编写vue-router路由配置;
4.编写业务代码;
5. 如果开发过程中需要再引入额外插件,那就重复1-2步骤。如果开发过程中需要增加新的路由结构,那就重复3步骤;