用vue+node+koa+sequlize实现后台管理系统(1)

首先构建前端项目
1.按照vue官网步骤

# 1. 如果没有安装 Vue CLI 就先安装
npm install --global @vue/cli

# 2. 创建一个新工程,并选择 "Manually select features (手动选择特性)" 选项
vue create my-project-name
一路默认小跑下来即可。

2.安装一些需要用的依赖包

{
  "name": "ace",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "axios": "^0.19.0",
    "core-js": "^3.3.2",
    "element-ui": "^2.12.0",
    "vue": "^2.6.10",
    "vue-class-component": "^7.0.2",
    "vue-property-decorator": "^8.3.0",
    "vue-router": "^3.1.3"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^4.0.0",
    "@vue/cli-plugin-typescript": "^4.0.0",
    "@vue/cli-service": "^4.0.0",
    "less": "^3.10.3",
    "less-loader": "^5.0.0",
    "style-loader": "^1.0.0",
    "typescript": "~3.5.3",
    "vue-template-compiler": "^2.6.10"
  }
}

添加依赖包到package.json中保存,npm install 即可。

3.我用到了饿了么UI库element,需要在main.ts中引入,

import Element from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(Element);

4.改造vue初始化的项目

.
├── App.vue
├── assets
├── components
├── main.ts
├── model
│   └── user.ts
├── router
│   └── index.ts
├── service
│   ├── index.ts
│   └── userService.ts
├── shims-tsx.d.ts
├── shims-vue.d.ts
├── utils
│   └── validators
│       └── index.ts
└── views
    ├── About.vue
    ├── home
    │   ├── Home.less
    │   ├── Home.ts
    │   └── Home.vue
    ├── pager
    │   ├── Paper.ts
    │   └── Paper.vue
    └── user
        ├── User.less
        ├── User.ts
        ├── User.vue
        └── component
            ├── AddUser.ts
            └── AddUser.vue

新增以上文件,页面可以自己随便写点东西。
下面主要说几个必须的文件。
-- router/index.ts 前端项目路由配置文件。

import Vue from 'vue';
import VueRouter from 'vue-router';
const Home = () => import(/* webpackChunkName: "Home" */ '../views/home/Home.vue');
const User = () => import(/* webpackChunkName: "User" */ '../views/user/User.vue');
const Paper = () => import(/* webpackChunkName: "Paper" */ '../views/pager/Paper.vue');
const AddUser = () => import(/* webpackChunkName: "User" */ '../views/user/component/AddUser.vue');
const About = () => import(/* webpackChunkName: "about" */ '../views/About.vue');

Vue.use(VueRouter);

const routes = [
    {
        path: '/',
        name: 'home',
        component: Home,
    },
    {
        path: '/user',
        name: 'name',
        component: User,
    },
    {
        path: '/add',
        name: 'addUser',
        component: AddUser,
    },
    {
        path: '/about',
        name: 'about',
        component: About,
    },
    {
        path: '/paper',
        name: 'paper',
        component: Paper,
    },
];

const router = new VueRouter({
    mode: 'history',
    base: process.env.BASE_URL,
    routes,
});

export default router;

我在项目中用的是axios,service/index.ts文件就是对axios的一个基础配置,如果大家有其他的需求,这里都可以配置。
service/index.ts

import Axios from 'axios';

const instance = Axios.create({
    baseURL: 'http://localhost:3000',
    timeout: 10000,
    headers: {
        'cache-control': 'no-cache',
    },
});

export default instance;

这里是用户服务,放在这里统一定义,方便维护。
service/userService.ts

import { IUserList, IUserListModel, IUserModel } from '@/model/user';
import { IQuery } from '../model/user';
import instance from './index';

/**
 * 查询用户列表
 */
export const getUserList = async (query: IQuery) => {
    const { data } = await instance.get('/api/getUserList', {
        params: {
            ...query,
        },
    });
    return data;
};

/**
 * 添加用户
 * @param user
 */
export const addUser = async (user: IUserModel) => {
    const data = await instance.post('/api/addUser', {
        user,
    });
    return data;
};

/**
 * 删除用户
 * @param id
 */
export const delUser = async (id: number) => {
    const data = await instance.post('/api/delUser', {
        id,
    });
    return data;
};

/**
 * 根据id查询用户信息
 * @param id
 */
export const getUserInfoById = async (id: number) => {
    const { data } = await instance.get('/api/getUserInfoById', {
        params: {
            id,
        },
    });
    return data;
};

/**
 * 编辑用户
 * @param user
 */
export const editUser = async (user: IUserList) => {
    const { data } = await instance.post('/api/updateUser', {
        user,
    });
    return data;
};

