Django rest framework + Vue簡單示例

構建vue項目參考這篇文章https://segmentfault.com/a/1190000008049815

1、建立Vue項目

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

建立腳手架:vue init webpack Vue項目名稱vue

基本插件:webpack

axios,發送Ajax請求
vuex,保存全部組件共用的變量
vue-cookies,操做cookieios

2、流程

vue項目基本目錄結構web

1.建立腳手架

vue init webpack Vue項目名稱ajax

運行 npm run dev vue-router

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

注意:vuex

咱們訪問的時候url通常會帶有‘#’,若是不想有,在路由後面加上  mode: 'history'npm

若是想url中想傳參:django

 { 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
相關文章
相關標籤/搜索