前端小菜雞使用Vue+Element筆記(一)


關於使用Vue+Element的項目簡介~

最近因為項目組缺前端人員,所以自己現學現做頁面,先把前后台功能調通 覺得前端可真的是不容易呀哎呀~

首先記錄一下相關的Vue入門的教程:

vue環境搭建示例:https://blog.csdn.net/mao834099514/article/details/79138484

vue基本語法了解:https://www.runoob.com/vue2/vue-tutorial.html  

          https://cn.vuejs.org/v2/guide/syntax.html 

Element組件使用文檔:http://element-cn.eleme.io/#/zh-CN/component/installation   這個真的很棒,代碼可以直接復制下來用的 都不用自己重新寫哈哈哈

這個是別人寫的Element組件綜合使用的代碼,有興趣的可以從github上把源碼下載下來 在本地跑起來看一看 寫的很全很優秀  https://github.com/PanJiaChen/vue-element-admin

 

前端項目目錄結構:

 

其中用於開發的是:src 目錄 

src目錄結構:

assets: 存放圖片信息

components: 存放vue頁面信息 例如: hello.vue

config:  里面是一些關於localStorage的配置

router: 里面包含的是一些路由的配置

service: 定義與后台進行交互的方法

store: 定義一些類似與后台session作用域的變量 可以在整個會話中使用這里面定義的對象

 

 一、 service目錄下的 api.js 文件

統一封裝和后台進行交互的Ajax方法,在 *.vue頁面可以直接通過import導入 使用該方法與后台進行交互

import { Message } from 'element-ui'
import Vue from 'vue'
import $ from 'jquery'
/**
 * 封裝的全局ajax請求
 */
Vue.prototype.baseURL = '/XXX-XXX-service'
const Http = (url, data, type, contentType) => {
  // 默認為post
  type = (type == null || type == '' || typeof (type) === 'undefined') ? 'post' : type//eslint-disable-line
  // 創建一個promise對象
  var promise = new Promise((resolve, reject) => {
    if (!data) {
      data = {}
    }
    if (!contentType && typeof (contentType) === 'string') {
      data.token = sessionStorage.token
    } else {
      url = url + '?token=' + sessionStorage.token
    }

    $.ajax({
      type: type,
      data: data,
      url: Vue.prototype.baseURL + url,
      timeout: 60000,
      dataType: 'json',
      contentType: contentType,
      success: function (res) {
        resolve(res)
      },
      error: function (e) {
        reject(e)
        Message.error({
          'message': '系統錯誤,請稍後再試',
          'duration': '2000',
          'showClose': false
        })
      },
      complete: function (XMLHttpRequest, status) {
        if (status == 'timeout') {//eslint-disable-line
          Message.warning({
            'message': '網路超時,請刷新',
            'duration': '2000',
            'showClose': false
          })
        }
      }
    })
  })
  return promise
}
//當指定類型為‘application/json’類型時,傳給后台的入參必須為對象 且需要通過 JSON.stringfy(userObj)方法處理后才能被正確讀取。 使用示例:hello(userObj)
export const hello = (params) => {
  return Http('/hello', params, 'post', 'application/json')
}

//這里未指定參數數據類型 則需要一個一個的指明參數 name = 'zs'; age= '18' 不能以對象的形式傳到后台。使用示例: userLogin(name,age)
export const userLogin = (params) => {
  return Http('/auth/user/login', params, 'post')
}

 

二、存儲會話級別變量的定義:store目錄下的index.js,mutation.js

index.js文件 :指定state下有那些屬性,之后在任意頁面都可以直接使用這里定義的屬性 以及對應的屬性值。

import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations'
import actions from './actions'
import getters from './getters'

Vue.use(Vuex)
const state = {
  fixnavli: 'other',  //這是給單個數據賦值的示例,之后再當前項目的任意一個頁面都能獲取到這個變量的值
  loadding: false, // 加載動畫
  userInfo: sessionStorage.getItem('userInfo') ? JSON.parse(sessionStorage.getItem('userInfo')) : '', //這是從session中取對象值來給state值 userInfo賦值
  userHasLogin: sessionStorage.getItem('userInfo')
}
export default new Vuex.Store({
  state,
  actions,
  getters,
  mutations
})

 

mutation.js文件: 給index.js文件中的state指定的屬性定義賦值方法,在頁面中可以動態改變state指定的屬性對應的值

export const ADD_NUM = 'ADD_NUM'
export const FIX_NAVLI = 'FIX_NAVLI'
export const LOADDING = 'LOADDING'
export const USER_LOGIN = 'USER_LOGIN'
export const USER_LOGINOUT = 'USER_LOGINOUT'
export const USER_LOGIN_TEST = 'USER_LOGIN_TEST'
export const INPUT_FORM = 'INPUT_FORM'
import {setStore, getStore} from '../config/mUtils'//eslint-disable-line

