vue中引入mintui、vux重構簡單的APP項目

  最近在學習vue時也瞭解到一些經常使用的UI組件,有用於PC的和用於移動端的。用於PC的有:Element(餓了麼)、iView等;用於移動端APP的有Vux、Mint UI(餓了麼)、Vant(有贊團隊)、cube-ui(滴滴)。css

  想作一個移動端微信公衆號使用的界面,因而選擇用mintUI。html

   mintUI官網:http://mint-ui.github.io/docs/#/en2/quickstartvue

1.項目中引入mint-ui

1.下載以及配置

(1)下載:webpack

E:\HBuilderSpace\vue-demo>cnpm install --save mint-ui

 

(2)引入:能夠按需引入,也能夠所有引入ios

所有引入的方式:git

main.js:github

import Vue from 'vue'; import App from './App.vue'; import router from './router'; import store from './store'; import MintUI from 'mint-ui' import 'mint-ui/lib/style.css' Vue.config.productionTip = false; Vue.use(MintUI) new Vue({ router, store, render: h => h(App), }).$mount('#app');

 

好比咱們在home.vue使用頭部固定的header:(只是簡單的實驗,須要的時候到官網查閱便可)web

<template>
  <div class="home">
 <mt-header title="multiple button"> <router-link to="/" slot="left"> <mt-button icon="back">back</mt-button> <mt-button @click="handleClose">close</mt-button> </router-link> <mt-button icon="more" slot="right"></mt-button> </mt-header>
    <ul class="footer">
      <router-link class="icons" to="/home/user">我的中心</router-link>
      <router-link class="icons" to="/home/contact">通信錄</router-link>
    </ul>
    <router-view/>
  </div>
</template>

<script> export default { name: 'home', }; </script>

<style scoped lang="scss"> li{ list-style: none;
} .footer{ position: fixed; width: 100%; height: 60px; line-height:60px; left: 0px; bottom: 0px; display: flex; flex-flow: row nowrap; justify-content: space-around;
} .icons{ font-size: 16px; flex: 1; text-align:center; border-top: 1px solid #42b983;
} a { color: #42b983; &.active{ color: #fff; background:#42b983;
   } } </style>

最終效果以下:ajax

 

 

按需引入的方式:(好比咱們按需引入所需的按鈕模塊)spring

(1)main.js引入模塊和css:

import Vue from 'vue'; import App from './App.vue'; import router from './router'; import store from './store'; import { Button } from 'mint-ui'; import 'mint-ui/lib/style.css' Vue.component(Button.name, Button); Vue.config.productionTip = false; new Vue({ router, store, render: h => h(App), }).$mount('#app');

 

 (2).vue文件直接使用:

<mt-button size="large" type="primary">large</mt-button>

結果:

 2. 重構以前的項目,改成mintUI

主要代碼以下:

App.vue:只定義了入口,在router/index.js中設置默認路由

<template>
  <div id="app">
    <router-view/>
  </div>
</template>

<style lang="scss"> *{ padding: 0px; text-align: center;
}
</style>

 

Main.js:按需引入所需的mint模塊,而且用Vue.component(name, options)發佈爲全局組件

import Vue from 'vue'; import App from './App.vue'; import router from './router'; import store from './store'; import 'mint-ui/lib/style.css' import { Button } from 'mint-ui'; import { Field } from 'mint-ui'; import { Header } from 'mint-ui'; import { Navbar, TabItem } from 'mint-ui'; Vue.component(Navbar.name, Navbar); Vue.component(TabItem.name, TabItem); Vue.component(Header.name, Header); Vue.component(Field.name, Field); Vue.component(Button.name, Button); Vue.config.productionTip = false; new Vue({ router, store, render: h => h(App), }).$mount('#app');

 

router/index.js:

