一、vue
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、寫路由
1 import Vue from 'vue' 2 import Router from 'vue-router' 3 import Index from '@/components/Index' 4 import Login from '@/components/Login' 5 import Course from '@/components/Course' 6 import Micro from '@/components/Micro' 7 import News from '@/components/News' 8 import CourseDetail from '@/components/CourseDetail' 9 import NotFound from '@/components/NotFound' 10 11 Vue.use(Router) 12 13 export default new Router({ 14 routes: [ 15 { 16 path: '/', 17 name: 'index', 18 component: Index 19 }, 20 { 21 path: '/index', 22 name: 'index', 23 component: Index 24 }, 25 { 26 path: '/course', 27 name: 'course', 28 component: Course 29 }, 30 { 31 path: '/course-detail/:id/', 32 name: 'courseDetail', 33 component: CourseDetail 34 }, 35 { 36 path: '/micro', 37 name: 'micro', 38 component: Micro 39 }, 40 { 41 path: '/news', 42 name: 'news', 43 component: News 44 }, 45 { 46 path: '/login', 47 name: 'login', 48 component: Login 49 }, 50 { 51 path: '*', 52 component: NotFound 53 } 54 ], 55 mode: 'history' 56 })
1 # 定義路由 2 { 3 path: '/course-detail/:id/', 4 name: 'courseDetail', 5 component: CourseDetail 6 }, 7 { 8 path: '/login', 9 name: 'login', 10 component: Login 11 }, 12 { 13 path: '*', 14 component: NotFound 15 } 16 17 18 # router-link參數 19 <router-link :to="{'path':'/course-detail/'+item.id }">{{item.name}}</router-link> 20 <router-link to="/index">首頁</router-link> 21 22 # 獲取傳過來的參數 23 this.$route.params.id 24 # 重定向 25 this.$router.push('/index') 26
注意:

如果不想在url顯示#,可以在路由里面加上這樣一個參數
mode: 'history'
5、寫組件
1 <template> 2 3 <div> 4 <h1>登錄頁面</h1> 5 <div> 6 <input type="text" v-model="username" placeholder="用戶名"> 7 <input type="text" v-model="password" placeholder="密碼"> 8 <a @click="doLogin">提交</a> 9 </div> 10 </div> 11 </template> 12 13 <script> 14 15 export default { 16 # 定義局部字段 17 data () { 18 return { 19 username: '', 20 password: '' 21 } 22 }, 23 # 加載時執行 24 mounted:function(){ 25 }, 26 # 定義局部方法 27 methods:{ 28 doLogin() { 29 var that = this 30 this.$axios.request({ 31 url: 'http://127.0.0.1:8000/login/', 32 method: 'POST', 33 data: { 34 username: this.username, 35 password: this.password 36 }, 37 responseType: 'json' 38 }).then(function (response) { 39 console.log(response.data) 40 // 找到全局變量,把用戶名和token賦值到其中。 41 that.$store.commit('saveToken',response.data) 42 // 重定向到index 43 that.$router.push('/index') 44 }) 45 } 46 } 47 } 48 </script> 49 50 <!-- Add "scoped" attribute to limit CSS to this component only --> 51 <style scoped> 52 53 </style>
6、發送ajax請求:axios
#發送ajax請求需要安裝axios組件
npm install axios
1 npm install axios 2 3 main.js 4 import Vue from 'vue' 5 import App from './App' 6 import router from './router' 7 8 import axios from 'axios' 9 10 Vue.prototype.$axios = axios 11 12 Vue.config.productionTip = false 13 ... 14 15 組件使用: 16 this.$axios.request({ 17 url: 'http://127.0.0.1:8000/login/', 18 method: 'POST', 19 data: { 20 username: this.username, 21 password: this.password 22 }, 23 responseType: 'json' 24 }).then(function (response) { 25 console.log(response.data) 26 27 that.$router.push('/index') 28 }) 29 30 PS:重定向 that.$router.push('/index')
7、vuex:保存所有組件共用的變量
安裝
npm install vuex
如果想用vuex需要做這么幾件事:
- a、先創建一個文件夾,store----store.js
- b、要先使用就先導入
- c、實例化一個對象,並且讓別人可以用
- d、這樣每一個組件都可以用username和token了
1 npm install vuex 2 3 main.js 4 import Vue from 'vue' 5 import App from './App' 6 import router from './router' 7 import axios from 'axios' 8 9 import store from './store/store' # vuex 10 11 Vue.prototype.$axios = axios 12 13 Vue.config.productionTip = false 14 15 /* eslint-disable no-new */ 16 new Vue({ 17 el: '#app', 18 store, # vuex 19 router, 20 components: { App }, 21 template: '<App/>' 22 }) 23 24 src/store/store.js 25 import Vue from 'vue' 26 import Vuex from 'vuex' 27 import Cookie from 'vue-cookies' 28 29 Vue.use(Vuex) 30 31 export default new Vuex.Store({ 32 // 組件中通過 this.$store.state.username 調用 33 state: { 34 username: Cookie.get('username'), 35 token: Cookie.get('token') 36 }, 37 mutations: { 38 // 組件中通過 this.$store.commit(參數) 調用 39 saveToken: function (state, data) { 40 state.username = data.username 41 state.token = data.token 42 Cookie.set('username', data.username, '20min') 43 Cookie.set('token', data.token, '20min') 44 45 }, 46 clearToken: function (state) { 47 state.username = null 48 state.token = null 49 Cookie.remove('username') 50 Cookie.remove('token') 51 } 52 } 53 })
8、vue-cookies:操作cookie
安裝
npm install vue-cookies
1 npm install vue-cookies 2 3 4 Cookie.get('username') 5 6 Cookie.set('username', data.username, '20min') 7 Cookie.remove('username') 8 9 10 src/store/store.js 11 import Vue from 'vue' 12 import Vuex from 'vuex' 13 import Cookie from 'vue-cookies' # vue-cookies 14 15 Vue.use(Vuex) 16 17 export default new Vuex.Store({ 18 // 組件中通過 this.$store.state.username 調用 19 state: { 20 username: Cookie.get('username'), # vue-cookies 21 token: Cookie.get('token') # vue-cookies 22 }, 23 mutations: { 24 // 組件中通過 this.$store.commit(參數) 調用 25 saveToken: function (state, data) { 26 state.username = data.username 27 state.token = data.token 28 Cookie.set('username', data.username, '20min') # vue-cookies 29 Cookie.set('token', data.token, '20min') 30 31 }, 32 clearToken: function (state) { 33 state.username = null 34 state.token = null 35 Cookie.remove('username') # vue-cookies 36 Cookie.remove('token') 37 } 38 } 39 })
三、代碼實現
前端代碼:
<!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>
// 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/>' })
<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>
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'
})
組件components
<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>
<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>
<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>
<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>
<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>
<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>
<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>
保存全局使用的變量store
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')
}
}
})
后端代碼:
"""vue和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()), ]
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':'hc', '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
