官网 https://www.antdv.com/docs/vue/introduce-cn/
-
简单使用
-
src/components/layout
-
<template> <div style=" 200px"> <a-menu :default-selected-keys="['1']" :default-open-keys="['sub1']" mode="inline" theme="dark" :inline-collapsed="collapsed" :selected-keys="[current]" @click="handleClick" > <a-sub-menu key="sub1"> <span slot="title"><a-icon type="mail" /><span>用户模块</span></span> <a-menu-item key="test"> 测试 </a-menu-item> <a-menu-item key="usermanage"> 用户管理 </a-menu-item> </a-sub-menu> </a-menu> </div> </template> <script> export default { data() { return { collapsed: false, current: '1', }; }, methods: { toggleCollapsed() { this.collapsed = !this.collapsed; }, handleClick(e) { this.current = e.key; this.$router.push({path:this.current}); }, }, }; </script>
-
src/views/user-manage/UserManage
-
<template> <div> <div id="components-layout-demo-basic"> <a-layout> <a-layout-header style="background: #F0F2F5"> <Crumbs></Crumbs> <h4 class="h3">用户管理</h4> </a-layout-header> <a-layout-content> <SearchComponent></SearchComponent> <ButtonComponent></ButtonComponent> </a-layout-content> <a-layout-footer> <TableComponent> </TableComponent> </a-layout-footer> </a-layout> </div> </div> </template> <script> import Crumbs from "./componentes/Crumbs"; import SearchComponent from "./componentes/SearchComponent"; import ButtonComponent from "./componentes/ButtonComponent"; import TableComponent from "./componentes/TableComponent"; import {getUser} from "../../http/apis"; export default { components: { Crumbs, SearchComponent, ButtonComponent, TableComponent, }, name: "UserManage", data() { return { visible: false, } }, methods: { }, //钩子方法 mounted() { }, created() { }, //监听属性 watch: {}, //计算属性 computed: {} } </script> <style scoped> .h3 { font-weight: 800; margin-left: -70px; margin-top: -20px; } </style>
-
组件嵌套使用 注意路径
-
按钮弹窗组件src/views/user-manage/componentes/ButtonComponentes.vue
-
<template> <div> <a-button type="primary" @click="showModal"> + 创建用户 </a-button> <a-modal v-model="visible" title="Basic Modal" @ok="handleOk"> 用户名 <a-input placeholder="" v-model="username"/> 密码 <a-input placeholder="" v-model="password"/> 手机号 <a-input placeholder="" v-model="mobile"/> 电子邮箱 <a-input placeholder="" v-model="email"/> </a-modal> </div> </template> <script> import {postRegister} from "../../../http/apis"; export default { name: "ButtonComponent", data() { return { visible: false, username: '', password: '', mobile: '', email: '', } }, methods: { showModal() { this.visible = true; }, handleOk() { let params = { username: this.username, password: this.password, mobile: this.mobile, email: this.email, } postRegister(params).then(res => { console.log(res) this.$router.go(0) }) this.visible = false; }, }, //钩子方法 mounted() { }, created() { }, //监听属性 watch: {}, //计算属性 computed: {} } </script> <style scoped> </style>
-
-
面包屑src/views/user-manage/componentes/Crumbs.vue
-
<template> <div> <a-breadcrumb separator="" class="a-breadcrumb"> <a-breadcrumb-item> Home </a-breadcrumb-item> <a-breadcrumb-separator>:</a-breadcrumb-separator> <a-breadcrumb-item href=""> 用户模块 </a-breadcrumb-item> <a-breadcrumb-separator/> <a-breadcrumb-item href=""> 用户管理 </a-breadcrumb-item> </a-breadcrumb> </div> </template> <script> export default { name: "Crumbs", data() { return {} }, methods: {}, //钩子方法 mounted() { }, created() { }, //监听属性 watch: {}, //计算属性 computed: {} } </script> <style scoped> .a-breadcrumb { /*background:red;*/ color: #1890ff; margin-top: -15px; margin-left: -70px; } </style>
-
-
输入框搜索src/views/user-manage/componentes/SearchComponentes.vue
-
<template> <div> <div> <a-input-search class="a-input-search" placeholder="请输入用户名" enter-button @search="onSearch"/> <br/><br/> {{user_list}} </div> </div> </template> <script> import {postSearch} from "../../../http/apis"; export default { name: "SearchComponent", data() { return { user_list:[], } }, methods: { onChange(date, dateString) { console.log(date, dateString); }, onSearch(value) { console.log(value); postSearch({search_name: value}).then(res => { console.log(res) this.user_list = res }) }, }, //钩子方法 mounted() { }, created() { }, //监听属性 watch: {}, //计算属性 computed: {} } </script> <style scoped> .a-input-search { 400px; margin-left: 40%; } .components-input-demo-size .ant-input { 200px; margin: 0 30px 30px 0; } </style>
-
-
表格展示src/views/user-manage/componentes/TableComponentes.vue
-
<template> <div> <a-table :columns="columns" :data-source="data" :rowKey="record => record.id"> <a slot="name" slot-scope="text">{{ text }}</a> <span slot="customTitle"><a-icon type="smile-o"/> 名字</span> <span slot="tags" slot-scope="tags"> </span> <span slot="action" slot-scope="text, record"> <a-button type="primary">修改</a-button> <a-button type="danger" @click="delUser(text.id)">删除</a-button> </span> </a-table> </div> </template> <script> import {delUser, getUser} from "../../../http/apis"; const columns = [ { dataIndex: 'username', // key: 'username', slots: {title: 'customTitle'}, scopedSlots: {customRender: 'name'}, }, { title: '手机号', dataIndex: 'mobile', // key: 'mobile', }, { title: '电子邮箱', dataIndex: 'email', // key: 'email', }, { title: '最后一次登录', // key: 'last_login', dataIndex: 'last_login', // scopedSlots: {customRender: 'tags'}, }, { title: '操作', // key: 'last_login', scopedSlots: {customRender: 'action'}, }, ]; // const data = [ // { // key: '1', // username: '战三', // mobile: 18548789043, // email: '515@qq.com', // is_superuser: '0', // last_login:'2020-12-09' // }, // ]; export default { name: "TableComponent", data() { return { data: [], columns, } }, methods: { showUser() { getUser().then(res => { console.log(res) this.data = res.results }) }, delUser(text) { console.log(text) delUser({id:text}).then(res => { console.log(res) this.$router.go(0) }).catch(err => { this.$router.go(0) }) }, }, //钩子方法 mounted() { }, created() { this.showUser() }, //监听属性 watch: {}, //计算属性 computed: {} } </script> <style scoped> </style>
-
-
路由src/router/index.js
-
import Vue from 'vue' import Router from 'vue-router' import Home from "../components/layout/Home"; Vue.use(Router) const page = name => () => import('@/views/' + name) export default new Router({ mode: 'history', routes: [ {path: '/login', component: page('Login'), name: '登录'}, { path: '/', name: 'Home', component: Home, children: [ {path: '/test', component: page('test/Test'), name: '测试页面'}, {path: '/usermanage', component: page('user-manage/UserManage'), name: '测试页面'}, ] }, ] }) #避免路由循环冗余 import VueRouter from 'vue-router' //import HelloWorld from '@/components/HelloWorld' const originalPush = VueRouter.prototype.push VueRouter.prototype.push = function push(location) { return originalPush.call(this, location).catch(err => err) }
-
-
登录src/views/Login.vue
-
<template> <div width=300> <center><h1>登录</h1></center> <a-form-item label="用户名" v-bind="formlayout"> <a-input v-model="username"/> </a-form-item> <a-form-item label="密码" v-bind="formlayout"> <a-input-password v-model="password" placeholder="input password" /> </a-form-item> <a-form-item v-bind="buttonlayout"> <a-button type="primary" @click="submit">登录</a-button> </a-form-item> </div> </template> <script type="text/javascript"> import { postLogin } from '../http/apis'; export default{ data(){ return{ username:"", password:'', //表单样式 formlayout:{ //标签 labelCol:{ xs:{span:24}, sm:{span:8} }, //文本框 wrapperCol:{ xs:{span:14}, sm:{span:6} } }, //按钮样式 buttonlayout:{ //按钮 wrapperCol:{ xs:{ span:24, offset:0 }, sm:{span:16,offset:8} } } } }, //自定义方法 methods:{ submit:function(){ var data={'username':this.username,'password':this.password} postLogin(data).then(resp => { console.log(resp) if(resp.token){ localStorage.setItem('token',resp.token) localStorage.setItem('username',resp.username) localStorage.setItem('uid',resp.id) this.$router.push('/') } }).catch(err=>{ console.log(err) alert('登录失败') }) } } }; </script> <style type="text/css"> </style>
-
-
axios请求接口src/http/apis.js
-
//将我们http.js中封装好的 get,post.put,delete 导过来 import {axios_get, axios_post, axios_delete, axios_put} from './index.js' // 书籍管理接口 // export const getBookList = (params, headers) => axios_get("/books/book/", params, headers) //用户 //获取用户信息 export const getUser = (params, headers) => axios_get("/user/user/", params, headers) //登录接口 export const postLogin = (params, headers) => axios_post("/user/login/", params, headers) //注册接口 export const postRegister = (params, headers) => axios_post("/user/register/", params, headers) //搜索 export const postSearch = (params, headers) => axios_post("/user/search/", params, headers) //删除 export const delUser = (params, headers) => axios_delete("/user/user/" + params.id + '/', headers)
-
封装axios index.js
-
import axios from 'axios' // 第一步:设置axios axios.defaults.baseURL = "http://192.168.56.100:8888/" //全局设置网络超时 axios.defaults.timeout = 10000; //设置请求头信息 axios.defaults.headers.post['Content-Type'] = 'application/json'; axios.defaults.headers.put['Content-Type'] = 'application/json'; // 第二:设置拦截器 /** * 请求拦截器(当前端发送请求给后端前进行拦截) * 例1:请求拦截器获取token设置到axios请求头中,所有请求接口都具有这个功能 * 例2:到用户访问某一个页面,但是用户没有登录,前端页面自动跳转 /login/ 页面 */ axios.interceptors.request.use( config => { // 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了 const token = localStorage.getItem("token") // console.log(token) if (token) { config.headers.Authorization = 'JWT ' + token } return config; }, error => { return Promise.error(error); }) axios.interceptors.response.use( // 请求成功 res => res.status === 200 ? Promise.resolve(res) : Promise.reject(res), // 请求失败 error => { if (error.response) { // 判断一下返回结果的status == 401? ==401跳转登录页面。 !=401passs // console.log(error.response) if (error.response.status === 401) { // 跳转不可以使用this.$router.push方法、 // this.$router.push({path:'/login'}) window.location.href = "http://127.0.0.1:8888/" } else { // errorHandle(response.status, response.data.message); return Promise.reject(error.response); } // 请求已发出,但是不在2xx的范围 } else { // 处理断网的情况 // eg:请求超时或断网时,更新state的network状态 // network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏 // 关于断网组件中的刷新重新获取数据,会在断网组件中说明 // store.commit('changeNetwork', false); return Promise.reject(error.response); } }); // 第三:封装axios请求 // 3.1 封装get请求 export function axios_get(url, params) { return new Promise( (resolve, reject) => { axios.get(url, {params:params}) .then(res => { // console.log("封装信息的的res", res) resolve(res.data) }).catch(err => { reject(err.data) }) } ) } // 3.2 封装post请求 export function axios_post(url, data) { return new Promise( (resolve, reject) => { // console.log(data) axios.post(url, JSON.stringify(data)) .then(res => { // console.log("封装信息的的res", res) resolve(res.data) }).catch(err => { reject(err.data) }) } ) } // 3.3 封装put请求 export function axios_put(url, data) { return new Promise( (resolve, reject) => { // console.log(data) axios.put(url, JSON.stringify(data)) .then(res => { // console.log("封装信息的的res", res) resolve(res.data) }).catch(err => { reject(err.data) }) } ) } // 3.4 封装delete请求 export function axios_delete(url, data) { return new Promise( (resolve, reject) => { // console.log(data) axios.delete(url, { params: data }) .then(res => { // console.log("封装信息的的res", res) resolve(res.data) }).catch(err => { reject(err.data) }) } ) }
-
-