欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vue实现学生页面

程序员文章站 2022-03-08 23:50:58
...

1.在App.vue中监听login的状态,当login从false变为true,表示用户已经登录。

 watch:{
    login(val){//监听login的状态变化
      if(val){
        this.loadDetails();
      }
    }
  },
  methods:{
    loadDetails(){//请求学生信息的接口,测试一下
        alert("你好,小明同学");
    }
  }

2.请求接口测试

vue实现学生页面

import {api} from "./utils/api"
methods:{
    loadDetails(){
        //请求地址,参数
        api.get("/student/detail",{headers:{Token:this.info.token}}).then(data=>{
          console.log(data);
        })
    }
  }

vue实现学生页面

3.请求回来的数据怎么保存呢?

通过data来定义数据,初始化数据

data(){
    return{
      student:{
        orgs:[],//组织
        stats:{},//状态
        assignments:[]//所有作业的信息
      }
    }
  }

4.请求接口成功后,给这些初始化的参数赋值,把请求到的数据保存到data里面

 methods:{
    loadDetails(){
        api.get("/student/detail",{headers:{Token:this.info.token}}).then(data=>{
          console.log(data);
          this.student.orgs=data.orgs;
          this.student.assignments=data.assignments;
          this.student.stats=data.stats;
        })
    }
  }

5.因为有自动登录这个功能,刷新的时候login的状态不会改变,请求的函数不会被执行,怎么解决?

所以我们要使用created钩子函数,每次刷新都会加载,先判断是否登录

 created(){
   if(this.login){
     this.loadDetails();
   }
  }

6.判断头部信息放老师信息还是学生信息,isTeacher属性我们通过computed监听了

 <h2>HappyStudy</h2>
        <div>
          <div v-if="isTeacher">我是老师头部信息</div>
          <div v-else>我是学生头部信息</div>
        </div>

7.渲染数据到页面上

<div v-else>
            <h4>
              <span>{{info.full_name}}</span>
              <span>学号:{{info.name}}</span>
            </h4>
            <h5>
              <span v-for="(org,index) in student.orgs" :key="`${org}_${index}`">{{org}}</span>
            </h5>
            <div>
             <span>{{student.stats.uncommitted}}个作业待提交</span>
             <span>{{student.stats.revising}}个作业待批改</span>
             <span>{{student.stats.improvable}}个作业需完善</span>
             <span>{{student.stats.finished}}个作业已完成</span>
            </div>
            <a href="javascript:;">
              <a-button icon="home">代码仓库</a-button>
            </a>
            <a-button icon="logout">退出</a-button>
          </div>

8.样式不好看,内容被挤到下面去了,所以我们给父级设置Flex布局,等等

vue实现学生页面

为了使退出按钮能够居中

.out-center{
  align-self: center;
}

全部

<style lang="scss">
#App{
 min-height: 100vh;
}
.header{
  h2,h4,h5{
    color: white;
  }
  .right>.flexrow>*{
   margin-right: 25px;
  }
  .label{
    color: white;
    padding: 0 5px;
  }
}
.flexrow{
  display: flex;
  flex-direction: row;//行
  justify-content: space-between;
  flex-wrap: nowrap;
}
.right{
  width: auto;
  flex-grow: 1;
  display: flex;
  flex-direction: row;//行
  justify-content: space-between;
  flex-wrap: nowrap;
}
.flexcol{
  display: flex;
  flex-direction:column;//行
  flex-wrap: nowrap;
  justify-content: space-evenly;//间隔一样
  span{
    flex: 1;
    max-height: 20px;
    line-height: 20px;
  }
}
.out-center{
  align-self: center;
}
.btn-space{
  margin: 0 0 0 15px;
}
</style>

样式方面,仁者见仁,智者见智,这边就不多说了

9.代码仓库就不放链接了,退出按钮的功能已经做了,在user.js中已经实现了,那么我要怎么去触发函数呢?

不需要自己再去写,通过 $store.dispatch去触发

<a-button icon="logout" class="btn-space out-center" @click="$store.dispatch('user/logout')">退出</a-button>

10.后台管理系统,脱离不了表格的使用,表格的使用虽然复杂,但是我们可以从基本用法开始用起

我们需要把后台传过来的数据放在表格里面

11.父组件往子组件里面传值,通过props

11.1.绑定上自定义的属性

 <Student v-else :student="student"></Student>

11.2.接收,然后渲染

export default {
    props:["student"]
}

vue实现学生页面

12.表格里面传的是数组的数据

最基本的使用要绑定上两个,一个是data-source(数据数组),一个是columns(表格列的配置)

dataIndex:'name',我们应该去渲染数据里面name的字段

13.官网上有定义data,数据是展示给我们看的,而我们不需要去定义,因为我们数据是从后台传过来的,我们需要去定义columns

<a-table :columns="columns" :data-source="data"></a-table>

14.已渲染出一列数据,如下,其他以此类推

<template>
    <div>
        <a-table :columns="columns" :dataSource="student.assignments"></a-table>
    </div>
</template>
<script>
export default {
    data(){
       return{
           columns:[{
               title:"课程",
               dataIndex:"org_name" //dataIndex要渲染哪个字段
           }]
       }
    },
    props:["student"]
}
</script>
<style lang="scss">