export default {
  [ADD_NUM] (state) {
    state.num += 1
  },
  [FIX_NAVLI] (state, name) {
    state.fixnavli = name
  },
  [LOADDING] (state, flag) {
    state.loadding = flag
  },
  [USER_LOGIN_TEST] (state) {
    state.userHasLogin = true
  },
  [USER_LOGIN] (state, userInfo) {
    sessionStorage.setItem('userInfo', JSON.stringify(userInfo))
    state.userHasLogin = true
    state.userInfo = userInfo
  },
  [INPUT_FORM] (state, inputForm) {
    sessionStorage.setItem('inputForm', JSON.stringify(inputForm))
    state.inputForm = inputForm
  },
}

 

 

三、 router目錄下的 路由信息 ,相當於控制前端頁面的跳轉信息

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home.vue'
import store from '@/store/index' // 引入store文件

Vue.use(Router)

const router = new Router({
  mode: 'history', // 默認是hash模式
  scrollBehavior (to, from, savePosition) { // 在點擊瀏覽器的“前進/后退”,或者切換導航的時候觸發。
    // console.log(to) // to:要進入的目標路由對象,到哪里去
    // console.log(from) // from:離開的路由對象,哪里來
    // console.log(savePosition) // savePosition:會記錄滾動條的坐標,點擊前進/后退的時候記錄值{x:?,y:?}
    if (savePosition) {
      return savePosition
    } else {
      if (from.meta.keepAlive) {
        from.meta.savedPosition = document.body.scrollTop
      }
      return {
        x: 0,
        y: to.meta.savedPosition || 0
      }
    }
  },
  routes: [
    {
      path: '/login',
      name: 'login',
      props: {
        'title': '登錄'
      },
      component: () => import(/* webpackChunkName: "about" */ '@/components/Login.vue') //請求 /login的時候回跳轉到 Login.vue頁面
    },
    {
      path: '/mainIndex',
      name: 'mainIndex',
      props: {
        'title': '主頁面'
      },
      component: () => import(/* webpackChunkName: "about" */ '@/components/mainIndex.vue')  //表示請求 /mainIndex時會跳轉到mainIndex.vue頁面
    }
  ]
})

router.beforeEach(function (to, from, next) {
  clearTimeout(Vue.prototype.loaddTimeout)
  clearTimeout(Vue.prototype.loaddTimeout1)
  Vue.prototype.loaddTimeout1 = setTimeout(function () {
    store.commit('LOADDING', true)// 每次跳轉顯示加載動畫
  }, 10000)
  Vue.prototype.loaddTimeout = setTimeout(function () {
    next({path: '/404', query: { redirecter: to.path }})
  }, 60000)
  var login = store.state.userHasLogin
  if (to.path == '/login') {//eslint-disable-line
    store.commit('USER_LOGINOUT')
    next()
  } else {
    if (login) {
      next()
    } else {
      next({
        path: '/login'
      })
    }
  }
})
router.afterEach((to, from) => {
  clearTimeout(Vue.prototype.loaddTimeout)
  clearTimeout(Vue.prototype.loaddTimeout1)
  store.commit('LOADDING', false)
})

export default router

 

四、config目錄下的 mUtils.js 文件

/**
 * 存儲localStorage
 */
export const setStore = (name, content) => {
  if (!name) return
  if (typeof content !== 'string') {
    content = JSON.stringify(content)
  }
  window.localStorage.setItem(name, content)
}

/**
 * 獲取localStorage
 */
export const getStore = name => {
  if (!name) return
  return window.localStorage.getItem(name)
}

/**
 * 刪除localStorage
 */
export const removeStore = name => {
  if (!name) return
  window.localStorage.removeItem(name)
}

 

 五、components目錄下的*.vue頁面: 這里包含了開發的絕大部分內容呀!!! 在頁面里會調用service包下api.js定義的方法,也會使用store包下的index.js定義的state屬性

<template>
  <div class="sidebar">
    <el-container>
      <el-container>
        <el-aside width="200px">Aside</el-aside>
        <el-container>
          <el-header> <h1>個人資料</h1></el-header>
          <el-container>
            <el-aside width="1000px">
              <el-row>
                <div class="grid-content bg-purple">
                  <el-col :span="12">
                    <span>姓名:</span>
                    <el-input placeholder="姓名" v-model="name"  class="filter-item"/>
                  </el-col>
                </div>
              </el-row>
              <el-row>
                  <el-col :span="12" >
                    <div class="grid-content bg-purple">
                      <span>出生日期</span>
                      <el-date-picker v-model="birth"  placeholder="年 / 月  / 日" type="date"/>
                    </div>
                  </el-col>
              </el-row>
            </el-aside>
          <el-header>
          <el-row>
            <div class="grid-content bg-purple">
               <el-col :span="9"><el-button type="primary" icon="el-icon-search" @click="query">跳轉</el-button></el-col>
               <el-col :span="9"><el-button type="primary" icon="el-icon-search" @click="nextStep">下一步</el-button></el-col>
            </div>
          </el-row>
        </el-header>
        </el-container>
      </el-container>
    </el-container>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex'  //這里是指定需要引用state定義的屬性
