zoukankan      html  css  js  c++  java
  • 路飞学城详细步骤 part2

    一 显示课程列表

      需求:当你点击课程,course.vue在 <router-view>渲染,并不需要你进行其他点击,所欲的课程列表直接在前端显示,数据是从数据库拿到的。

      补充1:生命周期钩子:mounted

      mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。

      1  完成这个功能的vue组件框架

      <template>

        <ul>

          <a v-for="(item,index) in course_list">{{item.name}}

        </ul>

      </template>

      <script>

        

        export default{

              name:'xx',

              data(){

                return{

                  course_list:[]

                  }

                }

              mounted(){

                    this.func1()

                    }

              methods:{

                  func1(){

                      var that = this

                      this.$axios.request({

                               }

                              ).then(function(response){

                                          that.course_list = response.data

                                          })

                      }

                  }

            }

      </script>

      <style>

      </style>

      实际代码

      Course.vue

    <template>
      <div>
        <p>{{msg}}</p>
        <ul>
          <li v-for="(item,index) in course_list">{{item.id}}   {{item.name}}</li>
        </ul>
      </div>
    </template>
    
    <script>
      export default{
          name:'course',
          data(){
            return {
              msg: '这是课程页面',
              course_list: []
            }
          },
          mounted(){
              this.initcourse()
          },
          methods:{
              initcourse(){
                  var that = this
                this.$axios.request({
                  url:this.$store.state.apilist.course,     // 更合理的方式使吧url统一放在vuex中,方便维护。
                  method:'GET',
                  params:{                                  //以 127.0.0.1:8000/api/v1/course/?token=gaegaeg3523的样式访问
                      token:this.$store.state.token,        // 因为是get请求,没有请求体,所以没有 data这个key值,与之对应的是有params这个key。
                  }
                }).then(function (response) {
                    console.log(response.data,typeof response.data);   // 类型是object 对象
                    that.course_list = response.data
                })
              }
          }
      }
    </script>
    
    <style>
    
    </style>

       页面显示

      

      2  需求 :到了上一步,感觉差不多了。实际上,点击每个课程,都应该跳转到显示每个课程详细信息的页面。 

       对Course.vue 和 路由的 index.js 进行如下修改。

        Course.vue

    <template>
      <div>
        <p>{{msg}}</p>
        <ul>
          <router-link v-for="(item,index) in course_list" :to="{path:'/course/detail/'+item.id}"> {{item.name}}</router-link>   <!--这里感觉带冒号是与路由中的数据吻合 -->
        </ul>
      </div>
    </template>

      index.js

     {
          path: '/course/detail/:id',           //:id 表示动态的
          name: 'coursedetail',
          component: CourseDetail,
        },

      

      需求:有个问题,在这个页面中如何获取具体的课程的id。因为要 需要根据具体的id,获取数据库的详细信息。

      在CourseDetail.vue中 ,this.$route.params.id 便可以获取到跳转的id值。 这个 'id' 是与index.js中的 :id 是相对应的。 index.js中改为 :xx,在CourseDetail中便是用this.$route.params.xx获取。

      剩下的代码就可以完成,后台的路由改动需要注意下。

      前端代码

      Course.vue

    <template>
      <div>
        <p>{{msg}}</p>
        <ul v-for="(item,index) in course_list">
          <li>
            <router-link  :to="{path:'/course/detail/'+item.id}"> <div>{{item.name}}</div></router-link>
          </li>
        </ul>
      </div>
    </template>
    
    <script>
      export default{
          name:'course',
          data(){
            return {
              msg: '这是课程页面',
              course_list: []
            }
          },
          mounted(){
              this.initcourse()
          },
          methods:{
              initcourse(){
                  var that = this
                this.$axios.request({
                  url:this.$store.state.apilist.course,
                  method:'GET',
                  params:{
                      token:this.$store.state.token,
                  }
                }).then(function (response) {
                    console.log(response.data,typeof response.data);
                    that.course_list = response.data
                })
              }
          }
      }
    </script>
    
    <style>
    
    </style>

      Course.vue

    <template>
      <div>
        <p>{{msg}}</p>
        课程id:{{courseid}}
        课程:{{detail.name}}
        价格:{{detail.price}}
        周期:{{detail.period}}
      </div>
    </template>
    
    <script>
      export default{
          name:'coursedetail',
          data(){
            return {
              msg: '这是详细的课程信息',
              courseid:this.$route.params.id,  //获取 课程id
              detail:{}
            }
          },
          mounted(){
              this.coursedetail()
        },
          methods:{
            coursedetail(){
                 let that = this;
                 var url = this.$store.state.apilist.course + this.courseid + '/';   // 拼接 要访问的后台api,一定注意,最后面要加 '/',排错拍了一个多小时。
                this.$axios.request({
    //              url:'http://127.0.0.1:8000/api/v1/course/'+this.$route.params.id,
                  url:url,
                  method:'GET',
                  params:{
                    token:this.$store.state.token,
                  },
                  }
                ).then(function (response) {
                  that.detail = response.data;
                })
            }
        },
    
      }
    </script>
    
    <style>
    
    </style>

      后台代码

      收获:两个不同的路由,可以走一个视图。因为,url 后面的(d+) 是可以视图的参数 (*args,**kwargs)。在视图中,对args,kwargs进行判断区分即可。

      urls.py。

    urlpatterns = [
        url(r'^(?P<version>[v1|v2]+)/auth/$',views.AuthView.as_view() ),
        url(r'^(?P<version>[v1|v2]+)/course/$',views.CourseView.as_view() ),
        url(r'^(?P<version>[v1|v2]+)/course/(?P<pk>d+)/$',views.CourseView.as_view() ),
    ]

      views.py

    class CourseView(APIView):
        def get(self,request,*args,**kwargs):
            pk = kwargs.get('pk')
            print(pk)
            if not pk:
                ret = [{'id':1,'name':'python基础'},
                       {'id':2,'name':'面向对象'}
                       ]
                return Response(ret)
            else:
                ret = {'name': 'python基础',
                       'price': '50',
                       'period': '180',
                       }
                return Response(ret)

      3 实现每个课程页面有其关联课程。关联课程可以跳转。

      思路 1 this.$router.push(),可以实现导航到不同的url。

        2 利用 <router-link :to="">的方式实现页面跳转,会有这样一个问题。 api/v1/course/2  -->  api/v1/course/3,在浏览器上,路径的url的确会发生改变,但是因为这两个url在vue路由中匹配的是同一个地址,只是 后面的 id不同。这种情况下,页面是不会刷新的,尽管手动刷新是可以的。这不是个好的方法。

        3 手动写函数,在函数中,利用router.push()跳转页面。然后,执行 初始化页面的方法。

      Course.vue

    <template>
      <div>
        <p>{{msg}}</p>
        <p>课程id:{{courseid}}</p>
        <p> 课程:{{detail.name}}</p>
        <p>价格:{{detail.price}}</p>
        <p> 周期:{{detail.period}}</p>
        推荐课程:
                  <ul>
                    <li v-for="(item,index) in this.detail.recommend"><a href="" @click="changeurl(item.id)">{{item.name}}</a></li>
                  </ul>
      </div>
    </template>
    
    <script>
      export default{
          name:'coursedetail',
          data(){
            return {
              msg: '这是详细的课程信息',
              courseid:this.$route.params.id,
              detail:{}
            }
          },
          mounted(){
              this.initcoursedetail()
        },
          methods:{
            initcoursedetail(){
                 let that = this;
                 var url = this.$store.state.apilist.course + this.courseid + '/';
                this.$axios.request({
    //              url:'http://127.0.0.1:8000/api/v1/course/'+this.$route.params.id,
                  url:url,
                  method:'GET',
                  params:{
                    token:this.$store.state.token,
                  },
                  }
                ).then(function (response) {
                  that.detail = response.data;
                })
            },
            changeurl(courseid){
                this.courseid = courseid;
                this.$router.push({name:'courseDetail',params:{id:courseid}});  // 注意,name: '',一定要加。是去路由中去找这个名称,反向生成。
                this.initcoursedetail()   // 初始化页面,拿到当前页面的id,从数据库中取值,666
            }
        },
    
      }
    </script>
    
    <style>
    
    </style>

      4 路由和视图的逼格更高点

      之前的view.py

    class CourseView(APIView):
        def get(self,request,*args,**kwargs):
            pk = kwargs.get('pk')
            print(pk)
            if not pk:
                ret = [{'id':1,'name':'python基础'},
                       {'id':2,'name':'面向对象'}
                       ]
                return Response(ret)
            else:
                ret = {'name': 'python基础',
                       'price': '50',
                       'period': '180',
                       'recommend':[{'id':10,'name':'基本数据类型'}],
                       }
                return Response(ret)

      urls.py

    urlpatterns = [
        url(r'^(?P<version>[v1|v2]+)/auth/$',views.AuthView.as_view() ),
        url(r'^(?P<version>[v1|v2]+)/course/$',views.CourseView.as_view() ),
        url(r'^(?P<version>[v1|v2]+)/course/(?P<pk>d+)/$',views.CourseView.as_view() ),

      改之后

      views.py

    class CourseView(GenericViewSet):                           #继承GenericViewSet
        def list(self,request,*args,**kwargs):
            ret = [{'id':1,'name':'python基础'},
                   {'id':2,'name':'面向对象'}
                   ]
            return Response(ret)
        def retrieve(self,request,*args,**kwargs):
            pk = kwargs.get('pk')
            ret = {'name': 'python基础',
                   'price': '50',
                   'period': '180',
                   'recommend': [{'id': 10, 'name': '基本数据类型'}],
                   }

      urls.py

    urlpatterns = [
        url(r'^(?P<version>[v1|v2]+)/auth/$',views.AuthView.as_view() ),
        url(r'^(?P<version>[v1|v2]+)/course/$',views.CourseView.as_view({'get':'list'}) ),
        url(r'^(?P<version>[v1|v2]+)/course/(?P<pk>d+)/$',views.CourseView.as_view({'get':'retrieve'}) ),
    ]

      

      这样就不在视图里对情况进行判断,而是通过 最开始的路由分发的时候就做好对应关系,更简洁。

      根据url,找到对应的视图,对此url的访问方式不同,依照as_views()后面的对应关系,执行这个视图的不同方法。api/course/  和 api/course/1/ 是两个不同的url,记住,尽管可以走同一个视图。

  • 相关阅读:
    Linux安装jdk
    虚拟机克隆配置
    eclipse 设置默认编码为Utf-8
    working copy is not up-to-date
    request、response 中文乱码问题与解决方式
    eclipse Some projects cannot be imported because they already exist in the workspace
    Eclipse 常用快捷键
    Error Code: 1175 Mysql中更新或删除时报错(未带关键字条件)
    jsp中文件下载的实现
    mySql 自动备份数据库
  • 原文地址:https://www.cnblogs.com/654321cc/p/8573545.html
Copyright © 2011-2022 走看看