此项目提供项目框架组件方案,适合初学者。

由于公司项目紧张,这是晚上下班写了一点点。

项目结构图


main.js

/**
 *  导入文件
 *  @Vue: vue
 *  @Vuex: vue的一种状态管理模式
 *  @FastClick: 点击时延迟
 *  @Element: element-ui
 *  @App: 入口vue
 *  @router: 路由文件
 */
import Vue from 'vue'
import Vuex from 'vuex'
import FastClick from 'fastclick'
import Element from 'element-ui'
import App from './App'
import router from './router/router'
import 'element-ui/lib/theme-default/index.css'
import $http from './kit/request'
import $message from './kit/message'
import $cookie from './kit/cookie'
/**
 * 加载插件
 */
Vue.use(Vuex)
Vue.use(Element)
/**
 *  设置常量信息
 */
let DOMAIN_NAME = ''
let SERVER_NAME = ''
let API_PREFIX = ''
/**
 *  设置全局公用常量
 */
Vue.prototype.DOMAIN_NAME = DOMAIN_NAME
Vue.prototype.SERVER_NAME = SERVER_NAME
Vue.prototype.API_PREFIX = API_PREFIX
/**
 *  设置store
 */
const store = new Vuex.Store({})
/**
 *  监听路由
 *  修改网站title的值
 */
router.afterEach((transition) => {
  if (transition.meta.title) {
    document.title = transition.meta.title
  }
})
/**
 *  通用工具类
 */
Vue.prototype.$post = function (opts) {
  opts.method = 'post'
  $http(opts)
}
Vue.prototype.$get = function (opts) {
  opts.method = 'get'
  $http(opts)
}
/**
 * 弹出层
 * @param opts
 * @param onCloses
 */
Vue.prototype.$message = function (opts, onCloses) {
  $message(opts, onCloses)
}
/**
 * 操作coookie
 * @param name
 * @param value
 * @param day
 */
Vue.prototype.$cookieSet = function (opts) {
  opts.method = 'set'
  $cookie(opts)
}
Vue.prototype.$cookieGet = function (opts) {
  opts.method = 'get'
  return $cookie(opts)
}
Vue.prototype.$cookieDel = function (opts) {
  opts.method = 'del'
  $cookie(opts)
}
/**
 *  日志输出开关
 */
Vue.config.productionTip = true
/**
 *  点击延迟
 */
FastClick.attach(document.body)
/**
 *  创建实例
 */
new Vue({
  store,
  router,
  render: h => h(App)
}).$mount('#app')
router.js

/**
 *  导入文件
 *  @Vue: vue
 *  @VueRouter: 路由
 */
import Vue from 'vue'
import VueRouter from 'vue-router'
/**
 *  加载模块
 */
Vue.use(VueRouter)
/**
 *  配置滚动条的位置
 *  通过这个这个属性(是个函数),可以让应用像浏览器的原生表现那样,在按下 后退/前进 按钮时,简单地让页面滚动到顶部或原来的位置。
 */
const scrollBehavior = (to, from, savedPosition) => {
  if (savedPosition) {
    return savedPosition
  } else {
    return { x: 0, y: 0 }
  }
}
/**
 *  路由配置
 *  @mode: 配置路由模式("hash" | "history" | "abstract" *  @base: 如果整个单页应用服务在 /app/ 下,然后 base 就应该设为 "/app/" *  @linkActiveClass: 点击触发的class
 *  @scrollBehavior: 配置滚动条的位置
 */
const router = new VueRouter({
  base: __dirname,
  likActiveClass: 'link-active',
  scrollBehavior,
  routes: [
    {
      path: '/init',
      name: 'init',
      component: resolve => require(['../components/init.vue'], resolve),
      children: [
        {
          path: '/init/home',
          name: 'home',
          component: resolve => require(['../components/home.vue'], resolve),
          meta: {title: '主页'}
        },
        {
          path: '/init/user/userList',
          name: 'userList',
          component: resolve => require(['../components/user/userList.vue'], resolve),
          meta: {title: '主页'}
        },
        {
          path: '/init/user/addUser',
          name: 'addUser',
          component: resolve => require(['../components/user/addUser.vue'], resolve),
          meta: {title: '主页'}
        }
      ]
    }, {
      path: '/login',
      name: 'login',
      component: resolve => require(['../components/login.vue'], resolve),
      meta: {title: '登录'}
    }
  ]
})

