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
  • 相关阅读:
    leetcode 279. Perfect Squares
    leetcode 546. Remove Boxes
    leetcode 312. Burst Balloons
    leetcode 160. Intersection of Two Linked Lists
    leetcode 55. Jump Game
    剑指offer 滑动窗口的最大值
    剑指offer 剪绳子
    剑指offer 字符流中第一个不重复的字符
    leetcode 673. Number of Longest Increasing Subsequence
    leetcode 75. Sort Colors (荷兰三色旗问题)
  • 原文地址:https://www.cnblogs.com/zhangningyang/p/8447305.html
Copyright © 2011-2022 走看看