zoukankan      html  css  js  c++  java
  • 前后端分离,Vue+restfullframework

     一、准备

    修改源:
        npm config set registry https://registry.npm.taobao.org 
    
    创建脚手架:
        vue init webpack Vue项目名称
        #Install vue-router? Yes
    插件:
       npm install axios axios,发送Ajax请求 vuex,保存所有组件共用的变量 vue
    -cookies,操作cookie

    二、流程

    1、创建脚手架

    npm config set registry https://registry.npm.taobao.org
    vue init webpack
    #吧route的那一个设置为yes,其他的设置为no

    2、启动Vue

    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 })
    View Code
     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                 
    View Code

    注意:

    如果不想在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>
    View Code

    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')
    View Code

    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 })
    View Code

    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 })
    View Code

    三、代码实现

     前端代码:

     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>
    index.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 })
    main.js
     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>
    app.vue
     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 })
    router ---index.js

    组件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>
    Index.vue
     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>
    Login.vue
     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>
    course.vue
     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>
    CoursesDetail
     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>
    Micro.vue
     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>
    News.vue
     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>
    NotFound

    保存全局使用的变量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 })
    store.js

    后端代码:

     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 ]
    urls.py
     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
    views.py
  • 相关阅读:
    删除文件时,提示 "操作无法完成..." 怎么处理
    对象的理解
    TP5架构下链接SQL数据库的一种方法
    关于URL隐藏index.php方法
    非典型的千万用户后台之路
    就这样,再见2015
    理想的程序员
    4个小例子告诉你:如何成为一名数据极客
    馆中窥职:小公司没那么糟糕
    JAVA设计模式详解(六)----------状态模式
  • 原文地址:https://www.cnblogs.com/zhangningyang/p/8447305.html
Copyright © 2011-2022 走看看