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
    
     
  • 相关阅读:
    WPF 使用 Direct2D1 画图 绘制基本图形
    WPF 使用 Direct2D1 画图 绘制基本图形
    dot net core 使用 IPC 进程通信
    dot net core 使用 IPC 进程通信
    win2d 图片水印
    win2d 图片水印
    Java实现 LeetCode 240 搜索二维矩阵 II(二)
    PHP closedir() 函数
    PHP chroot() 函数
    PHP chdir() 函数
  • 原文地址:https://www.cnblogs.com/hongdoudou/p/12675676.html
Copyright © 2011-2022 走看看