从零开始使用vue2+element搭建后台管理系统(前期准备+登录)

准备开始

1. 安装node (node -v查询版本号) (下载地址:https://nodejs.org/en/download/)

2. 安装淘宝镜像 npm install -g cnpm --registry=https://registry.npm.taobao.org

3. 安装 webpack,以全局的方式安装 npm install webpack -g

4.全局安装vue以及脚手架vue-cli npm install @vue/cli -g --unsafe-perm

5.创建vue项目 vue create 项目名称

项目前置配置

 

  • 选择预设模板:Manually select features:手动配置
  • 选择需要使用的特性:Babel,Router,Vuex,CSS Pre-processors,Linter / Formatter(单元、E2E测试不选,ts根据项目情况选)
  • Router 选择路由模式:选用history(URL 中不带有 # 符号,但需要后台配置支持)
  • 选择 CSS Pre-processors:Sass(因为element使用Sass)
  • 选择 Linter / Formatter(Pick a linter / formatter config: (Use arrow keys):这里我试着选了ESLint + Prettier,通常选择ESLint + Standard config
  • 选择在什么时间进行检测(Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)):
    • Lint on save:保存时检测(√)
    • Lint and fix on commit:提交时检测
  • 选择在什么位置保存配置文件(Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? (Use arrow keys)):In dedicated config files
  • 选择是否保存本次配置以便于下次使用(Save this as a preset for future projects? (y/N)):N

配置好后,会自动生成一个项目,根据终端的提示,cd进入项目后,执行npm run serve,本地环境的运行命令可以自己配

 

 

导入element

官方文档:https://element.eleme.cn/#/zh-CN/component/installation

全局导入命令:npm i element-ui -S

在main.js中引入:

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import 'element-ui/lib/theme-chalk/index.css'
import ElementUI from 'element-ui'

Vue.use(ElementUI) 
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";
Vue.use(VueRouter);
import LoginView from "../views/LoginView.vue";
import HomeView from "../views/HomeView.vue";
import LayoutView from "@/components/LayoutView";

/** 解决相同路径跳转报错 */
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location).catch((err) => err);
};

export const constantRoutes = [
  // 重定向
  {
    path: "/",
    redirect: "/home", // 重定向到首页
    component: LayoutView,
    children: [
      {
        path: "home",
        name: "home",
        component: HomeView,
        meta: { title: "home", icon: "home" },
      },
    ],
  },
  //login
  {
    path: "/login",
    component: LoginView,
  },
  // 重定向
  {
    path: "/home",
    redirect: "/home",
    component: LayoutView,
    children: [
      {
        path: "home",
        name: "home",
        component: HomeView,
        meta: { title: "home", icon: "home" },
      },
    ],
  },
  {
    path: "/user",
    component: LayoutView,
    redirect: "/user/user",
    children: [
      {
        path: "user",
        name: "user",
        component: () => import("@/views/user/index"),
        meta: { title: "账号管理", icon: "s-custom" },
      },
    ],
  },
  {
    path: "/order",
    component: LayoutView,
    redirect: "/order/order",
    children: [
      {
        path: "order",
        name: "order",
        component: () => import("@/views/order/index"),
        meta: { title: "订单管理", icon: "s-marketing" },
      },
    ],
  },
  {
    path: "/auth",
    component: LayoutView,
    redirect: "/auth/auth",
    children: [
      {
        path: "auth",
        name: "auth",
        component: () => import("@/views/auth/index"),
        meta: { title: "权限管理", icon: "s-tools" },
      },
    ],
  },
  {
    path: "/404",
    component: () => import("@/views/404"),
    hidden: true,
  },
];

const createRouter = () =>
  new VueRouter({
    mode: "history",
    base: process.env.BASE_URL,
    scrollBehavior: () => ({
      y: 0, // scrollBehavior用于定义路由切换时,页面滚动
    }),
    routes: constantRoutes,
  });
const router = createRouter();

export default router;

 

引入axios

官网::http://www.axios-js.com/ (基于Promise的HTTP客户端,用于发送HTTP请求)

安装:npm install axios -S

创建一个名为utils的文件夹,在其中创建一个名为request.js的文件:

// 封装请求函数
import axios from "axios";
// 路由守卫
import router from "../router";
import { getToken, removeToken } from "./auth.js";
import { Message } from "element-ui";

// 创建axios实例
const service = axios.create({
  // 通用请求的地址前缀
  // baseURL: '/api',
  baseURL: process.env.BASE_API,
  timeout: 5000,
  // 请求带上 cookie
  withCredentials: true,
  // 定义消息头
  headers: {
    "Content-Type": "application/json; charset=utf-8",
  },
});

