國慶在回家的路上,得知了vue2發佈了正式版,
國慶回來後,在公司內兩個項目便直接應用上了vue2,
一個是PC端的商戶後臺,一個是微信端商城,
都是基於Vue二、vue-router、vuex ......
在開發的過程當中,遇到了一系列的問題,
好比頁面後退數據還原,滾動條還原,
登陸超時,獲取列表數據,表單提交,
多臺服務器自動化部署,最終後一個個解決了,
可以平穩的從react切換到vue2開發,vue的文檔功不可沒。複製代碼
github:github.com/lzxb/vue2-d…javascript
.
|-- config // 項目開發環境配置
| |-- index.js // 項目打包部署配置
|-- src // 源碼目錄
| |-- components // 公共組件
| |-- header.vue // 頁面頭部公共組件
| |-- index.js // 加載各類公共組件
| |-- config // 路由配置和程序的基本信息配置
| |-- routes.js // 配置頁面路由
| |-- css // 各類css文件
| |-- common.css // 全局通用css文件
| |-- iconfont // 各類字體圖標
| |-- images // 公共圖片
| |-- less // 各類less文件
| |-- common.less // 全局通用less文件
| |-- pages // 頁面組件
| |-- home // 我的中心
| |-- index // 網站首頁
| |-- login // 登陸
| |-- signout // 退出
| |-- store // vuex的狀態管理
| |-- index.js // 加載各類store模塊
| |-- user.js // 用戶store
| |-- template // 各類html文件
| |-- index.html // 程序入口html文件
| |-- util // 公共的js方法,vue的mixin混合
| |-- app.vue // 頁面入口文件
| |-- main.js // 程序入口文件,加載各類公共組件
|-- .babelrc // ES6語法編譯配置
|-- gulpfile.js // 啓動,打包,部署,自動化構建
|-- webpack.config.js // 程序打包配置
|-- server.js // 代理服務器配置
|-- README.md // 項目說明
|-- package.json // 配置項目相關信息,經過執行 npm init 命令建立
.複製代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no,minimal-ui">
<title>vue2-demo</title>
</head>
<body>
<div id="app">
<router-view></router-view>
</div>
</body>
</html>複製代碼
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './config/routes'
import store from './store/'
import components from './components/' //加載公共組件
import './css/common.css'
import './less/common.less'
Object.keys(components).forEach((key) => {
var name = key.replace(/(\w)/, (v) => v.toUpperCase()) //首字母大寫
Vue.component(`v${name}`, components[key])
})
Vue.use(VueRouter)
const router = new VueRouter({
routes
})
router.beforeEach(({meta, path}, from, next) => {
var { auth = true } = meta
var isLogin = Boolean(store.state.user.id) //true用戶已登陸, false用戶未登陸
if (auth && !isLogin && path !== '/login') {
return next({ path: '/login' })
}
next()
})
new Vue({ store, router }).$mount('#app')複製代碼
import App from '../app'
export default [
{
path: '/',
component: App,
children: [
{
path: '/login', //登陸
meta: { auth: false },
component: resolve => require(['../pages/login/'], resolve)
},
{
path: '/signout', //退出
component: resolve => require(['../pages/signout/'], resolve)
},
{
path: '/home', //我的主頁
component: resolve => require(['../pages/home/'], resolve)
},
{
path: '/', //首頁
meta: { auth: false },
component: resolve => require(['../pages/index/'], resolve)
},
{
path: '*', //其餘頁面,強制跳轉到登陸頁面
redirect: '/login'
}
]
}
]複製代碼
<style lang="less" scoped> </style>
<template>
<router-view></router-view>
</template>
<script> export default { } </script>複製代碼
import Vue from 'vue'
import Vuex from 'vuex'
import user from './user'
Vue.use(Vuex)
export default new Vuex.Store({
strict: process.env.NODE_ENV !== 'production', //在非生產環境下,使用嚴格模式
modules: {
user
}
})複製代碼
import Vue from 'vue'
export const USER_SIGNIN = 'USER_SIGNIN' //登陸成功
export const USER_SIGNOUT = 'USER_SIGNOUT' //退出登陸
export default {
state: JSON.parse(sessionStorage.getItem('user')) || {},
mutations: {
[USER_SIGNIN](state, user) {
sessionStorage.setItem('user', JSON.stringify(user))
Object.assign(state, user)
},
[USER_SIGNOUT](state) {
sessionStorage.removeItem('user')
Object.keys(state).forEach(k => Vue.delete(state, k))
}
},
actions: {
[USER_SIGNIN]({commit}, user) {
commit(USER_SIGNIN, user)
},
[USER_SIGNOUT]({commit}) {
commit(USER_SIGNOUT)
}
}
}複製代碼
import header from './header'
export default { header }複製代碼
<style lang="less" scoped> .header { position: relative; line-height: 38px; color: #fff; text-align: center; background: #222; .item { position: absolute; top: 0; bottom: 0; z-index: 1; a { color: #fff; } } .left { left: 10px; } .right { right: 10px; } } </style>
<template>
<header class="header">
<div class="item left">
<slot name="left"></slot>
</div>
<div class="title">{{title}}</div>
<div class="item right">
<slot name="right"></slot>
</div>
</header>
</template>
<script> export default { props: { title: { type: String, default: '' } } } </script>複製代碼
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button{
-webkit-appearance: none !important;
margin: 0;
}複製代碼
* {
padding: 0;
margin: 0;
}複製代碼
<style lang="less" scoped> .login-msg { padding: 50px; text-align: center; } .msg { padding: 50px; text-align: center; font-size: 20px; color: red; } </style>
<template>
<div>
<v-header title="首頁">
<router-link slot="right" v-if="user.id" to="/home">{{user.name}}</router-link>
</v-header>
<div class="login-msg" v-if="!user.id">
<router-link to="/login">你還未登陸,請先登陸</router-link>
</div>
<div class="msg" v-if="user.id">
<img width="50" :src="logo" alt=""> <br>
哈哈,恭喜你已經入坑Vue2
</div>
</div>
</template>
<script> import { mapState } from 'vuex' import logo from './logo.png' export default { data() { return { logo } }, computed: mapState({ user: state => state.user }), } </script>複製代碼
<style lang="less" scoped> .login { padding: 50px; text-align: center; .line { padding: 5px; input { padding: 0 10px; line-height: 28px; } } button { padding: 0 20px; margin-top: 20px; line-height: 28px; } } </style>
<template>
<div>
<v-header title="登陸">
<router-link slot="left" to="/">返回</router-link>
</v-header>
<form class="login" v-on:submit.prevent="submit">
<div class="line">
<div v-show="btn && !form.id">id不能爲空</div>
<input type="number" placeholder="輸入你的id" v-model="form.id">
</div>
<div class="line">
<div v-show="btn && !form.name">用戶名不能爲空</div>
<input type="text" placeholder="輸入你的用戶名" v-model="form.name">
</div>
<button>登陸</button>
</form>
</div>
</template>
<script> import { mapActions } from 'vuex' import { USER_SIGNIN } from 'store/user' export default { data() { return { btn: false, //true 已經提交過, false沒有提交過 form: { id: '', name: '' } } }, methods: { ...mapActions([USER_SIGNIN]), submit() { this.btn = true if(!this.form.id || !this.form.name) return this.USER_SIGNIN(this.form) this.$router.replace({ path: '/home' }) } } } </script>複製代碼
<style lang="less" scoped> </style>
<template>
<div>
<v-header title="首頁">
<router-link slot="left" to="/">首頁</router-link>
<router-link slot="right" to="/signout">退出</router-link>
</v-header>
<div style="padding: 50px;">{{user.name}}歡迎回家</div>
</div>
</template>
<script> import { mapState } from 'vuex' export default { computed: mapState({ user: state => state.user }), } </script>複製代碼
<style lang="less" scoped> .btn { padding: 50px; text-align: center; button { padding: 5px 10px; } } </style>
<template>
<div>
<v-header title="退出">
<router-link slot="left" to="/home">返回</router-link>
</v-header>
<div class="btn">
<button v-on:click="submit">確認退出</button>
</div>
</div>
</template>
<script> import { mapActions } from 'vuex' import { USER_SIGNOUT } from 'store/user' export default { methods: { ...mapActions([USER_SIGNOUT]), submit() { this.USER_SIGNOUT() this.$router.replace({ path: '/login' }) } } } </script>複製代碼
vue2重構cnode社區,將會近日完成,
一個從0構建的vue2的完整項目,
能夠使用最簡單的方式實現頁面後退時狀態還原,
局部滾動條還原等。複製代碼