这里是定一个用户相关的interface。
model/user.ts

export interface IUserListModel {
    list: IUserList[];
    totalRows: number;
}
export interface IUserList {
    name: string;
    password: string;
    mobile: string;
    email: string;
    createTime: string;
    updateTime: string;
}

export interface IUserModel {
    name: string;
    password: string;
    mobile: string;
    email: string;
}

export interface IQuery {
    email: string;
    name: string;
    mobile: string;
    pageNo: number;
    pageSize: number;
}

这个文件为element表单提供验证,放在一起方便调用,方便维护,可以根据不同的需求改变验证方式。很灵活。
validators/index.ts

export const validateEmail = (_rule: object, value: string, callback: (err?: Error) => void) => {
    if (!value) {
        callback();
    } else {
        if (!/^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/.test(value)) {
            callback(new Error('请输入正确邮箱格式'));
        } else {
            callback();
        }
    }
};

export const validateEmailRequired = (_rule: object, value: string, callback: (err?: Error) => void) => {
    if (!value) {
        callback(new Error('请填写邮箱'));
    } else {
        if (!/^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/.test(value)) {
            callback(new Error('请输入正确邮箱格式'));
        } else {
            callback();
        }
    }
};

export const validateMobile = (_rule: object, value: string, callback: (err?: Error) => void) => {
    if (!value) {
        callback();
    } else {
        if (!/^1[3456789]\d{9}$/.test(value)) {
            callback(new Error('请输入正确手机号'));
        } else {
            callback();
        }
    }
};

export const validateMobileRequired = (_rule: object, value: string, callback: (err?: Error) => void) => {
    if (!value) {
        callback(new Error('请填写手机号'));
    } else {
        if (!/^1[3456789]\d{9}$/.test(value)) {
            callback(new Error('请输入正确手机号'));
        } else {
            callback();
        }
    }
};

最后写一个主要的页面。
views/user/*
user.Vue



user.ts

import { IUserList } from '@/model/user';
import { Form } from 'element-ui';
import { Component, Vue } from 'vue-property-decorator';
import { IQuery } from '../../model/user';
import { delUser, getUserList } from '../../service/userService';
import { validateEmail, validateMobile } from '../../utils/validators/index';

@Component({})
export default class User extends Vue {
    public userList: IUserList[] = [];

    public query = {
        email: '',
        name: '',
        mobile: '',
        pageNo: 1,
        pageSize: 5,
    };

    public totalRows: number = 0;

    public queryRules: object = {
        email: [{ validator: validateEmail, trigger: 'change' }],
        mobile: [{ validator: validateMobile, trigger: 'change' }],
    };

    public async created() {
        await this.initUserList(this.query);
    }
    public async initUserList(query: IQuery) {
        const data = await getUserList(query);
        this.userList = data.list;
        this.totalRows = data.totalRows;
    }
    public addUser() {
        this.$router.push('/add');
    }
    public async delUser(id: number) {
        this.$confirm('是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
        })
            .then(async () => {
                await delUser(id);
                await this.initUserList(this.query);
                this.$message({
                    type: 'success',
                    message: '删除成功!',
                });
            })
            .catch(() => {
                this.$message({
                    type: 'info',
                    message: '已取消删除',
                });
            });
    }

    public editUser(id: number) {
        this.$router.push(`/add?id=${id}`);
    }

    public async search(val: string) {
        (this.$refs[val] as Form).validate((valid) => {
            if (valid) {
                this.initUserList(this.query);
            }
        });
    }

    public resetForm(val: string) {
        (this.$refs[val] as Form).resetFields();
    }

    public async handleSizeChange(val: number) {
        this.query.pageSize = val;
        await this.initUserList(this.query);
    }

    public async handleCurrentChange(val: number) {
        this.query.pageNo = val;
        await this.initUserList(this.query);
    }
}

user.less

.search-line {
    display: flex;
    flex-wrap: nowrap;
}
.search-line .el-form {
    display: flex;
    flex-wrap: nowrap;
}

.footer-pagi {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 999;
    padding-left: 30px;
    height: 50px;
    background: #fff;
    box-shadow: 0 0 10px rgba(0,0,0,.12);
}

.footer-pagi .el-pagination {
    margin-top: 10px;
}

vue所需的基本页面及配置文件基本添加完毕。如果有同学也用ts写的话,可以参考typescript官网修改tslint.json和tsconfig.json.
tslint配置项

至此,前端页面基本完毕。
下一篇我贴上后台代码。

你可能感兴趣的:(vue.js,element,axios,typescript)