vue2.0从0开发项目管理系统
1、自己的github建一个项目。
2、本地vue2.0项目初始化。
安装node.js,检查node版(node -v)。
安装webpack(npm install webpack -g),检查webpack版本。(webpage -v)。
安装vue-cli脚手架(npm install vue-cli -g),检查版本。(vue -V)。
接下来用vue-cli构建项目
vue init webpack myProject

3、将项目关联git地址,首次提交代码。
新建一个文件夹名为(vue2.0)
git init 初始化git生成一个.git文件
git remote add origin git地址 将文件关联到git远程仓库
将myProject文件夹中的初始化的文件拖到vue2.0文件夹中。
git add . 添加文件提交到暂存区
git commit -m 'init' 提交文件到本地仓库
git push -u origin master 这里加上-u是因为:远程库是空的,加了-u后,以后即可直接用git push代替git push origin master
4、安装iview等一些项目中需要用到的第三方模块。
iview-ui官网https://www.iviewui.com/
在main.js中全局引入,具体看官网的快速上手。
5、准备开发工作。
直观思路是不是要开发登录 ---》home等页面。登录页面在router.js里面定义路由和页面路径,然后考虑路由跳转的文件,未登录状态下页面要跳转至登录页面,判断是否登录的标识是,localstore里面是否有token,如果没有的话需要将路由更改跳转到login页面。vue router.js中使用router.beforeEach去实现。
import Vue from 'vue' import Router from 'vue-router' import Home from '@/components/Home' import login from '@/components/login' Vue.use(Router) const router = new Router({ routes: [ { path: '/', name: 'Home', component: Home }, { path: '/login', name: 'login', component: login } ] }) const isLogin = localStorage.getItem('token') || '' router.beforeEach((to, from, next) => { // 先判断路由要跳转到哪?跳转登录页面且是登录状态 if (to.name === 'login' && !isLogin) { next() } // 不先判断会报错 :Maximum call stack size exceeded /* 分析报错原因: next()表示路由成功,直接进入to路由,不会再次调用route.beforeEach() next('/login')表示路由拦截成功,重定向值login,会再次调用route.beforeEach() */ if (isLogin) { next() } else { next('/login') } }) export default router
然后跳转login对应的页面就可以开心的开发页面了。
<template>
<div class="login_bg">
<div class="container">
<div class="left">
<h1>夜跑记录管理系统</h1>
<h2>study hard and make progress every day</h2>
</div>
<div class="right">
<div class="right_content">
<Form ref="formInline" :model="formInline" :rules="ruleInline">
<FormItem prop="user">
<Input type="text" size="large" clearable v-model="formInline.user" placeholder="用户名">
<Icon type="ios-person-outline" slot="prepend"></Icon>
</Input>
</FormItem>
<FormItem prop="password">
<Input type="password" size="large" clearable v-model="formInline.password" placeholder="密码">
<Icon type="ios-lock-outline" slot="prepend"></Icon>
</Input>
</FormItem>
<FormItem>
<Button long type="default" ghost @click="handleSubmit('formInline')">登 录</Button>
</FormItem>
</Form>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
formInline: {
user: '',
password: ''
},
ruleInline: {
user: [
{ required: true, message: '请填写用户名', trigger: 'blur' }
],
password: [
{ required: true, message: '请填写密码', trigger: 'blur' },
{ type: 'string', min: 6, message: '密码长度不能小于6位', trigger: 'blur' }
]
}
}
},
methods: {
handleSubmit (name) {
this.$refs[name].validate((valid) => {
if (valid) {
this.$Message.success('Success!')
} else {
this.$Message.error('Fail!')
}
})
}
}
}
</script>
<style scoped>
.login_bg {
min-width: 1200px;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 10;
background: url("../../static/img/login_bg.jpg") center center no-repeat;
}
.container {
display: flex;
align-items: center;
}
.left {
text-align: center;
width: 50%;
color: #ffffff;
}
.right {
background-color: rgb(0 0 0 / 40%);
height: 100vh;
width: 350px;
z-index: 11;
width: 30%;
display: flex;
align-items: center;
}
.right_content{
width: 75%;
vertical-align: middle;
margin: 0 auto;
}
</style>

开心的完成login页面,接下来要登录了。登录调接口之前思考一个问题:请求接口怎么封装?请求和响应拦截要怎么处理?那就开始一步步封装模块。
6、封装axios
参考链接: https://juejin.im/post/5b55c118f265da0f6f1aa354 掘金的网址(很好)
在vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,它是基于promise的http库,可运行在浏览器端和node.js中。他有很多优秀的特性,例如拦截请求和响应、取消请求、转换json、客户端防御cSRF等。所以我们的尤大大也是果断放弃了对其官方库vue-resource的维护,直接推荐我们使用axios库。如果还对axios不了解的,可以移步axios文档。
npm install axios; // 安装axios
目录结构