// 请求拦截器
service.interceptors.request.use(
  (config) => {
    //   // 在请求头中携带token
    //   config.headers.Authorization = localStorage.getItem("token");
    config.headers["Admin-Token"] = getToken();
    return config;
  },
  (error) => {
    console.log(error);
    Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  (response) => {
    const res = response.data;
    // 请求成功,返回数据
    if (res.code === 200) {
      return res;
    } else {
      // 根据状态码提示错误信息
      switch (res.code) {
        case 401:
          // 无权限,跳转到登录页面并清除token
          // localStorage.removeItem("token");
          removeToken();
          Message({
            message: res.message,
            type: "error",
            duration: 5000,
          });
          router.push("/login");
          break;
        case 403:
          alert("没有操作权限");
          break;
        case 404:
          alert("请求的资源不存在");
          // todo: 这里可以跳转到404页面
          break;
        case 500:
          alert("服务器内部错误");
          break;
        default:
          alert(res.message);
      }
      return Promise.reject(res.message || "Error");
    }
  },
  (error) => {
    console.log("err" + error);
    return Promise.reject(error);
  }
);

export default service;

 

引入js-cookie用来管理cookie

 npm install js-cookies -S

继续在utils文件夹下创建一个创建一个名为auth.js的文件,用来管理token:

const TokenKey = "Admin-Token";
import Cookie from "js-cookies";

// get
export function getToken() {
  return Cookie.getItem(TokenKey);
}

// set cookie有效期设置为客服交班时间14小时
export function setToken(value) {
  let seconds = 14 * 60 * 60;
  let expires = new Date(new Date() * 1 + seconds * 1000);
  console.log(TokenKey, value, expires);
  return Cookie.setItem(TokenKey, value, expires);
}

// remove
export function removeToken() {
  return Cookie.removeItem(TokenKey);
}

 

这里提供的方法就可以在需要的地方使用了~

 

最后src/main.js文件的内容为:

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import "element-ui/lib/theme-chalk/index.css";
import ElementUI from "element-ui";
import Cookie from "js-cookies";
import request from "./utils/request";
import api from "./api"; // 导入api接口
//导入permission.js,用户进行前端的权限控制
// import "./permission"

// 路由守卫
router.beforeEach((to, from, next) => {
  // 判断是否需要登录才能访问该路由
  // if (to.meta.requireAuth) {
  // 判断是否存在token
  const token = Cookie.getItem("Admin-Token");
  if (!token && to.path !== "/login") {
    next({
      path: "/login",
      query: { redirect: to.fullPath },
    });
  } else if (token && to.path === "/login") {
    next({ name: "home" });
  } else {
    next();
  }
});

Vue.use(ElementUI);
Vue.config.productionTip = false;
Vue.prototype.$http = request;
Vue.prototype.$api = api; // 将api挂载到vue的原型上

new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount("#app");

  

在views文件夹下创建LoginView.vue:

<template>
  <div class="sign-in">
    <el-row>
      <el-col :span="12" :offset="6">
        <img
          class="login-logo"
          src="../assets/logo.png"
          alt="烛月后台管理系统"
        />
        <el-form
          :model="loginForm"
          :rules="loginRules"
          ref="ruleForm"
          class="login-form"
          auto-complete="on"
          label-position="left"
        >
          <el-form-item prop="name">
            <el-input
              ref="username"
              v-model="loginForm.name"
              placeholder="Username"
              name="username"
              type="text"
              tabindex="1"
              auto-complete="on"
            />
          </el-form-item>
          <el-form-item prop="password">
            <el-input
              key="password"
              ref="password"
              v-model="loginForm.password"
              type="password"
              placeholder="Password"
              name="password"
              tabindex="2"
              auto-complete="on"
            />
          </el-form-item>
          <el-form-item>
            <el-button
              :loading="loading"
              type="primary"
              style="width: 100%; margin-bottom: 16px"
              @click="handleLogin('ruleForm')"
              >登录</el-button
            >
            <el-button
              style="width: 100%; margin-left: 0"
              @click="resetForm('ruleForm')"
              >重置</el-button
            >
          </el-form-item>
        </el-form>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import { login } from "../api/user";
import { setToken } from "@/utils/auth";
export default {
  data() {
    return {
      loading: false,
      loginForm: {
        name: "",
        password: "",
      },
      loginRules: {
        name: [{ required: true, message: "请输入用户名", trigger: "blur" }],
        password: [{ required: true, message: "请输入密码", trigger: "blur" }],
      },
    };
  },
  methods: {
    async handleLogin(formName) {
      this.$refs[formName].validate(async (valid) => {
        if (valid) {
          try {
            this.loading = true;
            const params = {
              data: {
                mobile: this.loginForm?.name,
                password: this.loginForm?.password,
              },
            };
            const res = await login(params);
            if (res.code !== 10000) this.$message.error(res.msg || "登录失败!");
            if (res.code === 10000 && res.data?.token) {
              this.$store.commit("user/SET_TOKEN", res.data.token);
              setToken(res.data.token);
              setTimeout(() => {
                this.$router.push({
                  name: "/home",
                });
              });
            }
          } finally {
            this.loading = false;
          }
        } else {
          this.$message.error("输入有误!");
        }
      });
    },

    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
  },
};
</script>

<style scoped lang="scss">
.sign-in {
  padding-top: 100px;
}
.login-logo {
  height: 100px;
}
.login-form {
  position: relative;
  width: 520px;
  max-width: 100%;
  padding: 30px 35px 0;
  margin: 0 auto;
  overflow: hidden;
}
</style>

  

登录成功后,进行token的存储,同时跳转到主页。

  

在api文件夹下新建user.js文件,写几个假的登录相关接口:

/**
 * 登录模块接口列表
 */

import request from "../utils/request"; // 导入http中创建的axios实例
// import qs from "qs"; // 根据需求是否导入qs模块

export function login(params) {
  console.log(params, "params");
  return {
    code: 10000,
    msg: "登录成功",
    data: {
      token: "abcdefghijklmnopqrstuvwxyz0123456789",
    },
  };
  //   return request.post("api/user/login", qs.stringify(params));
}

export function getInfo() {
  return {
    url: "api/user/info",
    type: "post",
    data: {
      msg: "success",
      code: 0,
    },
  };
}
export function logout() {
  return request({
    url: "api/user/logout",
    method: "post",
  });
}

  

  

运行效果:

 

 

 

posted @ 2023-09-09 17:44  芝麻小仙女  阅读(2677)  评论(0)    收藏  举报