import {hello} from '../service/api'   //這里是指定引用自定義的與后台進行交互的方法

export default {
  name: 'mainIndex',
  props: {
    title: String
  },
  data: function () {   
    return {  //這里定義需要用到的變量,在這里申明 也可以賦初始值 定義好后方法中可以使用 this.name給變量重新復制
      name: '',
      birth: '',
      aaaaa: this.fixnavli  //
    }
  },

  computed: {
    ...mapState([   //這里申明取出mapState中的值,方法中直接使用this.fixnavli, this.userInfo 便可以調用 (名字一一對應)
      'fixnavli',
      'userInfo',
    ])
  },
  methods: {
    ...mapMutations([  //這里是對state定義的屬性賦值的方法,用於隨時更新state中的屬性對應的屬性值,使用方法: this.INPUT_FORM(obj)
      'FIX_NAVLI',   
      'INPUT_FORM'
    ]),
/** 從這里開始 定義頁面中需要用到的方法,方法與方法直接的調用 使用 this.query() */
// 跳過按鈕 query: function () { var data = { code: this.fixnavli, msg: this.fixnavli } data = JSON.stringify(data) hello(data).then(res => { alert('返回:' + res.text) }) }, // 下一步 按鈕(轉到基本計划頁面) nextStep: function () { var inputForm = { //定義inputForm對象,可以是簡單的對應,也可以是嵌套的對象! 'currentstep': '1','onlProposalForm': { 'onlProposalForm1': { 'name': this.name, //會自動和 v-model指定的名字對應的值綁定 'birth': this.birth, }, 'onlProposalForm2': { 'areaCode': 'SRHK', 'sex': '0', } } } this.INPUT_FORM(inputForm) //調用更新state中定義的屬性對應的值的方法
    //這里進行頁面跳轉
this.$router.push({ path: '/login' //跳轉到登錄頁面 }) }, // 初始化頁面默認數據 selectInit () { let tmpInputForm = this.inputForm // 取出存入session中的對象,判斷是否有數據,如果有就從session中取出inputForm對象中存的數據填充頁面 if (tmpInputForm != null && tmpInputForm !== '') { this.age = tmpInputForm.onlProposalForm.onlProposalForm1.age this.birth = tmpInputForm.onlProposalForm.onlProposalForm1.birth } else { this.name = 'zs' //初始化的時候給頁面的框賦初始值 this.age = '18' } } , //******* 千萬要記得需要被調用的方法必須定義在 methods:{} 這個大框框里面,不然會識別不了的!!! }, mounted () { }, created: function () { this.selectInit() //在剛進入頁面的時候,會調用created方法,在里面調用自定義的 selectInit()方法進行頁面初始化 } } </script> <style> .el-row { margin-bottom: 20px; } .el-button--primary { color: black; background-color: rgba(121, 121, 152, 0.33); border-color: rgba(121, 121, 152, 0.33); } .el-input { width: auto; } .el-header, .el-footer { background-color: #B3C0D1; color: #333; } .el-aside { background-color: #D3DCE6; color: #333; } .el-main { background-color: #E9EEF3; color: #333; } </style>

 

六、關於代理配置信息(項目目錄下/config包下的 index.js)

 

'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.

const path = require('path')

module.exports = {
  dev: {

    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {
        '/iModule-proposal-service':{
        target: 'http://localhost:8708', //這個是后台項目的訪問端口號 8708

        changeOrigin: true,
        pathRewrite: {
          '^/ii-service': '/ii-service'  //這個是后台項目的訪問名字 ii-service
        }
      }
    },

    // Various Dev Server settings
    host: 'localhost', // can be overwritten by process.env.HOST
    port: 8088, //這個是當前前端項目啟動后的訪問端口  can be overwritten by process.env.PORT, if port is in use, a free one will be determined
    autoOpenBrowser: false,
    errorOverlay: true,
    notifyOnErrors: true,
    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-

    // Use Eslint Loader?
    // If true, your code will be linted during bundling and
    // linting errors and warnings will be shown in the console.
    useEslint: true,
    // If true, eslint errors and warnings will also be shown in the error overlay
    // in the browser.
    showEslintErrorsInOverlay: false,

    /**
     * Source Maps
     */

    // https://webpack.js.org/configuration/devtool/#development
    devtool: 'cheap-module-eval-source-map',

    // If you have problems debugging vue-files in devtools,
    // set this to false - it *may* help
    // https://vue-loader.vuejs.org/en/options.html#cachebusting
    cacheBusting: true,

    cssSourceMap: true
  },

  build: {
    // Template for index.html
    index: path.resolve(__dirname, '../dist/index.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',

    /**
     * Source Maps
     */

    productionSourceMap: true,
    // https://webpack.js.org/configuration/devtool/#production
    devtool: '#source-map',

    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],

    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM