web前端教程:Vue專案開發流程

千鋒HTML5學院發表於2019-05-15


一、企業專案開發流程

產品提需求

互動設計出原型設計

視覺設計出UI設計圖

前端開發出頁面模板

server端存取資料庫

驗收測試

二、為什麼要使用vue: 

5個前端,4個會vue,1個會react,那麼你該如何選擇

客戶要求使用vue

...

三、如何選擇腳手架

自己搭建腳手架 webpack

使用現成的腳手架 

vue-cli 基於webpack 3

@vue/cli 基於webpack 4

假設電腦中裝的時@vue/cli腳手架,但是想用vue-cli的模板,可以如下安裝指令

cnpm install -g @vue/cli

cnpm install -g @vue/cli-init

四、建立專案

@vue/cli

第一種建立方式: vue create mynewapp

第二種建立方式: vue ui

第三種建立法師: vue init webpack myapp

五、開始專案配置

1、如果做的移動端,那麼需要考慮300ms延時以及點選穿透的問題,甚至是部分android手機不支援promise的解決辦法,在index.html中引入如下程式碼,如果做的是pc端,忽略此步驟

// 避免移動端真機執行雙擊螢幕會放大

<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=0">

<script src=" <script> if ('addEventListener' in document) { document.addEventListener('DOMContentLoaded', function() { FastClick.attach(document.body); }, false); } if(!window.Promise) { document.writeln('<script src="); } </script>

2、修改目錄結構

src

api

assets

components

lib

router

store

views

App.vue

main.js

3、修改App.vue結構

cnpm i node-sass sass-loader -D

<template>

<div>

<div>

<header>頭部</header>

<div>內容</div>

</div>

<footer>底部</footer>

</div>

</template>

<script>

export default {

name: 'App'

}

</script>

<style>

@import '~@/lib/reset.scss';

html, body, .container, .detailContent {

@include rect(100%, 100%); // width: 100%; height: 100%;

}