axios里面是对请求超时、请求头、请求和响应拦截、环境的切换等的处理。
http.js里面封装了两个请求get、post。
Api文件里面是定义对应页面的请求。
话不多说,代码统统奉上:
axios.js:
import axios from 'axios'// 引入axios import router from '../router' // 设置 replace 属性(默认值: false)的话,当点击时,会调用 router.replace() 而不是 router.push(),于是导航后不会留下 history 记录。即使点击返回按钮也不会回到这个页面。 const toLogin = () => { router.replace({ path: '/login', query: { redirect: router.currentRoute.fullPath// 携带当前页面路由,以期在登录页面完成登录后返回当前页面 } }) } var instance = axios.create({timeout: 1000 * 12}) // 环境的切换 if (process.env.NODE_ENV === 'development') { instance.defaults.baseURL = 'https://www.baidu.com' } else if (process.env.NODE_ENV === 'debug') { instance.defaults.baseURL = 'https://www.ceshi.com' } else if (process.env.NODE_ENV === 'production') { instance.defaults.baseURL = 'https://www.production.com' } // post请求头的设置 instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8' // 请求拦截 instance.interceptors.request.use( config => { // 每次发送请求之前判断localStore是否存在token // 如果存在,则统一在http请求的header中加上token,这样后台根据token判断你的登录情况 // 即使本地存在token,也有可能是过期的,所以在相应拦截器中要对返回状态进行判断。 const token = localStorage.getItem('token') || '' token && (config.headers.token = token) return config }, error => { return Promise.error(error) } ) // 响应的拦截 instance.interceptors.response.use( response => { const code = response.data.code // 对状态码进行对应的处理 if (code === 0) { return Promise.resolve(response) } else if (code === 20000 || code === 20001 || code === 20002) { // 20000:用户token为空 20001:用户信息为空 20002:登录失效,请重新登录 // 清除token localStorage.removeItem('token') toLogin() return Promise.reject(response.data.msg) } else { if (response.data.msg) { return Promise.reject(response.data.msg) } } }, error => { return Promise.reject(error) } ) export default instance
http.js
import axios from './axios.js' import {Notice} from 'view-design' export function httpGet (url, params) { return new Promise((resolve, reject) => { axios.get(url, params).then(res => { resolve(res.data) }).catch(err => { Notice.error({ title: '错误', desc: err }) console.warn(err) reject(err) }) }) } export function httpPost (url, params) { return new Promise((resolve, reject) => { axios.post(url, params).then(res => { resolve(res.data) }).catch(err => { Notice.error({ title: '错误', desc: err }) console.warn(err) reject(err) }) }) }
login.js:
import {httpPost} from '../http.js'
export function login (params) {
return httpPost('/sys/user/login', params)
}
封装好axios之后就开始写登录方法了,因为管理系统页面较多,所以考虑到数据状态的管理,需要vuex来对数据进行管理。
那就开始愉快的封装vuex模块对应的一些东东吧。
7、封装vuex模块。
安装vuex:
npm install --save vuex
新建一个store文件夹用来管理vuex模块。
import Vue from 'vue' import Vuex from 'vuex' import user from './modules/user' import products from './modules/products' Vue.use(Vuex) export default new Vuex.Store({ modules: { user, products } })
user.js
import {login} from '../../request/Api/login'
import {Message} from 'view-design'
// state
// state提供数据源,所有的共享数据都要放到store的state中进行存储。
const state = {
token: '',
user: {},
menuList: []
}
/** mutations用于变更store中的数据。
* 1)只能通过mutations变更store中的数据,不可以直接操作store中的数据。
* 2)通过这个方式操作操作起来稍微有点繁琐,但是可以集中监控所有数据的变化。
* */
const mutations = {
setToken (state, token) {
state.token = token
},
setUserInfo (state, info) {
state.user = info
},
setMenuList (state, menu) {
state.menuList = menu
}
}
/**
* Action用于处理异步任务
* 如果通过异步操作数据必须使用Action,不能使用mutations,但是在Action中还是通过出发Mutation的方式间接变更数据。
*/
const actions = {
loginHandle (content, params) {
return new Promise((resolve, reject) => {
login(params).then(res => {
const result = res.result
localStorage.setItem('token', result.user.token)
localStorage.setItem('user', JSON.stringify(result.user))
localStorage.setItem('menuList', JSON.stringify(result.menus))
content.commit('setToken', result.user.token)
content.commit('setUserInfo', JSON.stringify(result.user))
content.commit('setMenuList', JSON.stringify(result.menus))
debugger
Message.success('登录' + res.msg)
resolve(result)
}).catch(error => {
reject(error)
})
})
}
}
const getters = {
}
export default{
state,
mutations,
actions,
getters
}
main.js里面要引入、挂载、处理store
import store from './store/index.js' import setStore from './store/setStore.js' new Vue({ el: '#app', router, store, created () { setStore() }, components: { App }, template: '<App/>' })
注意这个setStore,这个方法挂载在文件入口里面的原因是:登录之后将user信息储存到localStore中,登录之后进入页面之后store中的数据都置空了,所以在入口文件的created 的方法中set数据到store中。这样保证每个页面都能共享到stroe中的数据。
setStore.js
import store from './index' export default function setStore () { store.commit('setToken', localStorage.getItem('token')) store.commit('setUserInfo', localStorage.getItem('user')) store.commit('setMenuList', localStorage.getItem('menuList')) }
登录页面对应的修改:
import {mapActions} from 'vuex'
methods: {
...mapActions(['loginHandle']),
handleSubmit (name) {
this.$refs[name].validate((valid) => {
if (valid) {
let params = {
userName: this.formInline.user,
password: md5(this.formInline.password)
}
this.loginHandle(params).then(res => {
if (this.toPath) {
this.$router.push(this.toPath)
} else {
this.$router.push({
name: 'Home'
})
}
})
.catch(error => { console.log(error) })
.finally((msg) => {
console.log(msg)
})
} else {
return false
}
})
}
}
8、要搭建页面的公共组件了(header、menu、view)。
先优化下登录页面的样式吧。有亿点丑。
调整完毕的页面,还是一丑,没办法不是搞ui的。先这样吧!!!

github地址:
https://github.com/wenreq/basicsSys.git

浙公网安备 33010602011771号