/**
 *  路由出口
 */
export default router
app.vue

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

<script>
  export default {}
</script>

<style>
*{margin: 0;padding:0;}
html, body{height:100%;overflow: hidden}
#app{
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
  height: 100%;
}
.breadcrumb{padding:20px;}
</style>
login.vue

<template>
  <div id="Login">
    <el-form ref="loginForm" :rules="loginRules" :model="loginForm" label-position="left" label-width="0" class="loginForm">
      <h3 class="title">VUE</h3>
      <el-form-item prop="userName">
        <el-input type="text" v-model="loginForm.userName" auto-complete="off" placeholder="账号" ></el-input>
      </el-form-item>

      <el-form-item prop="userPass">
        <el-input type="password" v-model="loginForm.userPass" auto-complete="off" placeholder="密码" ></el-input>
      </el-form-item>

      <el-form-item>
        <el-button class="login-max-button" type="primary" @click.native.prevent="login">登录</el-button>
      </el-form-item>

    </el-form>
  </div>
</template>

<script>
  export default {
    components: {},
    created () {},
    data () {
      return {
        loginForm: {
          userName: '000000',
          userPass: '000000'
        },
        loginRules: {
          userName: [
            {required: true, message: '请输入账号', trigger: 'blur'},
            {min: 6, message: '账号最少是6', trigger: 'blur'}
          ],
          userPass: [
            {required: true, message: '请输入密码', trigger: 'blur'},
            {min: 6, message: '密码最少是6', trigger: 'blur'}
          ]
        }
      }
    },

    methods: {
      login (event) {
        let vue = this
        vue.$refs.loginForm.validate((valid) => {
          if (valid) {
            if (vue.loginForm.userName === '000000' && vue.loginForm.userPass === '000000') {
              vue.$message({msg: '登录成功!'}, function () {
                vue.$router.push({name: 'home', params: {}})
                vue.$cookieSet({name: 'loginInfo', value: {userName: vue.loginForm.userName}, day: 1})
              })
            } else {
              vue.$message({msg: '用户名和密码错误!(60)', tp: 'error'}, function () {
                vue.loginForm.userName = ''
                vue.loginForm.userPass = ''
              })
            }
//            vue.$post({
//              url: '/admin',
//              data: {
//                userName: vue.loginForm.userName,
//                userPass: vue.loginForm.userPass
//              },
//              success: function (data) {
//                console.log(data)
//              }
//            })
          } else {
            return false
          }
        })
      }
    }
  }
</script>

<style>
#Login .loginForm{border:1px solid #EAEAEA;width:400px;margin:200px auto;border-radius: 5px;padding: 35px;box-shadow: 0 0 40px #CAC6C6}
#Login .loginForm .title{height: 30px;border-bottom:1px solid #EAEAEA;margin-bottom:20px;text-align: center}
#Login .loginForm .login-max-button{width: 100%}
</style>
init.vue

<template>
  <div id="Content">
    <NavHeader></NavHeader>
    <el-row :gutter="1" type="flex" justify="start" style="height:95%;">
      <!--NavMenu-->
      <el-col :span="3" style="background: #E6E6E6">
        <div class="grid-content bg-purple">
          <NavMenu></NavMenu>
        </div>
      </el-col>
      <!--Content-->
      <el-col :span="21">
        <div class="grid-content bg-purple">
          <!--Content Template-->
          <transition name="bounce">
            <router-view></router-view>
          </transition>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script>
  import NavHeader from './layout/NavHeader.vue'
  import NavMenu from './layout/NavMenu.vue'
  export default {
    components: {
      NavHeader,
      NavMenu
    }
  }
