zoukankan      html  css  js  c++  java
  • Django rest framework + Vue简单示例

    构建vue项目参考这篇文章https://segmentfault.com/a/1190000008049815

    一、创建Vue项目

    修改源:npm config set registry https://registry.npm.taobao.org         (建议修改)

    创建脚手架:vue init webpack Vue项目名称

    基本插件:

    axios,发送Ajax请求
    vuex,保存所有组件共用的变量
    vue-cookies,操作cookie

    二、流程

    vue项目基本目录结构

    1.创建脚手架

    vue init webpack Vue项目名称

    运行 npm run dev 

    2.App.Vue中

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

    3.写路由

    写在route/index.js中

    import Vue from 'vue'
    import Router from 'vue-router'
    import HelloWorld from '@/components/HelloWorld'
    import index from '@/components/Index'
    import Cource from '@/components/Cource'
    import Xw from '@/components/Xw'
    import Login from '@/components/Login'
    import CourseDetail from '@/components/CourseDetail'
    
    
    
    Vue.use(Router);
    
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'HelloWorld',
          component: HelloWorld
        },
        {
          path: '/index',
          name: 'index',
          component: index
        },
        {
          path: '/cource',
          name: 'Cource',
          component: Cource
        },
        {
          path: '/xw',
          name: 'Xw',
          component: Xw
        },
        {
          path: '/login',
          name: 'Login',
          component: Login
        },
         {
          path: '/course-detail/:id/',
          name: 'CourseDetail',
          component: CourseDetail
        }
      ],
      mode: 'history'
    })
    index.js

    注意:

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

    如果想url中想传参:

     {
          path: '/course-detail/:id/',
          name: 'CourseDetail',
          component: CourseDetail
        }

    4.写组件

    组件写在src/components下

    <template>
      <div class="hello">
       <h1>登录</h1>
        <input type="text"  v-model="username"><br>
        <input type="text"   v-model="password"><br>
        <a type="button" @click="doLogin">提交</a>
      </div>
    </template>
    
    <script>
    export default {
      name: 'HelloWorld',
      data () {
        return {
          username: '',
          password:'',
        }
      },
      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);
            that.$store.commit('saveToken',response.data);
            // 重定向到index
            that.$router.push('/index')
          })
    
        }
      }
    }
    </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>
    View Code

    5.类似与ajax的请求ajax请求:axios

    下载:npm install axios

    首先必须在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 axios from 'axios'
    import store from './store/store'
    
    Vue.prototype.$axios = axios;
    
    Vue.config.productionTip = false;
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      store,
      router,
      components: { App },
      template: '<App/>'
    });
    main.js
    import axios from 'axios'                
    Vue.prototype.$axios = axios

    使用:

    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);
            that.$store.commit('saveToken',response.data);
            // 重定向到index
            that.$router.push('/index')
          })
    
        }
      }

    重定向: that.$router.push('/index')

    6.vuex的使用

    下载:npm install vuex 

    1.在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')
        }
      }
    })
    store.js

    2.在main.js中导入store

    // 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 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/>'
    });
    main.js

    7.vue-cookies 的使用

    下载:npm install vue-cookies 

    cookie的使用:

    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')
        }
      }
    })
    store.js

    8.router-link参数的常见用法

    <router-link :to="{'path':'/course-detail/'+item.id }"{{item.name}}</router-link>
    <router-link to="/index">首页</router-link>

    9. 获取传过来的参数

    this.$route.params.id

    10.重定向

    this.$router.push('/index')

    示例:

    前端vue部分:

    点击查看组件

    <template>
      <div id="app">
        <router-link to="/index">首页</router-link>
        <router-link to="/cource">课程</router-link>
        <router-link to="/xw">学位</router-link>
        <div>
              <div v-if="this.$store.state.username">
              <a>{{ this.$store.state.username }}</a>
              <a @click="logout">注销</a>
              </div>
              <router-link v-else to="/login">登录</router-link>
            </div>
        <router-view/>
      </div>
    </template>
    
    <script>
    export default {
      name: 'App',
      methods:{
        logout(){
          this.$store.state.username = '';
          this.$store.state.token = ''
        }
      }
    }
    </script>
    
    <style>
    /*#app {*/
      /*font-family: 'Avenir', Helvetica, Arial, sans-serif;*/
      /*-webkit-font-smoothing: antialiased;*/
      /*-moz-osx-font-smoothing: grayscale;*/
      /*text-align: center;*/
      /*color: #2c3e50;*/
      /*margin-top: 60px;*/
    /*}*/
    </style>
    App.vue

    组件

    <template>
      <div class="hello">
       <h1>登录</h1>
        <input type="text"  v-model="username"><br>
        <input type="text"   v-model="password"><br>
        <a type="button" @click="doLogin">提交</a>
      </div>
    </template>
    
    <script>
    export default {
      name: 'HelloWorld',
      data () {
        return {
          username: '',
          password:'',
        }
      },
      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);
            that.$store.commit('saveToken',response.data);
            // 重定向到index
            that.$router.push('/index')
          })
    
        }
      }
    }
    </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>
    Login.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>
    index.vue
    <template>
      <div class="hello">
           <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: 'HelloWorld',
      data () {
        return {
          courseList: ''
        }
      },
      mounted:function () {
         this.initCourses()
      },
       methods: {
        initCourses:function () {
          var that = this;
          this.$axios.request({
            url: 'http://127.0.0.1:8000/courses/',
            method: 'GET'
          }).then(function (response) {
            that.courseList = response.data.courseList
          })
        }
      }
    }
    </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>
    Cource.vue
    <template>
      <div>
          <div>课程详细</div>
          <h1>{{title}}</h1>
          <h1>{{summary}}</h1>
    
      </div>
    </template>
    
    <script>
    export default {
      data () {
        return {
          title:'',
          summary:'',
        }
      },
      mounted:function () {
        this.initCourseDetail()
      },
      methods:{
        initCourseDetail (){
          var nid = this.$route.params.id;
          var that = this;
          var url = 'http://127.0.0.1:8000/courses/' + nid+'.json';
          this.$axios.request({
            url: url,
            method:'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>
    CourceDetail.vue

    路由:

    import Vue from 'vue'
    import Router from 'vue-router'
    import HelloWorld from '@/components/HelloWorld'
    import index from '@/components/Index'
    import Cource from '@/components/Cource'
    import Xw from '@/components/Xw'
    import Login from '@/components/Login'
    import CourseDetail from '@/components/CourseDetail'
    
    
    
    Vue.use(Router);
    
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'HelloWorld',
          component: HelloWorld
        },
        {
          path: '/index',
          name: 'index',
          component: index
        },
        {
          path: '/cource',
          name: 'Cource',
          component: Cource
        },
        {
          path: '/xw',
          name: 'Xw',
          component: Xw
        },
        {
          path: '/login',
          name: 'Login',
          component: Login
        },
         {
          path: '/course-detail/:id/',
          name: 'CourseDetail',
          component: CourseDetail
        }
      ],
      mode: 'history'
    })
    index.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')
        }
      }
    })
    store.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 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/>'
    });
    main.js

    后端restframwork部分

    """luffyweb 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'^courses/$', views.CoursesView.as_view()),
        url(r'^courses/(?P<pk>d+).(?P<format>[a-z0-9]+)$', views.CoursesView.as_view()),
    ]
    urls
    from django.http import JsonResponse
    from django.shortcuts import render,HttpResponse
    from rest_framework.views import APIView
    
    # Create your views here.
    
    class LoginView(APIView):
        def get(self,request,*args,**kwargs):
            ret = {
                'code': 1000,
                'data': '老男孩'
            }
            response = JsonResponse(ret)
            response['Access-Control-Allow-Origin'] = "*"
            return response
    
        def post(self,request,*args,**kwargs):
    
            print(request.POST)
            ret = {
                'code':1000,
                'username':'老男孩',
                'token':'71ksdf7913knaksdasd7',
            }
            response = JsonResponse(ret)
            response['Access-Control-Allow-Origin'] = "*"
            return response
    
        def options(self, request, *args, **kwargs):
            # self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
            # self.set_header('Access-Control-Allow-Headers', "k1,k2")
            # self.set_header('Access-Control-Allow-Methods', "PUT,DELETE")
            # self.set_header('Access-Control-Max-Age', 10)
    
            response = HttpResponse()
            response['Access-Control-Allow-Origin'] = '*'
            response['Access-Control-Allow-Headers'] = '*'
            #response['Access-Control-Allow-Methods'] = 'PUT'
            return response
    
    class CoursesView(APIView):
        def get(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            if pk:
                ret = {
                    'title': "标题标题标题",
                    'summary': '老师,太饿了。怎么还不下课'
                }
            else:
                ret = {
                    'code': 1000,
                    'courseList': [
                        {"name": '21天学会Pytasdfhon', 'id': 1},
                        {"name": '23天学会Pytasdfhon', 'id': 2},
                        {"name": '24天学会Pytasdfhon', 'id': 3},
                    ]
                }
            response = JsonResponse(ret)
            response['Access-Control-Allow-Origin'] = "*"
            return response
    views
  • 相关阅读:
    [BAT]用BAT自作开机后自动启动截屏软件
    [TFS]如何彻底删除TFS上的团队项目
    [GIT]如何删除Git本地仓库
    [SQL] update select 查询的结果集
    [VS]反编译_DllToC#_REFLECTOR8.5
    Docker容器开机自动启动
    公告:开通csdn博客,敬请关注!
    1018 Public Bike Management
    微信红包算法
    LRU Cache
  • 原文地址:https://www.cnblogs.com/ctztake/p/8471997.html
Copyright © 2011-2022 走看看