详细步骤
1 添加登录页面
步骤:
Header.vue 写一个登录按钮,
在路由的 index.js中添加这个 新的路由,{'path':'xx','name':'xx',component:xx}
新建这个 xx 组件。
最终,完成 点击这个按钮,这个按钮本质是 a标签,拿到跳转的url,根据路由,拿到组件,最终在
PS:
组件是一个 functional 组件,渲染路径匹配到的视图组件。 vue适合单页面。
Header.vue之前:
"/index">首页 "/course">课程 "/news">深科技
Header.vue 之后
"/index">首页 "/course">课程 "/news">深科技
"/login">登录
2 取到登录页面 input框 中数据
步骤
1 在template中写input框。
2 input框中加入v-model,实现表单和应用状态之间的双向绑定。
3 写一个
4 这个事件干啥呢,通过this.username,this.password 拿到input框中的数据。(双向绑定是这样做的基础)
组件 login.vue的代码
"text" name="username" placeholder="请输入用户名">姓名 "password" name="password" placeholder="请输入密码">密码 "button" @click="loginfunc" value="提交">
3 往后台发送数据
引入axios组件,涉及到跨域,用CORS解决。
PS:插件通常会为 Vue 添加全局功能。插件的范围没有限制——一般有下面几种。
添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
步骤:
1)在main.js中导入axios.
2)login.vue 利用this.$axios.request({ }) 往后台发送数据。
3)设计到跨域,可以一步解决。写一个中间件,因为解决跨域是在返回的消息上设置allow-header/method/origin/,所以中间件用到的方法是process_response。
4)后台,视图继承APIView,执行正常的逻辑。
在main.js中加入
import axios from 'axios' Vue.prototype.$axios = axios
login.vue
"text" v-model="username" placeholder="请输入用户名">姓名 "password" v-model="password" placeholder="请输入密码">密码 "button" @click="loginfunc" value="提交">
views.py
PS:
复杂请求和简单请求区别,在于请求方式 和 请求头ContentType。
from rest_framework.views import APIView from rest_framework.response import Response class AuthView(APIView): def options(self, request, *args, **kwargs): obj = Response() obj['Access-Control-Allow-Origin'] = '*' #允许的url obj['Access-Control-Allow-Headers'] = 'Content-Type' #允许的请求头 obj['Access-Control-Allow-Methods'] = '*' #允许的请求方式 return obj def post(self,request,*args,**kwargs): print(request.data) return Response('111')
解决跨域,每个视图都要添加 allow-header/method/origin,所以更好的方法是写一个中间件,放在process_response中。
cors.py
from django.middleware.common import CommonMiddleware from django.utils.deprecation import MiddlewareMixin class CORS(MiddlewareMixin): def process_response(self,request,response): response['Access-Control-Allow-Origin'] = '*' # 允许的url response['Access-Control-Allow-Headers'] = 'Content-Type' # 允许的请求头 response['Access-Control-Allow-Methods'] = '*' return response
views.py
class AuthView(APIView): def post(self,request,*args,**kwargs): print(request.data) return Response('111')
4 区分登录状态,即登录前页面 和登录后。两者区别是,登录前只有登录按钮。登录成功后,显示用户名和注销。
问题1 login.vue 这个组件把用户名,用户密码发给后台。但是,最开始的登录按钮是在 Header.vue中。 如果登录成功,Header.vue 中的登录按钮应该变为 用户名。涉及到两个组件的传值问题。即跨组件传值,
结局方法:利用vuex,共享某些数据。
vuex的适用方法(是js文件)
1)在src文件夹下新建store文件夹,在store文件夹下新建store.js
2) store.js中代码如下,基本格式
import Vue from 'vue' import Vuex from 'vuex' import Cookies from 'vue-cookies' Vue.use(Vuex) export default new Vuex.Store({ state:{ username:'xx', token:'', apilist:'', }, getters:{ }, mutations:{ }, actions:{ } } )
3 )在main.js中导入vuex
import axios from 'axios' import store from './store/store' Vue.prototype.$axios = axios Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, store, components: { App }, template: '' })
这样,在每个vue组件中,都可以去到state中的数据。
下一步的流程是,state.username初始值为null,Header.vue可以拿到state.username,进行条件判断,渲染登录前,登录后不同的页面。
login.vue提交数据后,通过then()函数,对从后台返回的数据进行判断,如果用户登录成功,对state.username 进行重新赋值,Header.vue可以立马感受到,一旦发生变化,渲染与之对应的页面。
代码如下:
Header.vue
"/index">首页 "/course">课程 "/news">深科技 if="this.$store.state.username">"/index">{{this.$store.state.username}} "" @click="logoutfuc">注销 else>"/login">登录
Login.vue
"text" v-model="username" placeholder="请输入用户名">姓名 "password" v-model="password" placeholder="请输入密码">密码 "button" @click="loginfunc" value="提交">
总结:Login.vue 有着相当重要的功能。
1 登录页面,需要输入用户名,密码,取值是利用v-model双向绑定的方法,input表单输入和应用状态之间双向绑定。
2 点击提交按钮,触发函数,调用函数,通过axios ,提交数据给后台,
3 后台返回数据,axios调用回调函数then(),对数据进行判断,修改 vuex中 state中的值。
4 Header.vue 实时监听 state 中的值,发生变化,渲染不同的页面。
小问题:
1
2
3 v-else必须紧跟着v-if,官方文档中这样说。
5 登录成功后,在cookie中保存用户名,token。
用到vue-cookies组件,vuex组价。
经过第4步,可以简单的实现区分登录前后的状态。代码比较粗糙,vuex的有些方法也没有用到。进行如下修改。
在第四步中,登录状态是login函数的回调函数then方法,这是不合理的。如果每个页面都有,那在每个组件都都要写一遍。vuex 中mutations方法,专门提供方法,可以对state中的数据进行修改。而不同组件只需这段代码 this/that.$store.commit('mutations中的函数','函数需要的参数')。commit 表示触发。
store.js
import Vue from 'vue' import Vuex from 'vuex' import Cookies from 'vue-cookies' Vue.use(Vuex) export default new Vuex.Store({ state:{ username:Cookies.get('username'), // Cookies的作用在于,即便页面重新刷新,该有的数据依然存在cookie中,了不起。很大的作用。 token:Cookies.get('token'), // apilist:'', }, getters:{ }, mutations:{ saveToken:function (state,response) { state.username = response.username; //response类型是object,取值用 . ,不能用get('username') state.token = response.token; Cookies.set('username',response.username,'20min'); Cookies.set('token',response.token,'20min') }, clearToken:function (state) { state.username = null; state.token = null; Cookies.remove('username'); Cookies.remove('token') } }, actions:{ } } )
Login.vue
"text" v-model="username" placeholder="请输入用户名">姓名 "password" v-model="password" placeholder="请输入密码">密码 "button" @click="loginfunc" value="提交">
Header.vue
"/index">首页 "/course">课程 "/news">深科技 else>"/login">登录
views.py
class AuthView(APIView): def post(self,request,*args,**kwargs): ret = { 'username':request.data.get('username'), 'password':request.data.get('password'), 'token':'geageage111' } print(ret) print(Response(ret)) return Response(ret)
输出:
注意Response!!! 所以,前端取值,需要调用.data。
{'username': '11', 'password': '11', 'token': 'geageage111'}200, "text/html; charset=utf-8">