</script>
<style scoped>
#Content{height: 100%}
</style>
NavMenu.vue

<template>
  <div id="NavMenu">
    <el-menu theme="light" :unique-opened="uniqueOpened" default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" @select="handSelect">
      <el-submenu index="user">
        <template slot="title"><i class="el-icon-menu"></i>用户管理</template>
        <el-menu-item-group>
          <el-menu-item index="userList"><i class="el-icon-menu"></i> 用户列表</el-menu-item>
          <el-menu-item index="addUser"><i class="el-icon-plus"></i> 新建用户</el-menu-item>
        </el-menu-item-group>
      </el-submenu>
      <el-menu-item index="login"><i class="el-icon-setting"></i>退出登录</el-menu-item>
    </el-menu>
  </div>
</template>

<script>
  export default {
    data () {
      return {
        uniqueOpened: true
      }
    },
    methods: {
      handleOpen (key, keyPath) {
//        console.log(key, keyPath)
      },
      handleClose (key, keyPath) {
//        console.log(key, keyPath)
      },
      handSelect (key, keyPath) {
        let vue = this
        if (key) {
          vue.$router.push({name: key})
        } else {
          vue.$router.push({name: 404})
        }
      }
    }
  }
</script>

<style>
#NavMenu{background: #E6E6E6;height: 100%;}
#NavMenu .el-menu{background: #E6E6E6; text-align: l}
</style>
NavHeader.vue

<template>
  <div id="NavHeader">
    <el-row :gutter="1">
      <!--Logo/UserImg-->
      <el-col :span="4">
        <div class="grid-content logo">Element <b class="text">框架管理系统</b></div>
      </el-col>
      <!--Search-->
      <el-col :span="16"><div class="grid-content"></div></el-col>
      <!--QuitLogin and Msg-->
      <el-col :span="4">
        <div class="grid-content">
          <div class="userInfo">
            <div class="userImg"><img src="static/img/user.png" class="max-min-img"></div>
            <div class="userName">{{userName}}</div>
          </div>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script>
    export default {
      created () {
        let vue = this
        let userName = vue.$cookieGet({name: 'loginInfo'})
        if (userName) {
          vue.$data.userName = JSON.parse(userName).userName
        } else {
          vue.$message({msg: '请重新登录', tp: 'warning'}, function () {
            vue.$router.push({name: 'login'})
          })
        }
      },
      data () {
        return {
          userName: ''
        }
      }
    }
</script>

<style>
  #NavHeader{
    background: #20A0FF;
    height: 50px;
  }
  #NavHeader .logo{line-height: 50px;color: #FFF;font-size:30px;text-shadow:1px 1px 5px #666}
  #NavHeader .logo .text{font-size: 18px;}
  #NavHeader .grid-content{height: 50px;}
  #NavHeader .userInfo{height: 50px;margin-right:30px;}
  #NavHeader .userName{display: inline-block;height: 50px;line-height: 50px;padding: 0 10px;float: right;cursor: pointer;color: #FFF}
  #NavHeader .userImg{width:50px;height: 50px;display: inline-block;border-radius: 50%;float: right;}
  #NavHeader .userImg img{width:50px;height: 50px;border-radius: 50%}
  #NavHeader .max-min-img{max-width: 100%;max-height: 100%}
</style>
工具类request.js

import axios from 'axios'
import {Loading, Message} from 'element-ui'
/**
 * @param opts
 */
const $http = function (opts) {
  let loadingInstance = Loading.service()
  loadingInstance.close()
  axios({
    method: opts.method,
    url: opts.url,
    headers: opts.headers || {},
    params: opts.params || {},
    data: opts.data || {}
  }).then(function (response) {
    loadingInstance.close()
    opts.success(response)
  }).catch(function (error) {
    console.log(error)
    Message.warning({message: '系统异常'})
    loadingInstance.close()
  })
}
/**
 *  出口
 */
export default $http
以上为大部分代码

GIT完整地址:git@github.com:Apache-Ra/ra-vue-example.git

或留言邮箱



Logo

前往低代码交流专区

更多推荐