zoukankan      html  css  js  c++  java
  • 推荐课程及用户登录

    实现的效果:

    点击推荐课程,要跳转到相应的课程的详细页。

    Detail.vue

    <template>
      <div>
            <h1>课程详细页面</h1>
            <p>课程标题:{{detail.title}}</p>
            <p>图片:{{detail.img}}</p>
            <p>课程难度:{{detail.level}}</p>
            <p>课程口号:{{detail.slogon}}</p>
    
            <p>为什么要学?{{detail.why}}</p>
            <div>
              章节:
              <ul v-for="item in detail.chapter">
                <li>{{item.name}}</li>
              </ul>
            </div>
    
            <div>
              <h3>推荐课程:</h3>
              <ul v-for="item in detail.recommends">
                <li @click="changeDetail(item.id)">{{item.title}}</li>   //这里绑定一个点击事件,把ID传入
              </ul>
            </div>
    
      </div>
    
    </template>
    
    <script>
        export default {
            name: "detail",
          data(){
              return {
                detail:{
                  charter:[],
                  course:null,
                  level:null,
                  img:null,
                  title:null,
                  slogon:null,
                  why:null,
                  recommends:[]
                }
              }
          },
          mounted(){
              var id=this.$route.params.id;
              this.initDetail(id)
          },
          methods:{
            initDetail(nid){
    
              var that = this;
              this.$axios.request({
                  url:'http://127.0.0.1:8000/api/v1/course/'+nid+'/',
                  method:"GET",
    
              }).then(function (arg) {
                if (arg.data.code ===1000){
                   console.log(arg.data);
                    that.detail=arg.data.data
                }else{
                  alert(arg.data.error)
                }
    
              })
            },
            changeDetail(id){
              this.initDetail(id);    //只绑定这一个那么页面跳转,URL不跳
              this.$router.push({name:'detail',params:{id:id}}) //只绑定这一个,URL跳转,页面不变     所以需要2个进行配合变化。
            }
        }
        }
    </script>
    
    <style scoped>
    
    </style>

    然后登陆问题:

    1.首先做一个登录的组件

     

    2.在index.js中做一个挂载

    3.Login.vue组件

    <template>
      <div>
        <h1>用户登录</h1>
        <p><input type="text" placeholder="请输入用户名" v-model="username"></p>
        <p><input type="password" placeholder="请输入密码" v-model="password"></p>
        <p><input type="button" @click="doLogin" value="登录"></p>
      </div>
    </template>
    
    <script>
        export default {
            name: "login",
            data(){
              return {
                username:"",  //跟上面的v-model做一个双向绑定
                password:"",
              }
            },
          methods:{
              doLogin(){     //点击按钮,做一个登录
                var that=this   //这是在函数外把this赋值给that,axios里面的this就改变了,不是原来的this
                this.$axios.request({
                  url:'http://127.0.0.1:8000/api/v1/auth/',
                  method:"POST",
                  data:{
    
                    user:this.username,   //发送post请求,把用户名和密码传送过去。
                    pwd:this.password,
    
                  },
                  headers:{
                    "Content-Type":"application/json"   //记得加一个头,告诉服务器是json数据.
                  }
                }).then(function (arg) {
                  if(arg.data.code===1000){
                     console.log(arg);
                     that.$store.state.token=arg.data.token;   //取到服务器响应的token值
                     that.$store.state.username=that.username; //取到用户输入的用户名
                     that.$store.commit('saveToken',{token:arg.data.token,username:that.username})  发送一个保存token值和用户名的信号。
                  }else {
                    alert(arg.data.error)
                  }
    
                }).catch(function (arg) {
                  console.log("发生错误")
                })
              }
          }
        }
    </script>
    
    <style scoped>
    
    </style>

    4.在src下建立一个store文件夹并且一个store.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    import Cookie from 'vue-cookies'   //导入cookies 
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      // 组件中通过 this.$store.state.username 调用
      state: {
        username: Cookie.get("username"),    //这里如果还是原来的null的话,一刷新,全局变量就没了,刷新后因为下面蛇者了cookie,所以通过cookie去取这两个值。
        token:Cookie.get("token"),
      },
      mutations: {
        // 组件中通过 this.$store.commit(saveToken,参数)  调用
        saveToken: function (state, userToken) {
          state.username = userToken.username;      //这里通过上面那一步调用拿到用户名
          state.token = userToken.token;            //拿到token
          Cookie.set("username", userToken.username, "20min");   //设置一个cookie值。
          Cookie.set("token", userToken.token, "20min")
    
        },
        clearToken: function (state) {
          state.username = null;              //这里点击注销把用户名和token变为空,并且把cookie移除。
          state.token = null;
          Cookie.remove('username');
          Cookie.remove('token')
    
        }
      }
    })

    最后就是开发发送用户登录的接口。

    加一条URL:

     url(r'^auth/$',account.AuthView.as_view()),

    2.需要加两张表。

    class UserInfo(models.Model):
        user=models.CharField(max_length=32)
        pwd=models.CharField(max_length=64)
    
    class UserToken(models.Model):
        user=models.OneToOneField(to="UserInfo",on_delete=models.CASCADE)
        token=models.CharField(max_length=128)

    3.在account,py中进行登录验证接口开发

    from rest_framework.views import APIView
    from rest_framework.response import Response
    from api import models
    import uuid
    
    class AuthView(APIView):
        def post(self,request,*args,**kwargs):
            ret = {'code':1000}
            user=request.data.get("user")
            pwd=request.data.get("pwd")
            user=models.UserInfo.objects.filter(user=user,pwd=pwd).first()  #首先拿到这个用户对象
            if not user:
                ret['code']=1001
                ret['error']='用户名或者密码错误'
            else:
                uid=str(uuid.uuid4())    #存在的话设置一个token字符串
                models.UserToken.objects.update_or_create(user=user,defaults={'token':uid})  #给登录用户创造或者更新一条数据
                ret['token']=uid   #前端也返回一个token.
            return Response(ret)

    在开发中需要注意的一个点就是。

    随着技术的发展,现在的浏览器可以支持主动设置从而允许跨域请求,即:跨域资源共享(CORS,Cross-Origin Resource Sharing),其本质是设置响应头,使得浏览器允许跨域请求。

    * 简单请求 OR 非简单请求

    条件:
    1、请求方式:HEAD、GET、POST
    2、请求头信息:
    Accept
    Accept-Language
    Content-Language
    Last-Event-ID
    Content-Type 对应的值是以下三个中的任意一个
    application/x-www-form-urlencoded
    multipart/form-data
    text/plain

    注意:同时满足以上两个条件时,则是简单请求,否则为复杂请求

    * 简单请求和非简单请求的区别?

    简单请求:一次请求
    非简单请求:两次请求,在发送数据之前会先发一次请求用于做“预检”,只有“预检”通过后才再发送一次请求用于数据传输。
    * 关于“预检”


    - 请求方式:OPTIONS
    - “预检”其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息
    - 如何“预检”
    => 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过
    Access-Control-Request-Method
    => 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过
    Access-Control-Request-Headers

     在这里还有的需求就是请求某些值需要登录用户才可以,在前端做一个拦截器可以,在后端也需要做一个校验。

    1.使用认证组件:

    auth.py

    # Author:Jesi
    # Time : 2018/10/17 9:45
    from api import models
    from rest_framework.authentication import BaseAuthentication
    from rest_framework.exceptions import AuthenticationFailed
    
    class LuffyAuth(BaseAuthentication):
        def authenticate(self, request):
            token = request.query_params.get('token')
            obj = models.UserToken.objects.filter(token=token).first()
            if not obj:
                raise AuthenticationFailed({'code':1001,'error':'认证失败'})
            return (obj.user.user,obj)

    在这里取到前端登录用户传来的token值,然后拿到这个对象,如果不存在的话,那么抛出AuthenticationFailed的异常。

    如果通过了需要返回一个元组。  第一个值是用户的用户名,第二个值就是这个认证过的obj对象。

    2.进行微职位的请求的时候可以进行一下认证

    from api.auth.auth import LuffyAuth
    class MicroView(APIView):
        authentication_classes = [LuffyAuth,]
        def get(self,request,*args,**kwargs):
            print(request.user)     #jesi
    print(request.auth)    #UserToken object (1)
            ret={'code':1000,'title':"微职位"}
    
            return Response(ret)

    所以效果图就是下面的:

    使用假的token值或者不带认证失败。

    用户带正确的token值认证成功并且返回所需数据。

  • 相关阅读:
    canvas设置渐变
    canvas设置线条样式
    canvas给图形添加颜色
    Vue中父组件与子组件之间传值
    Vue实例的生命周期
    es6常用语法和特性
    JS基础:常用API
    JS基础:函数
    JS基础:闭包和作用域链
    JS基础:this的指向以及apply、call的作用
  • 原文地址:https://www.cnblogs.com/geogre123/p/9800495.html
Copyright © 2011-2022 走看看