zoukankan      html  css  js  c++  java
  • vue 组件嵌套(ant-design-vue)登录 之用户模块

    vue(ant-design-vue)组件嵌套方式

    1. axios跨域

      1. 新建http文件夹

      2. http/apis.js

        1. //将我们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)
          //修改
          export const upUser = (params, headers) => axios_put("/user/user/" + params.id + '/', params, headers)
          
      3. http/index.js

        1. 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 || res.status === 204 || res.status === 202 ? 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)
                  }).catch(err => {
                  reject(err)
                })
              }
            )
          }
          
    2. 在componentsindex.vue

      1. <template>
          <div>
            <a-layout
              id="components-layout-demo-top-side"
              :selected-keys="[current]"
            >
              <a-layout-header class="header">
                <div class="logo"/>
                <a-menu
                  theme="dark"
                  mode="horizontal"
                  :default-selected-keys="['1']"
                  :style="{ lineHeight: '64px' }"
                >
                  <a-menu-item key="1">
                    nav 1
                  </a-menu-item>
                  <a-menu-item key="2">
                    nav 2
                  </a-menu-item>
                  <a-menu-item key="3" style="margin-left: 80%">
                    <Header></Header>
                  </a-menu-item>
                </a-menu>
              </a-layout-header>
              <a-layout-content style="padding: 0 50px">
                <a-breadcrumb style="margin: 16px 0">
                  <a-breadcrumb-item>Home</a-breadcrumb-item>
                  <a-breadcrumb-item>List</a-breadcrumb-item>
                  <a-breadcrumb-item>App</a-breadcrumb-item>
                </a-breadcrumb>
                <a-layout style="padding: 24px 0; background: #fff">
                  <a-layout-sider width="200" style="background: #fff">
                    <a-menu
                      mode="inline"
                      :default-selected-keys="['1']"
                      :default-open-keys="['sub1']"
                      style="height: 100%"
                      @click="handleClick"
        
                    >
                      <a-sub-menu key="sub1">
                        <span slot="title"><a-icon type="user"/>用户模块</span>
                        <a-menu-item key="test">
                          测试
                        </a-menu-item>
                        <a-menu-item key="usermanage">
                          用户管理
                        </a-menu-item>
                      </a-sub-menu>
                      <a-sub-menu key="sub2">
                        <span slot="title"><a-icon type="laptop"/>工单模块</span>
                        <a-menu-item key="">
                          工单管理
                        </a-menu-item>
        
                      </a-sub-menu>
        <!--              <a-sub-menu key="sub3">-->
        <!--                <span slot="title"><a-icon type="notification"/>subnav 3</span>-->
        <!--                <a-menu-item key="">-->
        <!--                  option9-->
        <!--                </a-menu-item>-->
        <!--              </a-sub-menu>-->
                    </a-menu>
                  </a-layout-sider>
                  <a-layout-content :style="{ padding: '0 24px', minHeight: '280px' }">
                    <router-view></router-view>
                  </a-layout-content>
                </a-layout>
              </a-layout-content>
              <a-layout-footer style="text-align: center">
              </a-layout-footer>
            </a-layout>
          </div>
        
        </template>
        
        <script>
        import Header from "./layout/Header";
        
        
        export default {
          components:{
            Header,
        
          },
          name: "index",
          data() {
            return {
              current: '1',
        
            }
          },
          methods: {
            handleClick(e) {
              // console.log(e)
              this.current = e.key;
              this.$router.push({path: this.current});
            },
          },
        
        
          //钩子方法
          mounted() {
        
          },
          created() {
        
          },
          //监听属性
          watch: {},
          //计算属性
          computed: {}
        }
        </script>
        
        <style scoped>
        #components-layout-demo-top-side .logo {
           120px;
          height: 31px;
          background: rgba(255, 255, 255, 0.2);
          margin: 16px 28px 16px 0;
          float: left;
        }
        </style>
        
        
    3. 新建views文件夹

      1. views/user-manage/ 新建componentes/ButtonComponent.vue

        1. <template>
          
            <div>
              <a-button type="primary" @click="showModal" style="margin-left: 5px">
                + 创建用户
              </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,
                }
                this.$emit('addUser', params)
                // postRegister(params).then(res => {
                //   console.log(res)
                //   this.$router.go(0)
                // })
                this.visible = false;
              },
            },
          
          
            //钩子方法
            mounted() {
            },
            created() {
          
            },
            //监听属性
            watch: {},
            //计算属性
            computed: {}
          }
          </script>
          
          <style scoped>
          
          </style>
          
          
      2. views/user-manage/componentes/SearchComponent.vue

        1. <template>
          
            <div>
              <div>
                <a-input-search class="a-input-search" placeholder="请输入用户名" enter-button @search="onSearch"/>
                <br/><br/>
              </div>
          
          
            </div>
          
          </template>
          
          <script>
          import {postSearch} from "../../../http/apis";
          
          export default {
            name: "SearchComponent",
            data() {
              return {
              }
            },
            methods: {
              onChange(date, dateString) {
                console.log(date, dateString);
              },
              onSearch(value) {
                this.$emit('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: 35%;
          
          }
          
          .components-input-demo-size .ant-input {
             200px;
            margin: 0 30px 30px 0;
          }
          </style>
          
          
      3. views/user-manage/componentes/TableComponent.vue

        1. <template>
          
            <div>
              <a-table :columns="columns" :data-source="data" :rowKey="record => record.id" :pagination="pagination">
                <a slot="name" slot-scope="text">{{ text }}</a>
                <span slot="customTitle"><a-icon type="smile-o"/> 名字</span>
                <span slot="tags" slot-scope="tags">
                        <a-tag
                          v-for="tag in tags"
                          :key="tag"
                          :color="tag === 'loser' ? 'volcano' : tag.length > 5 ? 'geekblue' : 'green'"
                        >
                          {{ tag.toUpperCase() }}
                        </a-tag>
              </span>
                <span slot="action" slot-scope="text, record">
                      <a-button type="primary" @click="showModal(text)" style="margin-left: 5px">
                修改
              </a-button>
              <a-modal v-model="visible" title="Basic Modal" @ok="handleOk(text)">
                用户名
                <a-input placeholder="" v-model="username" v-if="pk == uid" />
                用户名
                <a-input placeholder="" v-model="username" disabled="disabled" v-if="pk != uid"  />
                手机号
                <a-input placeholder="" v-model="mobile"/>
                电子邮箱
                <a-input placeholder="" v-model="email"/>
              </a-modal>
                     <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: 'date_joined',
              // key: 'mobile',
            },
            {
              title: '电子邮箱',
              dataIndex: 'email',
              // key: 'email',
            },
            {
              title: '手机号',
              // key: 'last_login',
              dataIndex: 'mobile',
              // 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",
            props: ['data',],
            data() {
              return {
                // data: [],
                columns,
                visible: false,
                username: '',
                mobile: '',
                email: '',
                pk: '',
                pagination: {
                  total: 0,
                  pageSize: 2,//每页中显示10条数据
                  showSizeChanger: true,
                  pageSizeOptions: ["5", "10", "20", "30"],//每页中显示的数据
                  showTotal: total => `共有 ${total} 条数据`,  //分页中显示总的数据
                },
                uid: localStorage.getItem("uid")
              }
            },
            methods: {
              showModal(text) {
                this.visible = true;
                this.username = text.username
                this.mobile = text.mobile
                this.email = text.email
                this.pk = text.id
              },
              delUser(text) {
                this.$emit('delUser', text)
                //   console.log(text)
                //   delUser({id: text}).then(res => {
                //     console.log(res)
                //     this.$router.go(0)
                //   }).catch(err => {
                //     this.$router.go(0)
                //
                //   })
              },
              handleOk(text) {
                console.log(text.id)
                let params = {
                  username: this.username,
                  mobile: this.mobile,
                  email: this.email,
                  password: '1',
                  id: this.pk,
                }
                this.$emit('upUser', params)
                this.visible = false;
              },
            },
          
          
            //钩子方法
            mounted() {
            },
            created() {
              // this.showUser()
            },
            //监听属性
            watch: {},
            //计算属性
            computed: {}
          }
          </script>
          
          <style scoped>
          
          </style>
          
          
      4. views/user-manage/ componentes/Crumbs

        1. <template>
            <div>
              <a-breadcrumb separator="" class="a-breadcrumb">
                <a-breadcrumb-item>
                  nav  1
                </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: -30px;
          }
          </style>
          
          
      5. views/user-manage/ UserManage.vue

        1. <template>
            <div>
              <div id="components-layout-demo-basic">
                <a-layout>
                  <a-layout-header style="background: #F0F2F5">
                    <Crumbs></Crumbs>
                    <!--          页内标题-->
                  </a-layout-header>
          
          
                  <a-layout-content>
                    <!--          搜索组件-->
                    <SearchComponent
                      @onSearch="onSearch"
                    ></SearchComponent>
          
                    <!--          添加按钮-->
                    <ButtonComponent
                      @addUser="addUser"
                      :visible=false
                    >
                    </ButtonComponent>
                  </a-layout-content>
          
          
                  <a-layout-footer>
                    <!--          展示  删除按钮 修改按钮-->
                    <TableComponent
                      @showUser="showUser"
                      @delUser="delUser"
                      @upUser="upUser"
                      :data="data"
                    >
                    </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 {delUser, getUser, postRegister, postSearch, upUser} from "../../http/apis";
          const key = 'updatable';
          export default {
            components: {
              Crumbs,
              SearchComponent,
              ButtonComponent,
              TableComponent,
            },
            name: "UserManage",
            data() {
              return {
                visible: false,
                data: []
              }
            },
            methods: {
              //展示用户
              showUser() {
                getUser().then(res => {
                  console.log(res)
                  this.data = res.results
                })
              },
          
              //删除
              delUser(text) {
                const isDel = confirm("确定删除吗")
                if (isDel) {
                  delUser({id: text}).then(res => {
                    console.log(res)
                    this.showUser()
                    this.$message.info('删除成功');
                  }).catch(err => {
                    console.log(err)
                  })
                } else {
          
                }
          
              },
          
              //搜索name mobile email
              onSearch(value) {
                console.log(value);
                postSearch({search_name: value}).then(res => {
                  console.log(res)
                  const hide = this.$message.loading('Action in progress..', 0);
                  setTimeout(hide, 100);
                  this.data = res
                })
              },
          
              //添加用户
              addUser(params) {
                console.log(params.id)
                postRegister(params).then(res => {
                  console.log(res)
                  this.showUser()
                  this.visible = false;
                  this.$message.loading({content: '添加中...', key});
                  setTimeout(() => {
                    this.$message.success({content: '添加成功!', key, duration: 2});
                  }, 1000);
          
                })
                this.visible = false;
              },
              //修改用户
              upUser(params) {
          
                upUser(params).then(res => {
                  console.log(res)
                  this.showUser()
                  this.visible = false;
                })
                this.visible = false;
              },
            },
          
          
            //钩子方法
            mounted() {
            },
            created() {
              this.showUser()
          
            },
            //监听属性
            watch: {},
            //计算属性
            computed: {}
          }
          </script>
          
          <style scoped>
          .h3 {
            font-weight: 800;
            margin-left: -3%;
            margin-top: -20px;
          }
          
          </style>
          
          
      6. 登录页面 views/Login.vue

        1. <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>
          
          
      7. 全局配置src/main.js

        1. // 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'
          
          Vue.config.productionTip = false
          
          
          import ElementUI from 'element-ui'
          import 'element-ui/lib/theme-chalk/index.css'
          
          Vue.use(ElementUI)
          
          // 使用ant-design-vue
          import Antd from 'ant-design-vue';
          import 'ant-design-vue/dist/antd.css';
          
          Vue.config.productionTip = false
          Vue.use(Antd);
          
          
          /* eslint-disable no-new */
          new Vue({
            el: '#app',
            router,
            components: {App},
            template: '<App/>'
          })
          
          
          //路由守卫  未登录则登录
          router.beforeEach((to, from, next) => {
            // debugger
            if (to.path == '/login' || localStorage.getItem("token")) {
              next()
            } else {
              alert("尚未登录,请先登录")
              return next("/login")
            }
          })
          
          
      8. 路由 router/index.js

        1. 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: '/', component: index, name: 'index',
                children: [
                  {path: '/test', component: page('test/Test'), name: '测试页面'},
                  {path: '/usermanage', component: page('user-manage/UserManage'), name: '用户模块'},
          
                ]
              },
            ]
          })
          
          
          import VueRouter from 'vue-router'
          import index from "../components/index";
          //import HelloWorld from '@/components/HelloWorld'
          const originalPush = VueRouter.prototype.push
          VueRouter.prototype.push = function push(location) {
            return originalPush.call(this, location).catch(err => err)
          }
          
          
  • 相关阅读:
    收藏文章
    Python __func__
    Python 可变对象 & 不可变对象
    Kafka SASL ACL配置踩坑总结
    C++ 传递动态内存
    负数取反,单目运算“-”的运算
    C++重载运算符的理解
    c++ 随机函数用法
    static变量
    路由汇聚及其相关计算
  • 原文地址:https://www.cnblogs.com/wyx-zy/p/14032110.html
Copyright © 2011-2022 走看看