Vue+restfulframework示例
一、简单回顾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、写路由
- import Vue from 'vue'
- import Router from 'vue-router'
- import Index from '@/components/Index'
- import Login from '@/components/Login'
- import Course from '@/components/Course'
- import Micro from '@/components/Micro'
- import News from '@/components/News'
- import CourseDetail from '@/components/CourseDetail'
- import NotFound from '@/components/NotFound'
- Vue.use(Router)
- export default new Router({
- routes: [
- {
- path: '/',
- name: 'index',
- component: Index
- },
- {
- path: '/index',
- name: 'index',
- component: Index
- },
- {
- path: '/course',
- name: 'course',
- component: Course
- },
- {
- path: '/course-detail/:id/',
- name: 'courseDetail',
- component: CourseDetail
- },
- {
- path: '/micro',
- name: 'micro',
- component: Micro
- },
- {
- path: '/news',
- name: 'news',
- component: News
- },
- {
- path: '/login',
- name: 'login',
- component: Login
- },
- {
- path: '*',
- component: NotFound
- }
- ],
- mode: 'history'
- })
- # 定义路由
- {
- path: '/course-detail/:id/',
- name: 'courseDetail',
- component: CourseDetail
- },
- {
- path: '/login',
- name: 'login',
- component: Login
- },
- {
- path: '*',
- component: NotFound
- }
- # router-link参数
- <router-link :to="{'path':'/course-detail/'+item.id }">{{item.name}}</router-link>
- <router-link to="/index">首页</router-link>
- # 获取传过来的参数
- this.$route.params.id
- # 重定向
- this.$router.push('/index')
注意:
如果不想在url显示#,可以在路由里面加上这样一个参数
- mode: 'history'
5、写组件
- <template>
- <div>
- <h1>登录页面</h1>
- <div>
- <input type="text" v-model="username" placeholder="用户名">
- <input type="text" v-model="password" placeholder="密码">
- <a @click="doLogin">提交</a>
- </div>
- </div>
- </template>
- <script>
- export default {
- # 定义局部字段
- data () {
- return {
- username: '',
- password: ''
- }
- },
- # 加载时执行
- mounted:function(){
- },
- # 定义局部方法
- 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)
- // 找到全局变量,把用户名和token赋值到其中。
- that.$store.commit('saveToken',response.data)
- // 重定向到index
- that.$router.push('/index')
- })
- }
- }
- }
- </script>
- <!-- Add "scoped" attribute to limit CSS to this component only -->
- <style scoped>
- </style>
6、发送ajax请求:axios
- #发送ajax请求需要安装axios组件
- npm install axios
- npm install axios
- main.js
- import Vue from 'vue'
- import App from './App'
- import router from './router'
- import axios from 'axios'
- Vue.prototype.$axios = axios
- Vue.config.productionTip = false
- ...
- 组件使用:
- 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.$router.push('/index')
- })
- PS:重定向 that.$router.push('/index')
7、vuex:保存所有组件共用的变量
- 安装
- npm install vuex
如果想用vuex需要做这么几件事:
- a、先创建一个文件夹,store----store.js
- b、要先使用就先导入
- c、实例化一个对象,并且让别人可以用
- d、这样每一个组件都可以用username和token了
- npm install vuex
- main.js
- 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/>'
- })
- 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')
- }
- }
- })
8、vue-cookies:操作cookie
- 安装
- npm install vue-cookies
- npm install vue-cookies
- Cookie.get('username')
- Cookie.set('username', data.username, '20min')
- Cookie.remove('username')
- src/store/store.js
- import Vue from 'vue'
- import Vuex from 'vuex'
- import Cookie from 'vue-cookies' # vue-cookies
- Vue.use(Vuex)
- export default new Vuex.Store({
- // 组件中通过 this.$store.state.username 调用
- state: {
- username: Cookie.get('username'), # vue-cookies
- token: Cookie.get('token') # vue-cookies
- },
- mutations: {
- // 组件中通过 this.$store.commit(参数) 调用
- saveToken: function (state, data) {
- state.username = data.username
- state.token = data.token
- Cookie.set('username', data.username, '20min') # vue-cookies
- Cookie.set('token', data.token, '20min')
- },
- clearToken: function (state) {
- state.username = null
- state.token = null
- Cookie.remove('username') # vue-cookies
- Cookie.remove('token')
- }
- }
- })
三、代码实现
前端代码:
- <!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>
index.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/>'
- })
main.js
- <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>
app.vue
- 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'
- })
router ---index.js
组件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>
Index.vue
- <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>
Login.vue
- <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>
course.vue
- <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>
CoursesDetail
- <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>
Micro.vue
- <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>
News.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>
NotFound
保存全局使用的变量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')
- }
- }
- })
store.js
后端代码:
- """day145vue和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()),
- ]
urls.py
- 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':'haiyn',
- '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
views.py
Vue+restfulframework示例的更多相关文章
- Vue 项目 Vue + restfulframework
Vue 项目 Vue + restfulframework 实现登录认证 - django views class MyResponse(): def __init__(self): self.sta ...
- Vue 1-- ES6 快速入门、vue的基本语法、vue应用示例,vue基础语法
一.ES6快速入门 let和const let ES6新增了let命令,用于声明变量.其用法类似var,但是声明的变量只在let命令所在的代码块内有效. { let x = 10; var y = 2 ...
- Vue(1)- es6的语法、vue的基本语法、vue应用示例,vue基础语法
一.es6的语法 1.let与var的区别 ES6 新增了let命令,用来声明变量.它的用法类似于var(ES5),但是所声明的变量,只在let命令所在的代码块内有效.如下代码: { let a = ...
- python 之CORS,VUE+rest_framework示例
一.跨域 浏览器的同源策略 ----对ajax请求进行阻拦 ----对href属性读不阻拦 xhr=new XML ...
- Vue.js示例:GitHub提交(watch数据,created钩子,filters过滤); 网格组件(功能:1.检索,2排序);
GitHub提交 codePen: https://codepen.io/chentianwei411/pen/wEVPZo 注意:频繁看案例,可能会被限制. 重点: 表单输入绑定, 单选按钮的使 ...
- Django rest framework + Vue简单示例
构建vue项目参考这篇文章https://segmentfault.com/a/1190000008049815 一.创建Vue项目 修改源:npm config set registry https ...
- VUE购物车示例
代码下载地址:https://github.com/MengFangui/VueShoppingCart 1.index.html <!DOCTYPE html> <html lan ...
- webAPP如何实现移动端拍照上传(Vue组件示例)?
摘要:使用HTML5编写移动Web应用,主要是为了尝试一下“一套代码多处运行”,一个webapp几乎可以不加修改的运行在PC/Android/iOS等上面运行.但是写到现在觉得虽然这种方式弊大于利,不 ...
- Vue.js示例:树型视图; 模式组件;
树型图 本示例是一个简单的树形视图实现,它展现了组件的递归使用. mycode pen:https://codepen.io/chentianwei411/pen/KGKQxE 重点:递归是如何形成的 ...
随机推荐
- UOJ #30【CF Round #278】Tourists
求从$ x$走到$ y$的路径上可能经过的最小点权,带修改 UOJ #30 $ Solution:$ 如果两个点经过了某个连通分量,一定可以走到这个连通分量的最小值 直接构建圆方树,圆点存原点的点权 ...
- Redis 深度历险
学习资料 https://juejin.im/book/5afc2e5f6fb9a07a9b362527 包括下面几方面的内容 基础 应用 原理 集群 拓展 源码 to be done
- 使用jQuery重置(reset)表单的方法
由于JQuery中,提交表单是像下面这样的: 代码如下: $('#yigeform').submit() 所以,想当然的认为,重置表单,当然就是像下面这样子喽: 代码如下: $('#yigeform' ...
- 【编程拾遗】C++的static成员函数与单例模式
static小结 static的引入 static 是C++中非经常常使用的修饰符,它被用来控制变量的存储方式和可见性. 函数内部定义的变量,在程序运行到它的定义处时,编译器为它在栈上分配空间,函数在 ...
- Navicat for MySQL 12中文版 破解流程
1.下载 Keygen_Patch 软件 下载地址 pass: saxz 2.启动 Keygen_Patch 软件 3.提示破解成功了,先别着急 4.运行 Navica 软件,输入注册码 5.断网 ...
- 目标检测----ImageAI使用
1.开源项目 github地址 https://github.com/OlafenwaMoses/ImageAI 2.目标检测(Object Detection)入门概要 3.Pycharm中无法 ...
- [Kubernetes]如何使用yaml文件使得可以向外暴露服务
最近因为项目需要上线,所以这段时间都扑到了Kubernetes上面. 昨天老大交代了一个任务,大概就是这样的: 看起来挺简单的,因为相关文件都给我了,我以为直接把文件拖上去,然后在访问ip:port方 ...
- [Harbor]Docker登录Harbor仓库(HTTP方式)
Docker登录到Harbor仓库时,不管是使用http协议还是使用https协议,都需要修改一些配置. 这篇文章来介绍一下,在使用http协议时,需要进行什么哪些配置. 首先,确定自己的Harbor ...
- Path Sum I && II & III
Path Sum I Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that ad ...
- python 字典不区分大小写工具类
# -*- coding: utf-8 -*- # @Time : 2018/12/20 4:28 PM # @Author : cxa # @File : DictHelper.py # @Soft ...