.container, .detailContent {

@include flexbox(); // display: flex

@include flex-direction(column); // flex-direction:column

.box {

@include flex();

@include rect(100%, auto);

@include flexbox();

@include flex-direction(column);

.header {

@include rect(100%, 0.44rem);

@include background-color(#f66);

}

.content {

@include flex(); // flex: 1;

@include rect(100%, auto);

@include overflow(auto);

}

}

.footer {

@include rect(100%, 0.5rem);

@include background-color(#efefef);

@include flexbox();

a {

@include flex();

@include rect(auto, 100%);

@include flexbox();

@include justify-content(); // justify-content: center;

@include align-items(); // align-items: center;

@include text-color(#333);

&.active {

@include text-color(#f66);

}

}

}

}

</style>

4、依據結構設計頁面

views/home/index.vue

views/kind/index.vue

views/cart/index.vue

views/user/index.vue

以home為例

<template>

<div>

<header>首頁頭部</header>

<div>首頁內容</div>

</div>

</template>

<script>

export default {

}

</script>

<style>

</style>

5、配置路由

router/index.js

import Vue from 'vue'

import Router from 'vue-router'

import routes from './routes'

Vue.use(Router)

export default new Router({

routes

})

router/routes.js ----- 命名檢視+命令路由+路由的懶載入+路由重定向

// 如果一個頁面不需要底部,那麼就不要傳footer,比如kind無需底部

const routes = [

{

path: '/',

redirect: '/home'

},

{

path: '/home',

name: 'home',

components: {

default: () => import('@/views/home'),

footer: () => import('@/components/Footer')

}

},

{

path: '/kind',

name: 'kind',

components: {

default: () => import('@/views/kind'),

footer: () => import('@/components/Footer')

}

},

{

path: '/cart',

name: 'cart',

components: {

default: () => import('@/views/cart'),

footer: () => import('@/components/Footer')

}

},

{

path: '/user',

name: 'user',

components: {

default: () => import('@/views/user'),

footer: () => import('@/components/Footer')

}

}

]

export default routes

修改App.vue ---- 命名檢視(多檢視路由)default footer

<template>

<div>

<router-view></router-view>

<router-view name="footer"></router-view>

</div>

</template>

6、底部點選切換路由

components/Footer.vue,需要在App.vue中修改佈局樣式

<template>

<footer>

<ul>

<router-link tag="li" to="/home">

<span></span>

<p>首頁</p>

</router-link>

<router-link tag="li" to="/kind">

<span></span>

<p>分類</p>

</router-link>

<router-link tag="li" to="/cart">

<span></span>

<p>購物車</p>

</router-link>

<router-link tag="li" to="/user">

<span></span>

<p>我的</p>

</router-link>

</ul>

</footer>

</template>

<script>

export default {

}

</script>

7、編寫頁面

PC: element-ui 

iview 

移動端: mint-ui 

vant 

mint-ui 為例

cnpm i mint-ui -S

cnpm install babel-plugin-component -D

修改.babelrc檔案

{

"presets": [

["env", {

"modules": false,

"targets": {

"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]

}

}],

"stage-2"

],

"plugins": ["transform-vue-jsx", "transform-runtime",["component", [

{

"libraryName": "mint-ui",

"style": true

}

]]],

"env": {

"test": {

"presets": ["env", "stage-2"],

"plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs", "dynamic-import-node"]

}

}

}

7.1 main.js入口檔案處引入mintui

import Vue from 'vue'

import App from './App'

import router from './router'

import MintUI from 'mint-ui'

Vue.config.productionTip = false

Vue.use(MintUI)

7.2 封裝了banner.vue和prolist.vue元件

banner.vue元件中使用了UI庫 ---- 輪播圖預設佔據整個高度,提前設定好一個父容器

<template>

<div>

<mt-swipe :auto="4000">

<mt-swipe-item>11</mt-swipe-item>

<mt-swipe-item>22</mt-swipe-item>

<mt-swipe-item>33</mt-swipe-item>

</mt-swipe>

</div>

</template>

<script>

import Vue from 'vue'

import { Swipe, SwipeItem } from 'mint-ui'

Vue.use(Swipe, SwipeItem)

export default {

}

</script>

<style>

.banner {

height: 150px;

}

</style>

prolist.vue

<template>

<ul>

<li>

肖生客的救贖

</li>

</ul>

</template>

<script>

export default {

}

</script>

home/index.vue中引用元件

<template>

<div>

<header>首頁頭部</header>

<div>

<Banner />

<Prolist />

</div>

</div>

</template>

<script>

import Banner from '@/components/Banner'

import Prolist from '@/components/Prolist'

export default {

components: {

Banner,

Prolist

}

}

</script>

<style>

.banner {

height: 150px;

}

</style>

8、資料請求

cnpm i axios -S

8.1 新增mock資料功能 ----- 開發前期 ---- 後端沒有介面時這樣用

cnpm i mockjs -D

api/mock.js

// 引入mockjs

const Mock = require('mockjs')

const Random = Mock.Random

const doubandata = function () {

let articles = []

for (let i = 0; i < 10; i++) {

let newArticleObject = {

title: Random.csentence(5, 30),

thumbnail_pic_s: Random.dataImage('300x250', 'mock的圖片'),

author_name: Random.cname(),

date: Random.date() + ' ' + Random.time()

}

articles.push(newArticleObject)

}

return articles

}

// Mock.mock( url, post/get , 返回的資料);

Mock.mock('/douban', 'get', doubandata)

api/index.js

import axios from 'axios'

import { Indicator } from 'mint-ui'

const baseUrl = process.env.NODE_ENV === 'development' ? '' : '

console.log(baseUrl)

// 新增請求攔截器

axios.interceptors.request.use(function (config) {

// 在傳送請求之前做些什麼

Indicator.open()

return config

}, function (error) {

// 對請求錯誤做些什麼

Indicator.close()

return Promise.reject(error)

})

// 新增響應攔截器

axios.interceptors.response.use(function (response) {

// 對響應資料做點什麼

Indicator.close()

return response

}, function (error) {

// 對響應錯誤做點什麼

Indicator.close()

return Promise.reject(error)

})

const api = {

requestGet (url) {

return new Promise((resolve, reject) => {

axios.get(baseUrl + url)

.then(data => resolve(data.data))

.catch(err => reject(err))

})

},

requestPost (url, params) {

return new Promise((resolve, reject) => {

axios.post(baseUrl + url, params)

.then(data => resolve(data.data))

.catch(err => reject(err))

})

}

}

export default api

main.js處引入mock,專案上線以及由介面時則刪掉即可

import Vue from 'vue'

import App from './App'

import router from './router'

import MintUI from 'mint-ui'

import '@/api/mock'

8.2 假設後端已經有了介面,但是可能會存在跨域問題,如果有跨域問題,開發時需要使用到反向代理

刪掉main.js出的mock

config/index.js處配置反向代理

proxyTable: {

'/daxun': {

target: '

changeOrigin: true,

pathRewrite: {

'^/daxun': ''

}

},

},

修改api/index.js的 baseUrl地址

const baseUrl = process.env.NODE_ENV === 'development' ? '/daxun' : '

重啟伺服器,檢視效果,預期一致

9、資料處理

本元件內部處理 data

狀態管理器處理

data處理方式

home/index.vue

<template>

<div>

<header>首頁頭部</header>

<div>

<Banner />

<Prolist :prolist = "prolist"/>

</div>

</div>

</template>

<script>

import Banner from '@/components/Banner'

import Prolist from '@/components/Prolist'

import api from '@/api'

export default {

data () {

return {

bannerdata: [],

prolist: []

}

},

components: {

Banner,

Prolist

},

mounted () {

api.requestGet('/douban').then(data => {

console.log(data)

this.prolist = data

})

}

}

</script>

<style>

.banner {

height: 150px;

}

</style>

prolist.vue

<template>

<ul>

<li v-for="(item, index) of prolist" :key="index">

{{ item.title }}

</li>

</ul>

</template>

<script>

export default {

props: {

prolist: Array

}

}

</script>

mock.js修改了模擬地址,以後切換更加簡單

Mock.mock('/daxun/douban', 'get', doubandata)

以後切換mock和開發伺服器只需要新增和刪除main.js中的mock欄位即可

10、狀態管理器

cnpm i vuex -S

建立store/index.js,store/home.js,store/kind.js

index.js

import Vue from 'vue'

import VueX from 'vuex'

import home from './home'

import kind from './kind'

Vue.use(VueX)

const store = new VueX.Store({

modules: {

home,

kind

}

})

export default store

kind.js

export default {

state: {},

getters: {},

actions: {},

mutations: {}

}

home.js

import api from '@/api'

const store = {

state: {

bannerdata: [1, 2, 3],

prolist: []

},

getters: {

prolistLength (state) {

return state.prolist.length

}

},

actions: {

getprolist ({ commit }) { // 引數的解構賦值 context

api.requestGet('/douban')

.then(data => {

console.log(data)

commit('changeprolist', data) // context.commit('changeprolist', data)

}).catch(err => console.log(err))

}

},

mutations: {

changebannerdata (state, data) {

state.bannerdata = data

},

changeprolist (state, data) {

state.prolist = data

}

}

}

export default store

home/index.vue 透過mapState輔助函式可以直接獲取狀態管理器中的值,透過dispatch 觸發非同步的actions

<template>

<div>

<header>首頁頭部</header>

<div>

<Banner />

<Prolist :prolist = "prolist"/>

{{ bannerdata }}

</div>

</div>

</template>

<script>

import Banner from '@/components/Banner'

import Prolist from '@/components/Prolist'

import { mapState } from 'vuex'

export default {

computed: {

...mapState({

bannerdata: (state) => state.home.bannerdata,

prolist: (state) => state.home.prolist

})

},

components: {

Banner,

Prolist

},

mounted () {

this.$store.dispatch('getprolist') // dispatch 一個action(非同步操作)

}

}

</script>

<style>

.banner {

height: 150px;

}

</style>

使用mapActions的等價寫法

<template>

<div>

<header>首頁頭部</header>

<div>

<Banner />

<Prolist :prolist = "prolist"/>

{{ bannerdata }}

</div>

</div>

</template>

<script>

import Banner from '@/components/Banner'

import Prolist from '@/components/Prolist'

import { mapState, mapActions } from 'vuex'

export default {

computed: {

...mapState({

bannerdata: (state) => state.home.bannerdata,

prolist: (state) => state.home.prolist

})

},

components: {

Banner,

Prolist

},

methods: {

...mapActions(['getprolist']) // 生成一個同名的函式 function getprolsit () {this.$store.dispatch('getprolist')}

},

mounted () {

this.getprolist()

}

}

</script>

<style>

.banner {

height: 150px;

}

</style>

11、列表進入詳情

編寫詳情頁面 detail/index.vue,一定要記得修改App.vue中的樣式

<template>

<div>

<div>

<header>詳情頭部</header>

<div>內容</div>

</div>

<footer>詳情底部</footer>

</div>

</template>

<script>

export default {

}

</script>

修改routes.js

{

path: '/detail/:id',

name: 'detail',

components: {

default: () => import('@/views/detail')

}

}

宣告式跳轉

prolist.vue

<router-link tag="li" :to="{name: 'detail', params: {id: item.id}}" v-for="(item, index) of prolist" :key="index">

{{ item.title }}

</router-link>

程式設計時跳轉

<li v-for="(item, index) of prolist" :key="index" @click="goDetail(item)">

{{ item.title }}

</li>

methods: {

goDetail (item) {

// this.$router.push('/detail/' + item.id)

this.$router.push({

name: 'detail',

params: {id: item.id}

})

}

}

詳情頁面可以透過 this.$route.params.id 拿到傳遞過來的資料

12、頁面切換效果

App.vue使用transition包裹router-view

<template>

<div>

<transition name="slide">

<router-view></router-view>

</transition>

<router-view name="footer"></router-view>

</div>

</template>

<script>

export default {

name: 'App'

}

</script>

<style>

@import '~@/lib/reset.scss';

html, body, .container {

@include rect(100%, 100%); // width: 100%; height: 100%;

}

.container {

max-width: 640px;

margin: 0 auto;

box-shadow: 0 0 2px #ccc;

@include flexbox(); // display: flex

@include flex-direction(column); // flex-direction:column

.box {

@include flex();

@include rect(100%, auto);

@include flexbox();

@include flex-direction(column);

.header {

@include rect(100%, 0.44rem);

@include background-color(#f66);

}

.content {

@include flex(); // flex: 1;

@include rect(100%, auto);

@include overflow(auto);

}

}

.footer {

@include rect(100%, 0.5rem);

@include background-color(#efefef);

ul {

@include rect(100%, 100%);

@include flexbox();

li {

@include flex();

@include rect(auto, 100%);

@include flexbox();

@include justify-content(); // justify-content: center;

@include align-items(); // align-items: center;

@include text-color(#333);

&.router-link-exact-active,.router-link-active{

@include text-color(#f66);

}

}

}

}

}

.slide-enter {

transform: translateX(100%);

}

.slide-enter-active {

transition: all .3s;

}

.slide-enter-to {

transform: translateX(0%);

}

.slide-leave {

transform: translateX(0%);

}

.slide-leave-active {

transition: all 0s;

}

.slide-leave-to {

transform: translateX(-100%);

}

</style>

13、下拉重新整理以及上拉載入功能

以分類為例

<template>

<div>

<header>分類頭部</header>

<div>

<mt-loadmore :top-method="loadTop" :bottom-method="loadBottom" :bottom-all-loaded="allLoaded" ref="loadmore">

<ul>

<li v-for="(item, index) of kindlist" :key="item.id">{{ item.title }} --- {{ index }}</li>

</ul>

</mt-loadmore>

</div>

</div>

</template>

<script>

import Vue from 'vue'

import { Loadmore } from 'mint-ui'

import api from '@/api'

Vue.use(Loadmore)

export default {

data () {

return {

kindlist: [],

allLoaded: false, // 所有的資料是否已經載入完畢

pageCode: 1 // 頁碼

}

},

mounted () { // 請求一次資料

api.requestGet('/douban')

.then(data => {

this.kindlist = data

})

},

methods: {

loadTop () { // 下啦重新整理函式 --- 請求了第一頁的資料

api.requestGet('/douban')

.then(data => {

this.kindlist = data // 替換資料

this.pageCode = 1 // 重新整理完畢,頁碼歸1

this.allLoaded = false // 重新整理完畢,表示可以繼續載入下一頁

this.$refs.loadmore.onTopLoaded() // 更新列表

})

},

loadBottom () {

api.requestGet('/douban?count=20&start=' + this.pageCode * 20)

.then(data => {

if (data.length === 0) { // 沒有資料的條件

this.allLoaded = true// 若資料已全部獲取完畢

}

this.pageCode += 1 // 頁碼加一,下一次請求資料時用

this.kindlist = [...this.kindlist, ...data] //組合資料

this.$refs.loadmore.onBottomLoaded() // 更新列表

})

}

}

}

</script>

<style>

.kindlist {

li {

height: 40px;

border-bottom: 1px solid #ccc;

line-height: 40px;

}

}

</style>

如果想要結合vuex實現

kind/index.vue

<template>

<div>

<header>分類頭部</header>

<div>

<mt-loadmore :top-method="loadTop" :bottom-method="loadBottom" :bottom-all-loaded="allLoaded" ref="loadmore">

<ul>

<li v-for="(item, index) of kindlist" :key="item.id">{{ item.title }} --- {{ index }}</li>

</ul>

</mt-loadmore>

</div>

</div>

</template>

<script>

import Vue from 'vue'

import { Loadmore } from 'mint-ui'

import { mapState } from 'vuex'

Vue.use(Loadmore)

export default {

data () {

return {

allLoaded: false,

pageCode: 1

}

},

computed: {

...mapState({

kindlist: (state) => state.kind.kindlist

})

},

mounted () {

this.$store.dispatch('getkindlist')

},

methods: {

loadTop () {

this.$store.dispatch('loadTop').then(() => {

this.pageCode = 1

this.allLoaded = false

this.$refs.loadmore.onTopLoaded()

})

},

loadBottom () {

this.$store.dispatch('loadBottom', { pageCode: this.pageCode }).then(data => {

if (data.length === 0) {

this.allLoaded = true

} else {

this.pageCode += 1

}

this.$refs.loadmore.onBottomLoaded()

})

}

}

}

</script>

<style>

.kindlist {

li {

height: 40px;

border-bottom: 1px solid #ccc;

line-height: 40px;

}

}

</style>

store/kind.js

import api from '@/api'

export default {

state: {

kindlist: []

},

getters: {},

actions: {

getkindlist ({ commit }) {

api.requestGet('/douban')

.then(data => {

commit('changekindlist', data)

})

},

loadTop ({ commit }) {

return new Promise((resolve, reject) => {

api.requestGet('/douban')

.then(data => {

commit('changekindlist', data)

resolve()

})

})

},

loadBottom ({ commit, state }, params) {

console.log(params)

return new Promise((resolve, reject) => {

api.requestGet('/douban?count=20&start=' + params.pageCode * 20)

.then(data => {

console.log('bottom', data)

const arr = [...state.kindlist, ...data]

console.log('arr', arr)

commit('changekindlist', arr)

resolve(data)

})

})

}

},

mutations: {

changekindlist (state, data) {

state.kindlist = data

}

}

}

14、回到頂部

components/BackTop.vue

<template>

<span @click="backtop">返回頂部</span>

</template>

<script>

export default {

methods: {

backtop () {

console.log('1')

document.getElementById('content').scrollIntoView()

}

}

}

</script>

<style>

.backtop {

position:fixed;

right:10px;bottom:60px;

}

</style>

使用時可以給需要的地方新增一個

<div id="content"></div>

15、購物車業務邏輯

<template>

<div>

<header>購物車頭部</header>

<div>

<input type="checkbox" v-model="allChecked" @change="test">

<ul>

<li v-for="(item, index) of cartlist" :key="index">

<input type="checkbox" v-model="item.flag" @change="fn(item)"/>

{{ item.name }}

<button @click="item.num-=1">-</button> {{ item.num }} <button @click="item.num+=1">+</button>¥{{ item.price }} 小計: {{ item.num * item.price}}

</li>

</ul>

<h1>總數為:{{ totalNum }}</h1>

<h1>總價為:{{ totalprice }}</h1>

</div>

</div>

</template>

<script>

export default {

data () {

return {

allChecked: false,

cartlist: [

{

id: 1,

name: '蘋果',

price: 4.8,

num: 2,

flag: false

},

{

id: 2,

name: '香蕉',

price: 3,

num: 5,

flag: false

},

{

id: 3,

name: '榴蓮',

price: 29.8,

num: 1,

flag: false

}

]

}

},

methods: {

test () {

if (this.allChecked) {

this.cartlist.map(item => {

item.flag = true

})

} else {

this.cartlist.map(item => {

item.flag = false

})

}

},

fn (item) {

if (!item.flag) {

this.allChecked = false

} else {

let bool = true

this.cartlist.map(item => {

if (!item.flag) {

bool = false

}

})

this.allChecked = bool

}

}

},

computed: {

totalNum () {

let num = 0

this.cartlist.map(item => {

item.flag ? num += item.num : num += 0

})

return num

},

totalprice () {

let price = 0

this.cartlist.map(item => {

item.flag ? price += item.num * item.price : price += 0

})

return price.toFixed(2)

}

},

watch: {

allChecked (newVal) {

}

}

}

</script>

<style>

</style>

16、註冊功能 --- 計算屬性

<template>

<div>

<header>註冊</header>

<div>

<mt-field placeholder="請輸入使用者名稱" :state="usernameState" v-model="username"></mt-field>

<mt-field placeholder="請輸入密碼" type="password" v-model="password" :state="passwordState"></mt-field>

<mt-field placeholder="驗證碼" v-model="code" :state="codeState">

<mt-button @click="sendCode" :disabled="sendState">{{msg}}</mt-button>

</mt-field>

<mt-button :disabled="disabledtype" @click="register" :type="type" size="large">註冊</mt-button>

</div>

</div>

</template>

<script>

import Vue from 'vue'

import { Field, Button } from 'mint-ui'

import api from '@/api'

Vue.use(Field, Button)

export default {

data () {

return {

username: '17733203950',

password: '123456',

msg: '傳送驗證碼',

time: 10,

sendState: false,

code: '',

adminCode: ''

}

},

computed: {

usernameState () {

if (this.username === '') {

return ''

} else if (/^[1][3,4,5,6,7,8,9][0-9]{9}$/.test(this.username)) {

return 'success'

} else {

return 'error'

}

},

passwordState () {

if (this.password === '') {

return ''

} else if (this.password.length > 5) {

return 'success'

} else {

return 'error'

}

},

codeState () {

if (this.code === '') {

return ''

} else if (this.code === this.adminCode) {

return 'success'

} else {

return 'error'

}

},

disabledtype () {

if (this.usernameState === 'success' && this.passwordState === 'success' && this.codeState === 'success') {

return false

}

},

type () {

if (this.usernameState === 'success' && this.passwordState === 'success' && this.codeState === 'success') {

return 'primary'

} else {

return 'default'

}

}

},

methods: {

getCode () {

api.requestGet('/users/sendCode?tel=' + this.username)

.then(data => {

if (data === 0) {

console.log('驗證碼傳送失敗')

} else if (data === 1) {

console.log('手機號已經註冊過')

} else {

console.log(data)

this.adminCode = data.code

}

})

},

sendCode () {

console.log('傳送簡訊驗證碼')

this.sendState = true

this.getCode()

var timer = setInterval(() => {

this.msg = this.time + '後重新傳送'

this.time--

if (this.time === -1) {

this.msg = '傳送驗證碼'

this.sendState = false

this.time = 10

clearInterval(timer)

}

}, 1000)

},

register () {

api.requestPost('/users/register', {

username: this.username,

password: this.password

}).then(data => {

if (data === 0) {

console.log('註冊失敗')

} else if (data === 1) {

console.log('註冊成功')

} else {

console.log('使用者名稱已註冊')

}

})

}

}

}

</script>

<style>

</style>

登入

<template>

<div>

<header>登入</header>

<div>

<mt-field placeholder="請輸入使用者名稱" :state="usernameState" v-model="username"></mt-field>

<mt-field placeholder="請輸入密碼" type="password" v-model="password" :state="passwordState"></mt-field>

<mt-button :disabled="disabledtype" @click="login" :type="type" size="large">登入</mt-button>

</div>

</div>

</template>

<script>

import Vue from 'vue'

import { Field, Button } from 'mint-ui'

import api from '@/api'

Vue.use(Field, Button)

export default {

data () {

return {

username: '17733203950',

password: '123456'

}

},

computed: {

usernameState () {

if (this.username === '') {

return ''

} else if (/^[1][3,4,5,6,7,8,9][0-9]{9}$/.test(this.username)) {

return 'success'

} else {

return 'error'

}

},

passwordState () {

if (this.password === '') {

return ''

} else if (this.password.length > 5) {

return 'success'

} else {

return 'error'

}

},

disabledtype () {

if (this.usernameState === 'success' && this.passwordState === 'success') {

return false

}

},

type () {

if (this.usernameState === 'success' && this.passwordState === 'success') {

return 'primary'

} else {

return 'default'

}

}

},

methods: {

login () {

api.requestPost('/users/login', {

username: this.username,

password: this.password

}).then(data => {

if (data === 0) {

console.log('登入失敗')

} else if (data === 1) {

console.log('登入成功')

// 登入成功,還可以返回token資訊,把它儲存到本地

// 以後請求資料時,把token攜帶過去

localStorage.setItem('isLogin', 'ok')

} else if (data === 2) {

console.log('使用者未註冊')

} else {

console.log('密碼錯誤')

}

})

}

}

}

</script>

9a3e5cd08c144ccca6afa90707b25aca.gif

<style>

</style>


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69917019/viewspace-2644461/,如需轉載,請註明出處,否則將追究法律責任。

相關文章