赞
踩
安装参考
idea插件使用一
idea插件使用二
项目热部署参考
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
1) 安装node.js(请自行安装)
安装参考一
安装参考二
2)切换到项目根目录
3)在项目根目录执行:
npm install -g cnpm --registry=https://registry.npm.taobao.org
//切换模块下载镜像地址
4)项目根目录执行cnpm install,下载该项目依赖模块
提示如果安装“360安全卫士”或“电脑管家”,一定要关闭,不然报错
5)添加mark-down编辑依赖
cnpm install mavon-editor --save
6)用于解析md文档依赖
cnpm install markdown-it --save
cnpm install github-markdown-css
7)启动服务:项目根目录执行npm run dev,会自动打开前端首页(后端项目要提前部署好)
build | 项目构建(webpack)相关代码 |
---|---|
config | 配置目录,包括端口号等。我们初学可以使用默认的:8089,当然线上为 |
node_modules | npm 加载的项目依赖模块 |
src | 要开发的目录,基本上要做的事情都在这个目录里。里面包含了几个目录及文件:assets: 放置一些图片,如logo等。components: 公共组件。 router:路由。 App.vue: 项目入口文件,我们也可以直接将组件写这里,而不使用 components 目录。 main.js: 项目的核心文件。 |
static | 静态资源目录,如图片、字体等。 |
index.html | 首页入口文件,可以添加一些 meta 信息 |
package.json | 项目配置文件 |
README.md | 项目的说明文档,markdown 格式 |
项目前端模块中引入了vuex,存放vuex的系列文件:
vuex需要遵守的规则:
1、应用层级的状态应该集中到单个 store 对象中。
2、提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
3、异步逻辑都应该封装到 action 里面。
1)首先 index.js 入口文件
2)store.js - 引入vuex,设置state状态数据,引入getter、mutation和action
3)state.js 相当于数据库
里面定义了数据结构,一些数据的初始状态
4)getters.js 顾名思义 取用,不做修改
5)mutation-types.js 存放Vuex常用的变量
引入mutation-types.js 操作里面定义的常用变量
6)action.js - 提交mutation以达到委婉地修改state状态,可异步操作
store.js文件
import VUE from 'vue' import VUEX from 'vuex' VUE.use(VUEX) const state = { isPractice: false, //练习模式标志 flag: false, //菜单栏左右滑动标志 userInfo: null, menu: [ // { // index: '1', // title: '考试管理', // icon: 'icon-kechengbiao', // content:[{item1:'考试查询',path:'selectExam'},{item2:'添加考试',path:'/addExam'}], // }, // { // index: '2', // title: '题库管理', // icon: 'icon-tiku', // content:[{item2:'所有题库',path:'/selectAnswer'},{item3:'增加题库',path:'/addAnswer'},{path: '/addAnswerChildren'}], // }, { index: '1', title: '成绩查询', icon: 'icon-performance', content:[{item1:'学生成绩查询',path:'/allStudentsGrade'},{path: '/grade'},{item2: '成绩分段查询',path: '/selectExamToPart'},{path: '/scorePart'},{item2: '成绩分科排序',path: '/selectExamToPart2'},{path: '/scorePart2'}], }, { index: '2', title: '批改试卷', icon: 'el-icon-edit', content:[{item1:'未批改的应用题',path:'/studentApplication'},{item2: '已批改的应用题',path: '/studentApplication2'}], }, { index: '3', title: '答疑解惑', icon: 'el-icon-chat-dot-round', content:[{item1:'发布问题',path:'/publishProblem'},{item2:'学生问题',path:'/solveProblem'}], }, // { // index: '6', // title: '教师管理', // icon: 'icon-Userselect', // content:[{item1:'教师管理',path:'/teacherManage'},{item2: '添加教师',path: '/addTeacher'}], // }, // { // index: '7', // title: '模块管理', // icon: 'icon-module4mokuai', // content:[{item1:'模块操作',path:'/module'}], // } ], } const mutations = { practice(state,status) { state.isPractice = status }, toggle(state) { state.flag = !state.flag }, changeUserInfo(state,info) { state.userInfo = info } } const getters = { } const actions = { getUserInfo(context,info) { context.commit('changeUserInfo',info) }, getPractice(context,status) { context.commit('practice',status) } } export default new VUEX.Store({ state, mutations, getters, actions, // store })
项目中index.html和其他html差不多,但一般只定义一个空的根节点,在main.js里面定义的实例将挂载在根节点下,内容都通过vue组件来填充。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>锋芒频波测评系统</title>
<link rel="stylesheet" href="//at.alicdn.com/t/font_987928_pqv3jkd52jl.css">
<link rel="icon" type="image/x-icon" href="../static/img/图标1.png"/>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
main.js里面定义的实例
new Vue({
el: '#app',
router,
render: h => h(App),
components: { App },
template: '<App/>'
})
一个vue页面通常由三部分组成:模板(template)、js(script)、样式(style)
<router-view/>
为<router-view/> <router-view/>
的简写,是子路由视图,后面的路由页面都显示在此处。<style></style>
包裹,默认是影响全局的,如需定义作用域只在该组件下起作用,需在标签上加scoped,<style scoped></style>
<template> <div id="app"> <router-view/> </div> </template> <script> export default { name: 'App' } </script> <style> ul { list-style: none; } a { text-decoration: none; } * { margin: 0; padding: 0; } #app { font-family: "Microsoft YaHei", "Helvetica", "Tahoma", "Geneva", "Arial", sans-serif; background-color: #eee; } </style>
main.js主要是引入vue框架,根组件及路由设置,并且定义vue实例。
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router from './router' import echarts from 'echarts' import axios from 'axios' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import VueCookies from 'vue-cookies' import mavonEditor from 'mavon-editor' import 'mavon-editor/dist/css/index.css' Vue.use(ElementUI) Vue.use(VueCookies) Vue.use(mavonEditor) Vue.config.productionTip = false Vue.prototype.bus = new Vue() Vue.prototype.$echarts = echarts Vue.prototype.$axios = axios new Vue({ el: '#app', router, render: h => h(App), components: { App }, template: '<App/>' })
代码中的router相当于router:router,为ES6写法,在对象中,如果键值对一样的话,可以简写为一个;
components: { App }引入根组件App.vue,App即App:App;
template:'<App/>'
是简写形式,等价于 <App></App>
。
router下的index.js文件中的routes定义了路径为’/'的路由,该路由对应的页面是HelloWorld组件。
import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'login', //登录界面 component: () => import('@/components/common/login') }, { path: '/changeUser', name: 'changeUser', component: () => import ('@/components/common/userManager') }, { path: '/index', //教师主页 component: () => import('@/components/admin/index'), children: [ { path: '/', //首页默认路由 component: () => import('@/components/common/hello') }, { path:'/grade', //学生成绩 component: () => import('@/components/charts/grade') }, { path: '/selectExamToPart', //学生分数段 component: () => import('@/components/teacher/selectExamToPart') }, { path: '/selectExamToPart2', //学生分科成绩 component: () => import('@/components/teacher/selectExamToPart2') }, { path: '/scorePart', component: () => import('@/components/charts/scorePart') }, { path: '/scorePart2', //单科成绩排序 component: () => import('@/components/charts/scorePart2') }, { path: '/searchStudentApplication', //单科成绩排序 component: () => import('@/components/teacher/searchStudentApplication') }, { path: '/allStudentsGrade', //所有学生成绩统计 component: () => import('@/components/teacher/allStudentsGrade') }, { path: '/examDescription', //考试管理功能描述 component: () => import('@/components/teacher/examDescription') }, { path: '/selectExam', //查询所有考试 component: () => import('@/components/teacher/selectExam') }, { path: '/addExam', //添加考试 component: () => import('@/components/teacher/addExam') }, { path: '/answerDescription', //题库管理功能介绍 component: ()=> import('@/components/teacher/answerDescription') }, { path: '/selectAnswer', //查询所有题库 component: () => import('@/components/teacher/selectAnswer') }, { path: '/addAnswer', //增加题库主界面 component: () => import('@/components/teacher/addAnswer') }, { path: '/addAnswerChildren', //点击试卷跳转到添加题库页面 component: () => import('@/components/teacher/addAnswerChildren') }, { path: '/studentManage', //学生管理界面 component: () => import('@/components/teacher/studentManage') }, { path: '/studentApplication', //展示要批改的应用题 component: () => import('@/components/teacher/studentApplicationNoCorrect') }, { path: '/studentApplication2', //展示批改过的应用题 component: () => import('@/components/teacher/studentApplicationCorrect') }, { path: '/solveProblem', //展示问题 component: () => import('@/components/teacher/solveProblem') }, { path: '/publishProblem', //展示问题 component: () => import('@/components/teacher/publishProblem') }, { path: '/addStudent', //添加学生 component: () => import('@/components/teacher/addStudent') }, { path: '/teacherManage', component: () => import('@/components/admin/tacherManage') }, { path: '/addTeacher', component: () => import ('@/components/admin/addTeacher') }, ] }, { path: '/student', component: () => import('@/components/student/index'), children: [ {path:"/",component: ()=> import('@/components/student/myExam')}, {path: '/manager', component: () => import('@/components/student/manager')}, {path: '/update_stuinfo', component: () => import('@/components/student/update_stuinfo')}, {path: '/examMsg', component: () => import('@/components/student/examMsg')}, {path: '/message', component: () => import('@/components/student/message')}, {path: '/studentScore', component: () => import("@/components/student/answerScore")}, {path: '/scoreTable', component: () => import("@/components/student/scoreTable")} ] }, {path: '/answer',component: () => import('@/components/student/answer')}, {path: '/registerstudent', component: () => import('@/components/student/registerstudent')}, { path: '*', redirect: '/' } ] })
访问http://localhost:8088/显示的就是index.html页面,index.html原本只有一个根结点id=“app”。
main.js入口文件引入根组件App
前边我们已经提到,根组件App中,<router-view/>
是子路由视图,后面的路由页面都显示在此处,访问http://localhost:8088/,路由为‘/’,根据路由文件index.js,所以引入login组件。
login.vue
<!-- 用户登录界面 --> <template> <div id="login"> <div> <img src="../../assets/img/top_logo.jpg" height="60" width="60"/> </div> <div class="bg"></div> <el-row class="main-container"> <el-col :lg="8" :xs="16" :md="10" :span="10"> <div class="bottom"> <div class="container"> <p class="title">锋芒频波测评系统</p> <el-form :label-position="labelPosition" label-width="80px" :model="formLabelAlign"> <el-form-item label="账号:"> <el-input v-model.number="formLabelAlign.username" placeholder="请输入账号"></el-input> </el-form-item> <el-form-item label="密码:"> <!-- <i class="el-icon-unlock"></i>--> <el-input v-model="formLabelAlign.password" placeholder="请输入密码" type='password'></el-input> </el-form-item> <div> <input class="myInput" type="text" v-model="formLabelAlign.verifyCode" placeholder="请输入验证码"/> <!-- <el-input v-model="formLabelAlign.verifyCode" placeholder="请输入验证码" type='text' ></el-input>--> <img alt="单击图片刷新!" style="margin-bottom: -13px;" src="/api/kaptcha" onclick="this.src='/api/kaptcha?d='+new Date()*1"> </div> <div class="submit"> <el-button type="primary" class="row-login" @click="login()">登录</el-button> </div> <!-- <el-button class="row-register" type="button" @click="register()">Or, Sign Up?</el-button>--> </el-form> </div> </div> </el-col> </el-row> <el-row class="footer"> <el-col> <p class="msg2">©2020 锋芒工作室 All Rights Reserved</p> </el-col> </el-row> </div> </template> <script> import store from '@/vuex/store' import {mapState} from 'vuex' export default { store, name: "login", data() { return { role: 2, labelPosition: 'left', verfyCode_houtuan:'', formLabelAlign: { username: '', password: '', verifyCode:'' } } }, created(){ // this.$axios(`/api/getVerify`).then(res => { // console.log(res.data)}) }, methods: { getverfiyCode() { //分页查询所有试卷信息 }, register() { this.$router.push({path: '/registerstudent'}) }, //用户登录请求后台处理 login() { console.log("登录操作执行-------"); // console.log(this.formLabelAlign.verifyCode); this.$axios({ url: `/api/getVerify`, method: 'get', async:false }).then(res => { // if (res.data.code==200){ // // } if (res.data === this.formLabelAlign.verifyCode) { if (this.formLabelAlign.username === "" || this.formLabelAlign.password === ""){ this.$message({ showClose: true, type: 'error', message: '用户名或密码为空' }) }else{ this.$axios({ url: `/api/login`, method: 'post', data: { ...this.formLabelAlign } }).then(res=>{ let resData = res.data.data if(resData != null) { switch(resData.role) { case "0": //管理员 this.$cookies.set("cname", resData.adminName) this.$cookies.set("cid", resData.adminId) this.$cookies.set("role", 0) this.$router.push({path: '/index' }) //跳转到首页 break case "1": //教师 this.$cookies.set("cname", resData.teacherName) this.$cookies.set("cid", resData.teacherId) this.$cookies.set("role", 1) this.$router.push({path: '/index' }) //跳转到教师用户 break case "2": //学生 this.$cookies.set("cname", resData.studentName) this.$cookies.set("cid", resData.studentId) this.$cookies.set("role", 2) this.$router.push({path: '/student'}) break } } if(resData == null) { //错误提示 this.$message({ showClose: true, type: 'error', message: '用户名或者密码错误' }) } }) } }else{ this.$message({ showClose: true, type: 'error', message: '验证码错误' }) } }) }, clickTag(key) { this.role = key } }, computed: mapState(["userInfo"]), mounted() { } } </script> <style lang="scss" scoped> .myInput{ background-color: #FFF; background-image: none;border-radius: 4px;border: 1px solid #DCDFE6; -webkit-box-sizing: border-box;box-sizing: border-box; color: #606266; display: inline-block; font-size: inherit; height: 40px; line-height: 40px; outline: 0; padding: 0 15px; transition: border-color .2s cubic-bezier(.645,.045,.355,1); } .container { margin-bottom: 32px; } .container .el-radio-group { margin: 30px 0px; } #login { font-size: 14px; color: #000; background-color: #fff; } #login .bg { position: fixed; top: 70px; left: 0; width: 100%; overflow-y: auto; height: 75%; /*<!--background: url('../../assets/img/img2.jpg')center top / cover no-repeat;-->*/ background-color: #459ddd; } #login .main-container { display: flex; justify-content: center; align-items: center; margin-top: 75px; } #login .bottom { display:flex; justify-content: center; background-color:white; border-radius: 10px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); min-height: 430px; } #login .bottom .title { text-align: center; font-size: 30px; } .bottom .container .title { margin: 70px 0px;; } .bottom .submit .row-login { width: 100%; background-color: #459ddd; border-color: #459ddd; margin: 10px 0px 10px 0px; padding: 15px 20px; } .bottom .submit { display: flex; justify-content: center; } .footer { margin-top: 50px; text-align: center; } .footer .msg2 { font-size: 14px; color: gray; margin-top: 70px; } .bottom .options .register span:nth-child(1) { color: #8C8C8C; } //学生注册 .bottom .row-register { background-color: transparent; border: none; padding: 0; margin:0; font-size: 1.1em; box-sizing: border-box; border-bottom: 1px solid transparent; cursor: pointer; } .bottom .row-register{ border-bottom: 1px solid #ffffff; } </style>
由于在config文件夹下index.js文件下创建"api",代替target里面的地址(后台请求),后面组件中我们掉接口时直接用api代替
cnpm install jquery --save
1.下载到项目中
cnpm i github-markdown-css
2.将样式放到模块化vue目录下,然后在 style中导入
<style scoped lang="less">
@import './github-markdown.css';
</style>
3.在vue脚手架中的 .postcssrc.js文件中加入 exclude: ‘github-markdown’ //css样式文件
module.exports = { // 配置要使用的 PostCSS 插件 plugins: { // 配置使用 autoprefixer 插件 // 作用:生成浏览器 CSS 样式规则前缀 // VueCLI 内部已经配置了 autoprefixer 插件 // 所以又配置了一次,所以产生冲突了 // 'autoprefixer': { // autoprefixer 插件的配置 // // 配置要兼容到的环境信息 // browsers: ['Android >= 4.0', 'iOS >= 8'] // }, // 配置使用 postcss-pxtorem 插件 // 作用:把 px 转为 rem 'postcss-pxtorem': { rootValue ({ file }) { return file.indexOf('vant') !== -1 ? 37.5 : 75 }, // 配置要转换的 CSS 属性 // * 表示所有 propList: ['*'], exclude: 'github-markdown' //css样式文件 } }
4.在需要美化的正文部分加入github-markdown-css样式文件的 主样式类名
markdown-body 生效
<!-- 文章内容 -->
<div class="article-content markdown-body"
v-html='article.content'
ref="article-content"></div>
<van-divider>the end</van-divider>
</div>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。