前端小菜鸡使用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指定的属性对应的值
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: , //这个是当前前端项目启动后的访问端口 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
}
}
前端小菜鸡使用Vue+Element笔记(一)的更多相关文章
- 前端小菜鸡使用Vue+Element笔记(二)
记录一下在使用Vue和Element做项目时遇到过的难点... 1.在 <el-table>表格中嵌入 select下拉选择框,以及 tooltip提示框的使用 主要定义格式如红色标记代码 ...
- 小菜鸡学习---<正则表达式学习笔记2>
正则表达式学习笔记2 一.修饰符 前面我们学习的都是用于匹配的基本的关键的一些表达式符号,现在我们来学习修饰符.修饰符不写在正则表达式里,修饰符位于表达式之外,比如/runoob/g,这个最后的g就是 ...
- 循序渐进VUE+Element 前端应用开发(14)--- 根据ABP后端接口实现前端界面展示
在前面随笔<循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理>简单的介绍了一个结合ABP后端的登陆接口实现前端系统登陆的功能,本篇随笔继续深化这一主 ...
- 循序渐进VUE+Element 前端应用开发(16)--- 组织机构和角色管理模块的处理
在前面随笔<循序渐进VUE+Element 前端应用开发(15)--- 用户管理模块的处理>中介绍了用户管理模块的内容,包括用户列表的展示,各种查看.编辑.新增对话框的界面处理和后台数据处 ...
- 循序渐进VUE+Element 前端应用开发(17)--- 菜单资源管理
在权限管理系统中,菜单也属于权限控制的一个资源,应该直接应用于角色,和权限功能点一样,属于角色控制的一环.不同角色用户,登录系统后,出现的系统菜单是不同的.在VUE+Element 前端中,我们菜单结 ...
- 循序渐进VUE+Element 前端应用开发(18)--- 功能点管理及权限控制
在一个业务管理系统中,如果我们需要实现权限控制功能,我们需要定义好对应的权限功能点,然后在界面中对界面元素的功能点进行绑定,这样就可以在后台动态分配权限进行动态控制了,一般来说,权限功能点是针对角色进 ...
- 循序渐进VUE+Element 前端应用开发(19)--- 后端查询接口和Vue前端的整合
循序渐进VUE+Element 前端应用开发的系列文章中,前面介绍了系统各个功能的处理实现,本篇随笔从一个主线上介绍前后端开发的整合,让我们从ABP框架后端的查询接口的处理,前端API接口调用的封装, ...
- 循序渐进VUE+Element 前端应用开发(20)--- 使用组件封装简化界面代码
VUE+Element 前端应用,比较不错的一点就是界面组件化,我们可以根据重用的指导方针,把界面内容拆分为各个不同的组合,每一个模块可以是一个组件,也可以是多个组件的综合体,而且这一个过程非常方便. ...
- 循序渐进VUE+Element 前端应用开发(26)--- 各种界面组件的使用(2)
在我们使用Vue+Element开发前端的时候,往往涉及到很多界面组件的使用,其中很多直接采用Element官方的案例即可,有些则是在这个基础上封装更好利用.更少代码的组件:另外有些则是直接采用第三方 ...
随机推荐
- Asp.net core 学习笔记 ( identity server 4 JWT Part )
更新 : id4 使用这个 DbContext 哦 dotnet ef migrations add identity-server-init --context PersistedGrantDbCo ...
- Determine destination location of apt-get install <package>?
https://askubuntu.com/questions/129022/determine-destination-location-of-apt-get-install-package dpk ...
- Getting Started with Processing 第五章的easing问题
分析 使用 easing easing 的感官目的是为了 draw 的时候,画的图形不是即时 mouseX 的值,而是稍有落后一点.从算法分析,就是让所画图形的 x 坐标 落后于 mouseX 的值, ...
- 当实体类中entity/DTO/VO等类中,有枚举值,应该怎么输出?
当实体类中entity/DTO/VO等类中,有枚举值,应该怎么输出? 问题: orderStatus 和 payStatus都是枚举类,并且枚举的个数达地10来个,我们不可能在模板页面(jsp/ftl ...
- 4.1.7 Cutting Game(POJ 2311)
Problem description: 两个人在玩如下游戏. 准备一张分成 w*h 的格子的长方形纸张,两人轮流切割纸张.要沿着格子的边界切割,水平或者垂直地将纸张切成两部分.切割了n次之后就得到了 ...
- python记录day_20 多继承
多继承 继承: x是一种y的时候.可以使用继承关系.是"is a"的关系 在python中,支持多继承,一个类可以拥有多个父类.但是多继承中, 存在着这样一个问题,当两个父类中出现 ...
- laravel的重定向
Route::get("redirect1", function () { // redirct的三种写法 // return redirect()->route(" ...
- canal入门Demo
关于canal具体的原理,以及应用场景,可以参考开发文档:https://github.com/alibaba/canal 下面给出canal的入门Demo (一)部署canal服务器 可以参考官方文 ...
- bzoj4804: 欧拉心算 欧拉筛
题意:求\(\sum_{i=1}^n\sum_{j=1}^n\phi(gcd(i,j))\) 题解:\(\sum_{i==1}^n\sum_{j=1}^n\sum_{d=1}^n[gcd(i,j)== ...
- 谈一谈HashMap类2
1.由一个小案例引出本博文的讨论 public class Demo1 { public static void main(String[] args) throws Exception { Stud ...