一、简单回顾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 })
三、代码实现
前端代码:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width,initial-scale=1.0"> 6 <link rel="stylesheet" href="./static/bootstrap-3.3.7-dist/css/bootstrap.css"> 7 <script src="./static/bootstrap-3.3.7-dist/js/bootstrap.js"></script> 8 9 <title>s6vue</title> 10 </head> 11 <body> 12 <div id="app"></div> 13 <!-- built files will be auto injected --> 14 </body> 15 </html>
1 // The Vue build version to load with the `import` command 2 // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 import Vue from 'vue' 4 import App from './App' 5 import router from './router' 6 import store from './store/store' // 7 import axios from 'axios' // 要是用axios,就得先导入 8 Vue.prototype.$axios = axios //注册,以后就可以用$axios来定义了 9 10 Vue.config.productionTip = false 11 12 /* eslint-disable no-new */ 13 new Vue({ 14 el: '#app', 15 store, 16 router, 17 components: { App }, 18 template: '<App/>' 19 })
1 <template> 2 <div id="app"> 3 <!--首页里面永远是固定的东西--> 4 <ul class="nav nav-tabs"> 5 <li><router-link to="/index">首页</router-link> <!--用于点击查看组件--></li> 6 <li><router-link to="/micro">学位课</router-link> <!--用于点击查看组件--></li> 7 <li><router-link to="/course">课程</router-link></li> <!--用于点击查看组件--> 8 <li><router-link to="/news">深科技</router-link></li> <!--用于点击查看组件--> 9 <!--如果已经登录了,就不用在登录了,在页面还是显示当前用户和注销,如果没有登录就显示登录--> 10 <li v-if="this.$store.state.username"> 11 <span><a>欢迎{{ this.$store.state.username }}登录</a></span> 12 <span><a @click="logout()">注销</a></span> 13 </li> 14 <li v-else=""> <router-link to="/login">登录</router-link></li> 15 </ul> 16 <router-view/> <!--组件显示的位置--> 17 </div> 18 </template> 19 20 <script> 21 export default { 22 name: 'App', 23 methods:{ 24 logout(){ 25 this.$store.state.username='' 26 this.$store.state.token='' 27 } 28 } 29 } 30 </script> 31 32 <style> 33 34 35 </style>
1 import Vue from 'vue' 2 import Router from 'vue-router' 3 import HelloWorld from '@/components/HelloWorld' 4 import Index from '@/components/Index' 5 import Login from '@/components/Login' 6 import Micro from '@/components/Micro' 7 import News from '@/components/News' 8 import Course from '@/components/Course' 9 import CourseDetail from '@/components/CourseDetail' 10 import NotFound from '@/components/NotFound' 11 12 13 14 Vue.use(Router) 15 16 export default new Router({ 17 routes: [ 18 { 19 path: '/', 20 name: 'HelloWorld', 21 component: HelloWorld 22 }, 23 { 24 path: '/index', 25 name: 'index', 26 component: Index 27 }, 28 { 29 path: '/login', 30 name: 'Login', 31 component: Login 32 }, 33 { 34 path: '/course', 35 name: 'Course', 36 component: Course 37 }, 38 { 39 path: '/course-detail/:id/', 40 name: 'CourseDetail', 41 component: CourseDetail 42 }, 43 { 44 path: '/micro/', 45 name: 'Micro', 46 component: Micro 47 }, 48 { 49 path: '/course-detail/:id/', 50 name: 'CourseDetail', 51 component: CourseDetail 52 }, 53 { 54 path: '/news/', 55 name: 'News', 56 component: News 57 }, 58 { 59 path: '*', 60 component: NotFound 61 } 62 ], 63 mode:'history' 64 })
组件components
1 <template> 2 <div class="hello"> 3 <h1>{{ msg }}</h1> 4 </div> 5 </template> 6 7 <script> 8 export default { 9 name: 'index', 10 data () { 11 return { 12 msg:"这里是首页" 13 } 14 } 15 } 16 </script> 17 18 <!-- Add "scoped" attribute to limit CSS to this component only --> 19 <style> 20 21 </style>
1 <template> 2 <div class=""> 3 <h2>登录页面</h2> 4 <p>用户名:<input type="text" placeholder="username" v-model="username"></p> 5 <p>密码:<input type="text" placeholder="password" v-model="password"></p> 6 <button><a @click="DoLogin()">提交</a></button> 7 </div> 8 </template> 9 10 <script> 11 export default { 12 name: 'index', 13 data () { 14 return { 15 username: "", 16 password: "" 17 } 18 }, 19 methods:{ 20 DoLogin (){ 21 var that = this 22 // console.log(this.$axios); 23 this.$axios.request({ //发送axios请求 24 url:'http://127.0.0.1:8082/login/', //请求路径 25 method:"POST",//请求方式 26 data:{ //要发送 的数据 27 username:this.username, 28 password:this.password 29 }, 30 responseType:'json' //期望返回的类型是json的格式 31 }).then(function (response) { //吧返回的结果交给回调函数处理 32 //登录成功之后,找到全局变量,吧用户名和token赋值到其中 33 that.$store.commit('saveToken',response.data); 34 //重定向(登录成功之后让跳转到index页面) 35 that.$router.push('/index') 36 //为什么不直接用this呢?这里的this代表的是$axios,用that他代指的是整个Vue对象 37 }) 38 } 39 } 40 41 } 42 </script> 43 44 <!-- Add "scoped" attribute to limit CSS to this component only --> 45 <style> 46 47 </style>
1 <template> 2 <div class=""> 3 <ul> 4 <li v-for="item in courseList"> 5 <router-link :to="{'path':'/course-detail/'+item.id}">{{item.name}}</router-link> 6 </li> 7 </ul> 8 </div> 9 </template> 10 11 <script> 12 export default { 13 name: 'index', 14 data () { 15 return { 16 msg:'课程页面', 17 courseList:[] 18 } 19 }, 20 mounted:function () { 21 //当组件一加载的时候就应该去数据库去获取数据 22 this.initCourses() 23 }, 24 methods:{ 25 initCourses:function () { 26 var that = this 27 this.$axios.request({ 28 url:'http://127.0.0.1:8082/course/', 29 method:"GET" 30 }).then(function (response) { 31 console.log(response); 32 that.courseList = response.data.courseList //吧从数据库取的数据赋值到courseList列表里面 33 }) 34 } 35 } 36 37 } 38 39 </script> 40 41 <!-- Add "scoped" attribute to limit CSS to this component only --> 42 <style> 43 44 </style>
1 <template> 2 <div class="hello"> 3 <div>课程详细</div> 4 <h3>{{ title }}</h3> 5 <h3>{{ summary }}</h3> 6 </div> 7 </template> 8 9 <script> 10 export default { 11 name: 'HelloWorld', 12 data () { 13 return { 14 title:'', 15 summary:'' 16 } 17 }, 18 mounted:function () { 19 //当组件一加载就执行的函数 20 this.initCoursesDetail() 21 }, 22 methods:{ 23 initCoursesDetail(){ 24 var nid = this.$route.params.id //获取id 25 var that = this 26 var url = 'http://127.0.0.1:8082/course/' + nid + '.json' 27 this.$axios.request({ 28 url:url, 29 methods:'GET', 30 responseType:'json' 31 }).then(function (response) { 32 console.log(response) 33 that.title = response.data.title; 34 that.summary = response.data.summary 35 }) 36 } 37 } 38 } 39 </script> 40 41 <!-- Add "scoped" attribute to limit CSS to this component only --> 42 <style scoped> 43 44 </style>
1 <template> 2 <div class="hello"> 3 <h2>欢迎报名学位课</h2> 4 </div> 5 </template> 6 7 <script> 8 export default { 9 name: 'HelloWorld', 10 data () { 11 return { 12 msg: 'Welcome to Your Vue.js App' 13 } 14 } 15 } 16 </script> 17 18 <!-- Add "scoped" attribute to limit CSS to this component only --> 19 <style scoped> 20 h1, h2 { 21 font-weight: normal; 22 } 23 ul { 24 list-style-type: none; 25 padding: 0; 26 } 27 li { 28 display: inline-block; 29 margin: 0 10px; 30 } 31 a { 32 color: #42b983; 33 } 34 </style>
1 <template> 2 <div class="hello"> 3 <h2>深科技</h2> 4 </div> 5 </template> 6 7 <script> 8 export default { 9 name: 'HelloWorld', 10 data () { 11 return { 12 msg: 'Welcome to Your Vue.js App' 13 } 14 } 15 } 16 </script> 17 18 <!-- Add "scoped" attribute to limit CSS to this component only --> 19 <style scoped> 20 h1, h2 { 21 font-weight: normal; 22 } 23 ul { 24 list-style-type: none; 25 padding: 0; 26 } 27 li { 28 display: inline-block; 29 margin: 0 10px; 30 } 31 a { 32 color: #42b983; 33 } 34 </style>
1 <template> 2 <div class="hello"> 3 <h1>找不到页面</h1> 4 </div> 5 </template> 6 7 <script> 8 export default { 9 name: 'HelloWorld', 10 data () { 11 return { 12 msg: 'Welcome to Your Vue.js App' 13 } 14 } 15 } 16 </script> 17 18 <!-- Add "scoped" attribute to limit CSS to this component only --> 19 <style scoped> 20 h1, h2 { 21 font-weight: normal; 22 } 23 ul { 24 list-style-type: none; 25 padding: 0; 26 } 27 li { 28 display: inline-block; 29 margin: 0 10px; 30 } 31 a { 32 color: #42b983; 33 } 34 </style>
保存全局使用的变量store
1 import Vue from 'vue' 2 import Vuex from 'vuex' 3 import Cookie from 'vue-cookies' 4 5 Vue.use(Vuex) 6 7 8 export default new Vuex.Store({ 9 //组件中通过this.$store.state.username 调用 10 state:{ 11 username:Cookie.get('username'), 12 token:Cookie.get('token') 13 }, 14 mutations:{ 15 //组件中通过this.$store.commit(参数)调用 16 saveToken:function (state,data) { //存放用户名和token的函数 17 state.username = data.username //data代指从后端返回过来的数据 18 state.token = data.token 19 Cookie.set('username',data.username,'20min') //吧用户名和token存放到cookie中 20 Cookie.set('token',data.token,'20min') 21 }, 22 //清空token和cookie 23 clearToken:function (state) { 24 state.username=null 25 state.token= null 26 Cookie.remove('username') 27 Cookie.remove('token') 28 } 29 } 30 })
后端代码:
1 """day145vue和restful配合 URL Configuration 2 3 The `urlpatterns` list routes URLs to views. For more information please see: 4 https://docs.djangoproject.com/en/1.11/topics/http/urls/ 5 Examples: 6 Function views 7 1. Add an import: from my_app import views 8 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 Class-based views 10 1. Add an import: from other_app.views import Home 11 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 Including another URLconf 13 1. Import the include() function: from django.conf.urls import url, include 14 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 15 """ 16 from django.conf.urls import url 17 from django.contrib import admin 18 from api import views 19 urlpatterns = [ 20 url(r'^admin/', admin.site.urls), 21 url(r'^login/', views.LoginView.as_view()), 22 url(r'^course/$', views.CourseView.as_view()), 23 url(r'^course/(?P<pk>\d+)\.(?P<format>[a-z-9]+)$', views.CourseView.as_view()), 24 ]
1 from django.shortcuts import render,HttpResponse 2 from rest_framework.views import APIView 3 from rest_framework.response import Response 4 from django.http import JsonResponse 5 6 7 class LoginView(APIView): 8 9 def get(self,request,*args,**kwargs): 10 ret = { 11 'code':111, 12 'data':'在知识的海洋里一路向前' 13 } 14 15 response = JsonResponse(ret) 16 response['Access-Control-Allow-Origin']='*' 17 return response 18 19 def post(self,request,*args,**kwargs): 20 print(request.body) #在body里面有值 21 print(request.POST) #在post里面是没有值的 22 ret = { 23 'code':1000, 24 'username':'haiyn', 25 'token':'sdswr3fdfsdfdxqw2fgh', 26 } 27 response = JsonResponse(ret) 28 response['Access-Control-Allow-Origin'] = "*" 29 return response 30 31 def options(self, request, *args, **kwargs): 32 response = HttpResponse() 33 response['Access-Control-Allow-Origin'] = '*' 34 response['Access-Control-Allow-Headers'] = '*' 35 # response['Access-Control-Allo w-Methods'] = 'PUT' 36 return response 37 38 39 class CourseView(APIView): 40 def get(self,request,*args,**kwargs): 41 print(args,kwargs) 42 pk = kwargs.get('pk') 43 if pk: 44 print(kwargs.get('pk')) 45 ret = { 46 'title': "标题标题标题", 47 'summary': '老师,太饿了。怎么还不下课' 48 } 49 else: 50 ret = { 51 'code':1000, 52 'courseList':[ 53 {'name':'人生苦短,来学Python','id':1}, 54 {'name':'32天学会java,欢迎报名','id':2}, 55 {'name':'人工智能即将统领世界...','id':3}, 56 ] 57 } 58 response= JsonResponse(ret) 59 response['Access-Control-Allow-Origin'] = '*' 60 return response