</style>

15.使用dataIndex是直接渲染,但是有的数据需要拼接或者运算,怎么办呢?

使用customRender,生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引,@return 里面可以设置表格行/列合并

vue实现学生页面

 data(){
       return{
           columns:[
           {
               title:"课程",
               dataIndex:"org_name"
           },
            {
               title:"作业名称",
               dataIndex:"name"
           },
            {
               title:"开始-截止时间",
               //这行的值,数据,索引
               customRender(text,record,index){
                   console.log(record);
                 return `${record.start_time}~${record.end_time}`
               }
           }
           
           ]
       }
    }

16.怎么渲染出按钮呢?

通过scopedSlots,使用 columns 时,可以通过该属性配置支持 slot-scope 的属性,如 scopedSlots: { customRender: 'XXX'}

16.1.先在columns里面定义scopedSlots

data(){
       return{
           columns:[
           {
               title:"课程",
               dataIndex:"org_name"
           },
            {
               title:"作业名称",
               dataIndex:"name"
           },
            {
               title:"开始-截止时间",
               //这行的值,数据,索引
               customRender(text,record,index){
                   console.log(record);
                   console.log(text);
                   console.log(index);
                 return `${record.start_time}~${record.end_time}`
               }
           },
           {
               title:"操作",
               //渲染按钮
               scopedSlots:{
                   customRender:"operation" //对应slot里面的名称
               }
           } 
           ]
       }
    }

16.2.然后在slot标签里面编写按钮

<template>
    <div>
        <a-table :columns="columns" :dataSource="student.assignments">
            <template slot="operation">
                  <a-upload name="file">
                      <a-button icon="up">上传</a-button>
                  </a-upload>
            </template>
        </a-table>
    </div>
</template>

17.上传是通过id来上传,不需要使用axios

vue实现学生页面

<script>
const HOST="http://sandbox_api.estudy.xyz"
export default {
    data(){
       return{
           uploadHost:HOST+"/student/upload",//上传地址
       }
    },
}
</script>

 然后在action中绑定上请求地址

<template>
    <div>
        <a-table :columns="columns" :dataSource="student.assignments">
            <template slot="operation">
                  <a-upload name="file" :action="uploadHost">
                      <a-button icon="up">上传</a-button>
                  </a-upload>
            </template>
        </a-table>
    </div>
</template>

18.上传的时候,不仅要传id,也要传token

组件库里面的headers:设置上传的请求头部

18.1.首先要先获取info的信息,通过

import {mapState} from "vuex"; //引入
export default {
    computed:{
      ...mapState("user",["info"])
    }
}

18.2.在headers请求头里面传参:把token对象传进去

<template slot="operation">
                  <a-upload name="file" :action="uploadHost" :headers="{Token:info.token}">
                      <a-button icon="up">上传</a-button>
                  </a-upload>
            </template>

19. slot-scope里面可以传三个参数,text,record,index,

我们从record中取出上传文件的id,把id也传过去

vue实现学生页面

 <template slot="operation" slot-scope="record">
                  <a-upload 
                  name="file" 
                  :action="uploadHost" 
                  :headers="{Token:info.token}"
                  :data="{id:record.assignment_id}">
                      <a-button icon="upload">上传</a-button>
                  </a-upload>
            </template>

 20.我们上传文件成功或者失败要给个提示什么的,要加上回调函数

vue实现学生页面

20.1.绑定上点击事件

 <template slot="operation" slot-scope="record">
                  <a-upload 
                  name="file" 
                  :action="uploadHost" 
                  :headers="{Token:info.token}"
                  :data="{id:record.assignment_id}"
                  @change="changeUpload">
                      <a-button icon="upload">上传</a-button>
                  </a-upload>
            </template>
methods:{
        changeUpload(info){
            console.log(info);
        }
    },

看一下是什么信息,再来判断

vue实现学生页面

20.2.根据后台数据,判断是上传成功或者上传失败

methods:{
        changeUpload(info){
            console.log(info);
            if(info.file.status==="done"&&info.file.response.data){
                this.$message.info("上传成功");
            }else if(info.file.status==="error"){
                this.$notification.error({
                    message:"上传失败",
                    description:info.file.response.errorMessage
                })
            }
        }
}

21.不想要上传时有进度条,怎么去掉?

 :showUploadList="false" ,可以传对象或者布尔

vue实现学生页面

<template slot="operation" slot-scope="record">
                  <a-upload 
                  name="file" 
                  :action="uploadHost" 
                  :headers="{Token:info.token}"
                  :data="{id:record.assignment_id}"
                  @change="changeUpload"
                  :showUploadList="false">
                      <a-button icon="upload">上传</a-button>
                  </a-upload>
            </template>

 以上,我们完成上传功能。

接下来,实现下载功能

22.只有作业已经上传过了,才有下载按钮,否则不出现下载按钮

根据后台有没有work这个字段,来判断下载按钮有没有

<a v-if="record.work" href="">
                       <a-button icon="download">下载</a-button>
</a>

未完待续

相关标签: vue小练习 vue