zoukankan      html  css  js  c++  java
  • vue+django rest framework

    vue+django rest framework

    简单回顾vue

    首先强调:

    修改源:
        npm config set registry https://registry.npm.taobao.org 
    
    创建脚手架:
        vue init webpack Vue项目名称
        #记得把route的这个设置为yes,其他的设置为no 比如: Install vue-router? Yes
        
    
    插件:
        axios,发送Ajax请求
        vuex,保存所有组件共用的变量
        vue-cookies,操作cookie
    

    流程详细

    1、创建脚手架

    #可以用淘宝源来下载,这样下载的快
    npm config set registry https://registry.npm.taobao.org
    vue init webpack
    #吧route的那一个设置为yes,其他的设置为no
    

    2、运行

    cd Vue项目名称 
    npm run dev
    

    3、显示组件

    # 用于点击查看组件
    <router-link to="/index">首页</router-link>
                    
    # 组件显示的位置
    <router-view/>
    

    4、路由配置
    index.js

    import Vue from 'vue'
    import Router from 'vue-router'
    import Index from '@/components/Index'
    import Login from '@/components/Login'
    import Course from '@/components/Course'
    import Micro from '@/components/Micro'
    import News from '@/components/News'
    import CourseDetail from '@/components/CourseDetail'
    import NotFound from '@/components/NotFound'
    
    Vue.use(Router)
    
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'index',
          component: Index
        },
        {
          path: '/index',
          name: 'index',
          component: Index
        },
        {
          path: '/course',
          name: 'course',
          component: Course
        },
        {
          path: '/course-detail/:id/',
          name: 'courseDetail',
          component: CourseDetail
        },
        {
          path: '/micro',
          name: 'micro',
          component: Micro
        },
        {
          path: '/news',
          name: 'news',
          component: News
        },
        {
          path: '/login',
          name: 'login',
          component: Login
        },
        {
          path: '*',
          component: NotFound
        }
      ],
      mode: 'history'
    })
    
    # 定义路由
                        {
                          path: '/course-detail/:id/',
                          name: 'courseDetail',
                          component: CourseDetail
                        },
                        {
                          path: '/login',
                          name: 'login',
                          component: Login
                        },
                        {
                          path: '*',
                          component: NotFound
                        }
                    
                    
                    # router-link参数
                        <router-link :to="{'path':'/course-detail/'+item.id }">{{item.name}}</router-link>
                        <router-link to="/index">首页</router-link>
        
                    # 获取传过来的参数
                        this.$route.params.id
                    # 重定向
                        this.$router.push('/index')
    
    注意

    我们访问的时候url一般会带有‘#’,如果不想有,在路由后面加上 mode: 'history'

    5、写组件
    组件写在src/components下

    <template>
    
      <div>
        <h1>登录页面</h1>
        <div>
          <input type="text" v-model="username" placeholder="用户名">
          <input type="text" v-model="password" placeholder="密码">
          <a @click="doLogin">提交</a>
        </div>
      </div>
    </template>
    
    <script>
    
    export default {
      # 定义局部字段
      data () {
        return {
          username: '',
          password: ''
        }
      },
      # 加载时执行
      mounted:function(){
      },
      # 定义局部方法
      methods:{
        doLogin() {
          var that = this
          this.$axios.request({
            url: 'http://127.0.0.1:8000/login/',
            method: 'POST',
            data: {
              username: this.username,
              password: this.password
            },
            responseType: 'json'
          }).then(function (response) {
            console.log(response.data)
            // 找到全局变量,把用户名和token赋值到其中。
            that.$store.commit('saveToken',response.data)
            // 重定向到index
            that.$router.push('/index')
          })
        }
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    
    </style>
    

    6、发送ajax请求:axios

    #发送ajax请求需要安装axios组件
    npm install axios
    
    npm install axios
    
    main.js 
        import Vue from 'vue'
        import App from './App'
        import router from './router'
        
        import axios from 'axios'
        
        Vue.prototype.$axios = axios
    
        Vue.config.productionTip = false
        ...
    
    组件使用:
        this.$axios.request({
        url: 'http://127.0.0.1:8000/login/',
        method: 'POST',
        data: {
          username: this.username,
          password: this.password
        },
        responseType: 'json'
      }).then(function (response) {
        console.log(response.data)
        
        that.$router.push('/index')
      })
    
    PS:重定向 that.$router.push('/index')
    

    7、vuex:保存所有组件共用的变量

    安装  
    npm install vuex
    

    具体步骤:

    a、先创建一个文件夹,store----store.js
    b、要先使用就先导入
    c、实例化一个对象,并且让别人可以用
    d、这样每一个组件都可以用username和token了

    npm install vuex 
    
    main.js 
    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import axios from 'axios'
    
    import store from './store/store'    # vuex
    
    Vue.prototype.$axios = axios
    
    Vue.config.productionTip = false
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      store,                            # vuex
      router,
      components: { App },
      template: '<App/>'
    })
    
    src/store/store.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    import Cookie from 'vue-cookies'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      // 组件中通过 this.$store.state.username 调用
      state: {
        username: Cookie.get('username'),
        token: Cookie.get('token')
      },
      mutations: {
        // 组件中通过 this.$store.commit(参数)  调用
        saveToken: function (state, data) {
          state.username = data.username
          state.token = data.token
          Cookie.set('username', data.username, '20min')
          Cookie.set('token', data.token, '20min')
    
        },
        clearToken: function (state) {
          state.username = null
          state.token = null
          Cookie.remove('username')
          Cookie.remove('token')
        }
      }
    })
    

    8、vue-cookies:操作cookie

    npm install vue-cookies
    
    npm install vue-cookies 
    
    
    Cookie.get('username')
    
    Cookie.set('username', data.username, '20min')
    Cookie.remove('username')
    
    
    src/store/store.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    import Cookie from 'vue-cookies'    # vue-cookies
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      // 组件中通过 this.$store.state.username 调用
      state: {
        username: Cookie.get('username'),    # vue-cookies
        token: Cookie.get('token')            # vue-cookies
      },
      mutations: {
        // 组件中通过 this.$store.commit(参数)  调用
        saveToken: function (state, data) {
          state.username = data.username
          state.token = data.token
          Cookie.set('username', data.username, '20min')    # vue-cookies
          Cookie.set('token', data.token, '20min')    
    
        },
        clearToken: function (state) {
          state.username = null
          state.token = null
          Cookie.remove('username')    # vue-cookies
          Cookie.remove('token')
        }
      }
    })
    

    三、代码实现

    前端代码
    index.html

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <link rel="stylesheet" href="./static/bootstrap-3.3.7-dist/css/bootstrap.css">
        <script src="./static/bootstrap-3.3.7-dist/js/bootstrap.js"></script>
    
        <title>s6vue</title>
      </head>
      <body>
        <div id="app"></div>
        <!-- built files will be auto injected -->
      </body>
    </html>
    
    index.html
    

    main.js

    // 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'
    import store from './store/store'  //
    import axios from 'axios'    // 要是用axios,就得先导入
    Vue.prototype.$axios = axios  //注册,以后就可以用$axios来定义了
    
    Vue.config.productionTip = false
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      store,
      router,
      components: { App },
      template: '<App/>'
    })
    

    app.vue

    <template>
      <div id="app">
        <!--首页里面永远是固定的东西-->
        <ul class="nav nav-tabs">
          <li><router-link to="/index">首页</router-link>  <!--用于点击查看组件--></li>
          <li><router-link to="/micro">学位课</router-link>  <!--用于点击查看组件--></li>
          <li><router-link to="/course">课程</router-link></li>  <!--用于点击查看组件-->
          <li><router-link to="/news">深科技</router-link></li>  <!--用于点击查看组件-->
          <!--如果已经登录了,就不用在登录了,在页面还是显示当前用户和注销,如果没有登录就显示登录-->
          <li v-if="this.$store.state.username">
            <span><a>欢迎{{ this.$store.state.username }}登录</a></span>
            <span><a @click="logout()">注销</a></span>
          </li>
          <li v-else=""> <router-link to="/login">登录</router-link></li>
        </ul>
       <router-view/>  <!--组件显示的位置-->
      </div>
    </template>
    
    <script>
    export default {
      name: 'App',
      methods:{
        logout(){
          this.$store.state.username=''
          this.$store.state.token=''
        }
      }
    }
    </script>
    
    <style>
    
    
    </style>
    
    app.vue
    

    router -- index.js

    import Vue from 'vue'
    import Router from 'vue-router'
    import HelloWorld from '@/components/HelloWorld'
    import Index from '@/components/Index'
    import Login from '@/components/Login'
    import Micro from '@/components/Micro'
    import News from '@/components/News'
    import Course from '@/components/Course'
    import CourseDetail from '@/components/CourseDetail'
    import NotFound from '@/components/NotFound'
    
    
    
    Vue.use(Router)
    
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'HelloWorld',
          component: HelloWorld
        },
        {
          path: '/index',
          name: 'index',
          component: Index
        },
         {
          path: '/login',
          name: 'Login',
          component: Login
        },
         {
          path: '/course',
          name: 'Course',
          component: Course
        },
         {
          path: '/course-detail/:id/',
          name: 'CourseDetail',
          component: CourseDetail
        },
         {
          path: '/micro/',
          name: 'Micro',
          component: Micro
        },
        {
          path: '/course-detail/:id/',
          name: 'CourseDetail',
          component: CourseDetail
        },
         {
          path: '/news/',
          name: 'News',
          component: News
        },
        {
          path: '*',
          component: NotFound
        }
      ],
      mode:'history'
    })
    
    router ---index.js
    

    组件components
    Index.vue

    <template>
      <div class="hello">
          <h1>{{ msg }}</h1>
      </div>
    </template>
    
    <script>
    export default {
      name: 'index',
      data () {
        return {
          msg:"这里是首页"
        }
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style>
    
    </style>
    
    Index.vue
    

    Login.vue

    <template>
      <div class="">
        <h2>登录页面</h2>
        <p>用户名:<input type="text" placeholder="username" v-model="username"></p>
        <p>密码:<input type="text" placeholder="password" v-model="password"></p>
        <button><a @click="DoLogin()">提交</a></button>
      </div>
    </template>
    
    <script>
    export default {
      name: 'index',
      data () {
        return {
          username: "",
          password: ""
        }
      },
        methods:{
          DoLogin (){
              var that = this
    //          console.log(this.$axios);
              this.$axios.request({  //发送axios请求
                url:'http://127.0.0.1:8082/login/', //请求路径
                method:"POST",//请求方式
                data:{   //要发送 的数据
                  username:this.username,
                  password:this.password
                },
                responseType:'json'  //期望返回的类型是json的格式
              }).then(function (response) {  //吧返回的结果交给回调函数处理
                //登录成功之后,找到全局变量,吧用户名和token赋值到其中
                that.$store.commit('saveToken',response.data);
                //重定向(登录成功之后让跳转到index页面)
                  that.$router.push('/index')
                  //为什么不直接用this呢?这里的this代表的是$axios,用that他代指的是整个Vue对象
              })
          }
        }
    
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style>
    
    </style>
    
    Login.vue
    

    course.vue

    <template>
      <div class="">
          <ul>
            <li v-for="item in courseList">
              <router-link :to="{'path':'/course-detail/'+item.id}">{{item.name}}</router-link>
            </li>
          </ul>
      </div>
    </template>
    
    <script>
    export default {
      name: 'index',
      data () {
        return {
          msg:'课程页面',
          courseList:[]
        }
      },
       mounted:function () {
          //当组件一加载的时候就应该去数据库去获取数据
          this.initCourses()
      },
      methods:{
        initCourses:function () {
          var that = this
          this.$axios.request({
              url:'http://127.0.0.1:8082/course/',
              method:"GET"
          }).then(function (response) {
            console.log(response);
            that.courseList = response.data.courseList  //吧从数据库取的数据赋值到courseList列表里面
          })
        }
      }
    
    }
    
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style>
    
    </style>
    
    course.vue
    

    CourseDetail.vue

    <template>
      <div class="hello">
        <div>课程详细</div>
        <h3>{{ title }}</h3>
        <h3>{{ summary }}</h3>
      </div>
    </template>
    
    <script>
    export default {
      name: 'HelloWorld',
      data () {
        return {
          title:'',
          summary:''
        }
      },
      mounted:function () {
        //当组件一加载就执行的函数
        this.initCoursesDetail()
      },
      methods:{
        initCoursesDetail(){
          var nid = this.$route.params.id  //获取id
          var that = this
          var url = 'http://127.0.0.1:8082/course/' + nid + '.json'
          this.$axios.request({
            url:url,
            methods:'GET',
            responseType:'json'
          }).then(function (response) {
            console.log(response)
            that.title = response.data.title;
            that.summary = response.data.summary
          })
        }
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    
    </style>
    
    CoursesDetail
    

    Micro.vue

    <template>
      <div class="hello">
        <h2>欢迎报名学位课</h2>
      </div>
    </template>
    
    <script>
    export default {
      name: 'HelloWorld',
      data () {
        return {
          msg: 'Welcome to Your Vue.js App'
        }
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    h1, h2 {
      font-weight: normal;
    }
    ul {
      list-style-type: none;
      padding: 0;
    }
    li {
      display: inline-block;
      margin: 0 10px;
    }
    a {
      color: #42b983;
    }
    </style>
    
    Micro.vue
    

    News.vue

    <template>
      <div class="hello">
       <h2>深科技</h2>
      </div>
    </template>
    
    <script>
    export default {
      name: 'HelloWorld',
      data () {
        return {
          msg: 'Welcome to Your Vue.js App'
        }
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    h1, h2 {
      font-weight: normal;
    }
    ul {
      list-style-type: none;
      padding: 0;
    }
    li {
      display: inline-block;
      margin: 0 10px;
    }
    a {
      color: #42b983;
    }
    </style>
    
    News.vue
    

    NotFound.vue

    <template>
      <div class="hello">
     <h1>找不到页面</h1>
      </div>
    </template>
    
    <script>
    export default {
      name: 'HelloWorld',
      data () {
        return {
          msg: 'Welcome to Your Vue.js App'
        }
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    h1, h2 {
      font-weight: normal;
    }
    ul {
      list-style-type: none;
      padding: 0;
    }
    li {
      display: inline-block;
      margin: 0 10px;
    }
    a {
      color: #42b983;
    }
    </style>
    
    NotFound
    

    保存全局使用的变量store
    store.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    import Cookie from 'vue-cookies'
    
    Vue.use(Vuex)
    
    
    export default new Vuex.Store({
      //组件中通过this.$store.state.username 调用
      state:{
        username:Cookie.get('username'),
        token:Cookie.get('token')
      },
      mutations:{
        //组件中通过this.$store.commit(参数)调用
        saveToken:function (state,data) {  //存放用户名和token的函数
          state.username = data.username   //data代指从后端返回过来的数据
          state.token = data.token
          Cookie.set('username',data.username,'20min')   //吧用户名和token存放到cookie中
          Cookie.set('token',data.token,'20min')
        },
        //清空token和cookie
        clearToken:function (state) {
          state.username=null
          state.token= null
          Cookie.remove('username')
          Cookie.remove('token')
        }
      }
    })
    
    store.js
    

    后台代码
    urls.py

    """day145vue和restful配合 URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/1.11/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.conf.urls import url, include
        2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
    """
    from django.conf.urls import url
    from django.contrib import admin
    from api import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^login/', views.LoginView.as_view()),
        url(r'^course/$', views.CourseView.as_view()),
        url(r'^course/(?P<pk>d+).(?P<format>[a-z-9]+)$', views.CourseView.as_view()),
    ]
    
    urls.py
    

    views.py

    from django.shortcuts import render,HttpResponse
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from django.http import JsonResponse
    
    
    class LoginView(APIView):
    
        def get(self,request,*args,**kwargs):
            ret = {
                'code':111,
                'data':'在知识的海洋里一路向前'
            }
    
            response =  JsonResponse(ret)
            response['Access-Control-Allow-Origin']='*'
            return response
    
        def post(self,request,*args,**kwargs):
            print(request.body)  #在body里面有值
            print(request.POST)   #在post里面是没有值的
            ret = {
                'code':1000,
                'username':'haiyn',
                'token':'sdswr3fdfsdfdxqw2fgh',
            }
            response = JsonResponse(ret)
            response['Access-Control-Allow-Origin'] = "*"
            return response
    
        def options(self, request, *args, **kwargs):
            response = HttpResponse()
            response['Access-Control-Allow-Origin'] = '*'
            response['Access-Control-Allow-Headers'] = '*'
            # response['Access-Control-Allo w-Methods'] = 'PUT'
            return response
    
    
    class CourseView(APIView):
        def get(self,request,*args,**kwargs):
            print(args,kwargs)
            pk = kwargs.get('pk')
            if pk:
                print(kwargs.get('pk'))
                ret = {
                    'title': "标题标题标题",
                    'summary': '老师,太饿了。怎么还不下课'
                }
            else:
                ret = {
                    'code':1000,
                    'courseList':[
                        {'name':'人生苦短,来学Python','id':1},
                        {'name':'32天学会java,欢迎报名','id':2},
                        {'name':'人工智能即将统领世界...','id':3},
                    ]
                }
            response= JsonResponse(ret)
            response['Access-Control-Allow-Origin'] = '*'
            return response
    
    views.py
    
     
  • 相关阅读:
    lr中读写文件操作代码(原创)
    loadrunner中常用函数
    25岁综合焦虑症
    如果我是你的女朋友。。。看到了自己!哈哈
    web_reg_save_param 和关联的使用(原创)
    awk 的使用转自oracle.com
    去掉thinktime查看响应时间的方法
    vi 的使用方法
    ejs include助手没有处理BOM头的解决
    Nodejs, MemCacheD 在实际项目中的使用
  • 原文地址:https://www.cnblogs.com/hongdoudou/p/12675676.html
Copyright © 2011-2022 走看看