import Vue from 'vue'; import VueRouter from 'vue-router'; import Login from '../views/Login.vue'; Vue.use(VueRouter); const routes = [ { path: '/', name: 'login', component: Login, }, { path: '/home', name: 'home', // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/Home.vue'), redirect: '/home/user', children: [{ path: 'user', name: 'user', component: () => import(/* webpackChunkName: "about" */ '../views/User.vue') }, { path: 'contact', name: 'contact', component: () => import(/* webpackChunkName: "about" */ '../views/Contact.vue') }] }, ]; const router = new VueRouter({ mode: 'hash', base: process.env.BASE_URL, linkActiveClass: 'active', routes, }); export default router;

定義了默認路由是Login,Login採用一次性加載,其餘採用懶加載。登陸成功以後的/home重定向到子路由/home/user。

 

store/index.js

import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({ state: { username: '' }, mutations: { setLoginUsername(state, username) { state.username = username }, }, actions: { setLoginUsernameFun(context, username) { context.commit("setLoginUsername", username); }, }, modules: { }, });

  vuex管理組件定義了一個屬性與修改屬性的方法

 

views/Login.vue

<template>
  <div class="login">
    <form v-if="!isReg">
      <h1>歡迎來到XXX系統</h1>
      <br/>
      <mt-field label="用戶名" placeholder="Input username" v-model="name"></mt-field>
      <mt-field label="密    碼" placeholder="Input password" type="password" v-model="password"></mt-field>
         <mt-button size="large" type="primary" @click.prevent="login()" key="login">登陸</mt-button>
              <br/>
         <mt-button size="large" type="default" @click.prevent="reg()" key="reg" plain>註冊</mt-button>
      <br/>
   
    </form>
    <div v-else>
      <h1>註冊</h1>
      <br/>
      <br/>
      <mt-field label="用戶名" placeholder="Input username" v-model="name"></mt-field>
      <mt-field label="密    碼" placeholder="Input password" type="password" v-model="password"></mt-field>
      <mt-field label="密    碼" placeholder="Input passwordRepeat" type="password" v-model="passwordRepeat"></mt-field>
         <mt-button size="large" type="primary" @click="addUser()" key="doReg">註冊</mt-button>
              <br/>
         <mt-button size="large" type="default" @click="cancel()" key="cancel" plain>取消</mt-button>
    </div>

  </div>
</template>

<script> import store from '@/store'; import { MessageBox } from 'mint-ui'; import { Toast } from 'mint-ui'; export default { name: 'login', store, data() { return { isReg: false, name: '', password: '', }; }, methods: { login() { this.isReg = false; var nameLocal = localStorage.getItem("name"); var passwordLocal = localStorage.getItem("password"); if (nameLocal == '' || passwordLocal == '') { MessageBox.alert("您還沒註冊!", "title"); return; } if (nameLocal === this.name && passwordLocal === this.password) { store.dispatch("setLoginUsernameFun", nameLocal); Toast("登陸成功"); this.$router.push('/home') return false; } MessageBox.alert("帳號密碼錯誤"); }, reg() { this.name = ''; this.password = ''; this.passwordRepeat = ''; this.isReg = true; }, addUser() { if (this.name == '' || this.password == '') { MessageBox.alert("必填用戶名密碼!!!"); return; } if (this.password !== this.passwordRepeat) { MessageBox.alert("兩次密碼不一致!!!"); return; } localStorage.setItem("name", this.name); localStorage.setItem("password", this.password); this.name = ''; this.password = ''; this.isReg = false; Toast("註冊成功"); }, cancel() { this.isReg = false; } }, }; </script>

  定義了兩個表單,登陸和註冊用的,用isReg屬性進行切換。註冊成功保存到本地localStorage。

  注意:(1)mint中button默認類型是submit,因此須要阻止事件的默認行爲。(2)mintUI的JS組件不能夠在main.js中全局引入。好比MessageBox、Toast。

 

views/Home.vue

<template>
    <div class="home">
        <mt-header title="XXX管理系統">
            <router-link to="/" slot="left">
                <mt-button icon="back">back</mt-button>
            </router-link>
            <mt-button icon="more" slot="right"></mt-button>
        </mt-header>

        <router-view/>
        <ul class="footer">
            <router-link class="icons" to="/home/user">我的中心</router-link>
            <router-link class="icons" to="/home/contact">通信錄</router-link>
        </ul>
    </div>
</template>

<script> export default { name: 'home', }; </script>

<style scoped lang="scss"> li { list-style: none; } .footer { position: fixed; width: 100%; height: 60px; line-height: 60px; left: 0px; bottom: 0px; display: flex; flex-flow: row nowrap; justify-content: space-around; } .icons { font-size: 16px; flex: 1; text-align: center; border-top: 1px solid #42b983; } a { color: #42b983; &.active { color: #fff; background: #42b983; } } </style>

  定義了兩個子路由,並用secc語法定義了樣式。例如樣式 a 裏面的&.active 會被解析爲 a.active,&表明當前選擇器。 scoped  表明默認的css做用域是當前頁面,若是不寫會影響全局css樣式,通常爲當前頁面。

 

views/Uer.vue

<template>
  <div class="user"> 我的中心。歡迎您: {{getLoginUsername()}} </div>
</template>

<script> import store from '@/store'; export default { name: 'User', store, methods: { getLoginUsername() { return store.state.username }, }, }; </script>

 

views/Contact.vue:

<template>
  <div class="user"> 通信錄 </div>
</template>

 

3.最終效果:

(1)登陸:

 (2)登陸以後主頁面:

 

 4.引入axios實現先後端分離的註冊、登陸效果

1.安裝axios

cnpm install --save axios

 2.目錄結構

 

 

3.重要代碼解釋

src/axios/index.js內容以下:

import axios from "axios"; import { MessageBox } from 'mint-ui'; // 引入常量模塊
import Constants from '@/Constants.vue'; // 修改axios請求的默認配置(配置會以一個優先順序進行合併。這個順序是:在 lib/defaults.js 找到的庫的默認值,而後是實例的 defaults 屬性,最後是請求的 config 參數。) //` baseURL` 將自動加在 `url` 前面,除非 `url` 是一個絕對 URL。
axios.defaults.baseURL = Constants.projectBaseAddress; // 添加請求攔截器
axios.interceptors.request.use(function(config) { // 模擬處理前增長token
    return config; }, function(error) { // 對請求錯誤作些什麼
    return Promise.reject(error); }); // 添加響應攔截器
axios.interceptors.response.use(function(response) { // 對響應數據作點什麼
    if(response.data.success) { // 若是是成功返回信息以後提取出來返回以供後面的調用鏈使用(後臺返回的JSON數據)
        return response.data; } else { MessageBox.alert(response.data.msg); return new Promise(function(resolve, reject) { // resolve('success1');
            // reject('error');
 }); } }, function(error) { // 對響應錯誤作點什麼
    return Promise.reject(error); }); export default axios;

  對axios進行改造以後從新發布對象。全部的請求前面增長一個baseURL,其值是Constants模塊的projectBaseAddress。增長攔截器同一對後臺返回false的結果進行彈窗,返回爲true的提取返回的數據。

 

src/Constants.vue:

<script> export default { name: 'Constants', projectBaseAddress: '/api' }; </script>

  做爲一個全局JS工具類發佈,使用的方式參考上面axios/index.js中使用。

 

vue.config.js中使用代理對全部/api/訪問進行代理,解決跨域問題。固然跨域也能夠後臺設置容許跨域。這個參考express跨域設置規則就能夠。

module.exports = { publicPath: './', lintOnSave: false, devServer: { proxy: { '/api': { target: 'http://localhost:8088', ws: true, changeOrigin: true, pathRewrite: { '^/api': '' } } } } }

 

Login.vue進行修改:登陸註冊採用同步的方式進行登陸註冊。async關鍵字+await。登陸成功將username、fullname傳回前臺存入localStorage。

<template>
    <div class="login">
        <form v-if="!isReg">
            <h1>歡迎來到XXX系統</h1>
            <br/>
            <mt-field label="用戶名" placeholder="Input username" v-model="username"></mt-field>
            <mt-field label="密    碼" placeholder="Input password" type="password" v-model="password"></mt-field>
            <mt-button size="large" type="primary" @click.prevent="login()" key="login">登陸</mt-button>
            <br/>
            <mt-button size="large" type="default" @click.prevent="reg()" key="reg" plain>註冊</mt-button>
            <br/>

        </form>
        <div v-else>
            <h1>註冊</h1>
            <mt-field label="用戶名" placeholder="Input username" v-model="username"></mt-field>
            <mt-field label="用戶姓名" placeholder="Input userfullname" v-model="userfullname"></mt-field>
            <mt-field label="密    碼" placeholder="Input password" type="password" v-model="password"></mt-field>
            <mt-field label="電    話" placeholder="Input phone" v-model="phone"></mt-field>
            <mt-radio title="性    別" v-model="sex" :options="sexOptions" align="right">
            </mt-radio>
            <mt-button size="large" type="primary" @click="addUser()" key="doReg">註冊</mt-button>
            <br/>
            <mt-button size="large" type="default" @click="cancel()" key="cancel" plain>取消</mt-button>
        </div>

    </div>
</template>

<script> import store from '@/store'; import { MessageBox } from 'mint-ui'; import { Toast } from 'mint-ui'; import axios from "@/axios"; var login = { name: 'login', store, data() { return { isReg: false, username: '', userfullname: '', password: '', phone: '', sex: '', sexOptions: [{ label: '男性', value: '男' }, { label: '女性', value: '女' } ] }; }, methods: { async login() { this.isReg = false; if(this.username == "" || this.password == "") { MessageBox.alert("帳號密碼必須輸入"); return; } 
                var response = await axios.post('/doLoginJSON.html', { username: this.username, password: this.password }); if(response.success) { Toast("登陸成功"); // 將用戶存入localStorage
                    localStorage.setItem("username", response.data.username); localStorage.setItem("userfullname", response.data.userfullname); // 跳轉路由
                    this.$router.replace("/home"); } }, reg() { this.username = ''; this.password = ''; this.isReg = true; }, async addUser() { if(this.username == '' || this.password == '' || this.userfullname == '' || this.phone == '' || this.sex == '') { MessageBox.alert("請檢查必填字段!!!"); return; } 
                var response = await axios.post('/user/addUserJSON.html', { username: this.username, userfullname: this.userfullname, password: this.password, phone: this.phone, sex: this.sex, }); if(response.success) { this.isReg = false; Toast("註冊成功"); } }, cancel() { this.isReg = false; } } } export default login; </script>

 

User.vue進行修改:(從localStorage獲取當前登陸的用戶信息)

<template>
    <div class="user"> 我的中心。歡迎您: {{getLoginUsername()}} </div>
</template>

<script> import store from '@/store'; export default { name: 'User', store, methods: { getLoginUsername() { var username = localStorage.getItem("username"); var userfullname = localStorage.getItem("userfullname"); return userfullname; }, }, }; </script>

5.引入Vux

vux官網:https://vux.li/

  查看了vux官網發現git上star的人數也很多,組件也知足本身的使用需求,因而選擇了vux。並且vux提供了樹形插件、圖表統計插件以及經常使用的md5等工具函數。

1.簡介

VUX(讀音 [v’ju:z],同 views)是基於WeUI和Vue(2.x)開發的移動端UI組件庫,主要服務於微信頁面。

基於webpack + vue-loader + vux能夠快速開發移動端頁面,配合vux-loader方便你在WeUI的基礎上定製須要的樣式。

vux-loader保證了組件按需使用,所以不用擔憂最終打包了整個vux的組件庫代碼。

VUX並不徹底依賴於WeUI,VUX 在 WeUI 的基礎上擴展了多個經常使用組件,可是儘可能保持總體UI樣式接近WeUI的設計規範。

 

幾個名詞解釋:

vue-loader:用於編譯 .vue 文件,官方模板已經幫你配置好。

vux-loader:VUX 組件庫的 webpack loader,實現按需加載等功能。它不是替代 vue-loader 而是配合 vue-loader 使用。若是你使用 vux2 模板,暫不須要手動使用它。

 

官網的建議

  VUX 必須配合 vux-loader 使用,若是不使用 vux2 模板請按照文檔正確配置。less@3.x 有嚴重的兼容問題,請暫時使用 less@^2.7.3。暫未適配 vue-cli@3.x。

 

 2.安裝

(1)安裝vux

npm install vux --save

(2)安裝less、less-loader (//安裝less,vux使用的是less)

npm install less less-loader --save-dev

(3)安裝vux-loader:vux是基於vux-loader的,因此必需要安裝這個,不然會報一大堆錯

npm install vux-loader --save-dev

(4)安裝vue-loader:我沒安裝的時候報錯,因此安裝了該模塊

npm install vue-loader@14.2.2 -D

 

(5)修改配置:vue.config.js:增長以下配置(vue-cli3.x版本的配置方式)

configureWebpack: config => { require('vux-loader').merge(config, { options: {}, plugins: ['vux-ui'] }) }

3.組件的使用:這裏使用x-button組件

(1)安裝組件,也能夠稱爲註冊組件:

局部註冊:在模塊中引入:

import { XButton } from 'vux' export default { components: { XButton } }

 

全局註冊:在main.js中(有點相似於mintui的按需註冊組件)

import { XButton } from 'vux' Vue.component('x-button', XButton)

(2)使用組件:

<x-button type="warn">vux按鈕</x-button>

  

至此簡單的引入了vux,接下來在使用的時候參考文檔使用所需組件便可。

補充:關於vux的不同的地方

(1)@click 綁定事件不生效。按照Vue文檔,在組件上綁定原生點擊事件請使用@click.native。

 

6.錯誤小記載

(1)npm run build的時候報錯:

Invalid options object. CSS Loader has been initialised using an options object that does not match the API schema.
- options has an unknown property 'minimize'

在css-loader1.0版本的時候移除了該屬性,我沒有找到替代辦法,因此我選擇了下降css-loader版本解決:

npm install css-loader@0.28.11

 

 

總結:

0.@表明的是src目錄

1.vue中引入全局JS變量和JS方法有兩種:

(1)將全局的東西提取到單獨的模塊中,好比:抽到Constants.vue中,內容以下

<script> export default { name: 'Constants', projectBaseAddress: '/api', method1() { return "method1"; } }; </script>

 

其餘模塊使用的方法:引入模塊,使用便可:

import Constants from '@/Constants.vue'; console.log(Constants.projectBaseAddress); console.log(Constants.method1());

 

(2)經過Vue.prototype掛載到Vue實例中。能夠掛載對象、函數、變量等,也能夠是從模塊中引入的對象。

var Constants = { name: 'Constants', projectBaseAddress: '/api', method1() { return "method1"; } }; Vue.prototype.Constants = Constants;

 

組件中調用便可:

console.log(this.Constants);

2.axios是基於Promise的ajax庫,能夠用async+await實現同步請求,其攔截器也能夠作一些統一處理。

3.axios跨域請求能夠在後臺設置容許跨域+攜帶cookie,以後設置axios攜帶cookie。也可使用代理,上面是使用了代理。

 

前臺git地址:https://github.com/qiao-zhi/vue-demo.git

 後臺git地址:https://github.com/qiao-zhi/springboot-ssm

相關文章
相關標籤/搜索