一、基于api前端显示课程详细信息

1、调整Course.vue模块

<template>
<div>
<h1>课程列表</h1>
<div v-for="row in courseList">
<div style="width:350px;float: left;">
<!--<img src="" alt=""/>-->
<h3><router-link :to="{name:'detail', params:{id:row.id}}">{{row.title}}</router-link></h3>
<p>{{row.level}}</p>
</div>
</div>
</div>
</template> <script>
export default {
name: "index",
data() {
return {
courseList: []
}
},
mounted: function () {
// vue页面刚加载时自动执行
this.initCourse()
},
methods: {
initCourse: function () {
/*
this.courseList = [
{id:1,title:'Python全栈'},
{id:2,title:'Linux运维'},
{id:3,title:'金融分析'},
]
*/ // 通过ajax向接口发送请求,并获取课程列表
// axios 发送ajax请求
// npm install axios --save
// 第一步:在main.js中配置
// 第二步:使用axios发送请求
var that = this; this.$axios.request({
url: 'http://127.0.0.1:8000/api/v1/course/',
method: "GET"
}).then(function (ret) {
// ajax请求发送成功后,获取的响应内容
console.log(ret.data);
if (ret.data.code === 1000) {
// 注意这里的this已经不再是之前的this
that.courseList = ret.data.data
}else{
alert("获取数据失败");
}
}).catch(function (ret) {
// ajax请求失败之后,获取响应的内容
})
}
}
}
</script> <style scoped> </style>

  显示效果:

  

2、调整Detail.vue模块

<template>
<div>
<h1>课程详细页面</h1>
<div>
<p>{{detail.course}}</p>
<p>{{detail.img}}</p>
<p>{{detail.level}}</p>
<p>{{detail.slogon}}</p>
<p>{{detail.title}}</p>
<p>{{detail.why}}</p>
<div>
<ul v-for="item in detail.chapter">
<li>{{item.name}}</li>
</ul>
</div> <div>
<ul v-for="item in detail.recommends">
<li>{{item.title}}</li>
</ul>
</div>
</div>
</div>
</template> <script>
export default {
name: "index",
data() {
return {
detail: { // 定义字典和相关的key
course: null,
img: null,
level: null,
slogon: null,
title: null,
why: null,
chapter: [],
recommends: [],
}
}
},
mounted() {
this.initDetail()
},
methods: {
initDetail() {
var nid = this.$route.params.id; // 获取当前id值(用于拼接url)
var that = this;
this.$axios.request({ // 发送axios请求
url: 'http://127.0.0.1:8000/api/v1/course/' + nid + '/',
method: 'GET'
}).then(function (arg) { // arg是返回的值:{code:1000, data:{...}}
// 将拿到的值赋值给detail
if (arg.data.code === 1000) {
that.detail = arg.data.data // 注意这里的this已经不是原来的this
} else {
alert(arg.data.error)
}
})
}
}
}
</script> <style scoped> </style>

  显示效果:

  

二、推荐课程切换及详情展示

1、测试使用router-link是否合适

  对Detail.vue修改如下:

<template>
<div>
<h1>课程详细页面</h1>
<div>
<p>{{detail.course}}</p>
<p>{{detail.img}}</p>
<p>{{detail.level}}</p>
<p>{{detail.slogon}}</p>
<p>{{detail.title}}</p>
<p>{{detail.why}}</p>
<div>
<ul v-for="item in detail.chapter">
<li>{{item.name}}</li>
</ul>
</div> <div>
<h3>推荐课程</h3>
<ul v-for="item in detail.recommends">
<li><router-link :to="{name:'detail',params:{id:item.id}}">{{item.title}}</router-link></li>
</ul>
</div>
</div>
</div>
</template>

  给推荐课程添加链接地址,点击可以实现url切换,但是由于组件没有重新加载,this.initDetail()没有执行。

  因此页面的内容并不会发生切换。此方法不合适。

2、添加点击事件处理推荐课程点击切换

<template>
<div>
<h1>课程详细页面</h1>
<div>
<p>{{detail.course}}</p>
<p>{{detail.img}}</p>
<p>{{detail.level}}</p>
<p>{{detail.slogon}}</p>
<p>{{detail.title}}</p>
<p>{{detail.why}}</p>
<div>
<ul v-for="item in detail.chapter">
<li>{{item.name}}</li>
</ul>
</div> <div>
<h3>推荐课程</h3>
<ul v-for="item in detail.recommends">
<!--为推荐课程添加点击事件-->
<li @click="changeDetail(item.id)">{{item.title}}</li>
</ul>
</div>
</div>
</div>
</template> <script>
export default {
name: "index",
data() {
return {
detail: { // 定义字典和相关的key
course: null,
img: null,
level: null,
slogon: null,
title: null,
why: null,
chapter: [],
recommends: [],
}
}
},
mounted() {
var id = this.$route.params.id; // 获取当前id值(用于拼接url)
this.initDetail(id)
},
methods: {
initDetail(nid) {
var that = this;
this.$axios.request({ // 发送axios请求
url: 'http://127.0.0.1:8000/api/v1/course/' + nid + '/',
method: 'GET'
}).then(function (arg) { // arg是返回的值:{code:1000, data:{...}}
// 将拿到的值赋值给detail
if (arg.data.code === 1000) {
that.detail = arg.data.data // 注意这里的this已经不是原来的this
} else {
alert(arg.data.error)
}
})
},
changeDetail(id){ // click拿到课程id重新加载就可以渲染成功了
this.initDetail(id); // 切换页面显示
this.$router.push({name: 'detail', params: {id:id}}); // 修改url地址
}
}
}
</script> <style scoped> </style>

  注意:这里将var id = this.$route.params.id; 操作提到了vue生命周期mounted方法中。因此initDetail(nid)函数接收的nid,有可能是从mounted中传递过来的id也可以是changeDetail传递的id。

  在 Vue 实例内部,你可以通过 $router 访问路由实例。因此你可以调用 this.$router.push

this.$router.push({name: 'detail', params: {id:id}});   // 命名的路由

  显示效果如下所示:

  

  点击推荐课程可以自由切换页面路径和页面显示。

三、用户登录功能实现

1、前端添加Login.vue模块

(1)App.vue和index.js添加Login模块

############# App.vue ###############
<template>
<div id="app">
<router-link to="/index">首页</router-link>
<router-link to="/course">课程</router-link>
<router-link to="/micro">微职位</router-link>
<router-link to="/news">深科技</router-link>
<div>
<router-link to="/login">登录</router-link>
</div>
<router-view/>
</div>
</template> ############# index.js ###############
import Login from '../components/Login'
Vue.use(Router); export default new Router({
routes: [
// 其他代码省略
{
path: '/login',
name: 'login',
component: Login
},
]
})

(2)Login.vue构建

<template>
<div>
<h2>用户登录</h2>
<div>
<p>
<input type="text" placeholder="请输入用户名" v-model="username">
</p>
<p>
<input type="password" placeholder="请输入密码" v-model="password">
</p>
<input type="button" value="登录" @click="doLogin">
</div>
</div>
</template> <script>
export default {
data(){
return {
// 通过v-model双向绑定用户名和密码
username:'',
password:''
}
},
methods: {
doLogin(){
this.$axios.request({
url:'http://127.0.0.1:8000/api/v1/auth/',
method:'POST',
data:{
user:this.username,
pwd:this.password
},
headers:{
'Content-Type': 'application/json'
}
}).then(function (arg) {
// 拿回结果
console.log(arg)
}).catch(function (arg) {
// 拿到错误信息
console.log("发生错误")
})
}
}
}
</script> <style scoped> </style>

  注意:这里是通过v-model双向绑定用户名和密码,并以此通过post请求来发送username和password。

2、django后台auth接口配置

(1)路由配置api/urls.py:

urlpatterns = [
"""代码省略"""
url(r'^(?P<version>[v1|v2]+)/auth/$', account.AuthView.as_view()), ]

(2)视图配置api/view/account.py:

from rest_framework.views import APIView
from rest_framework.response import Response class AuthView(APIView):
def post(self, request, *args, **kwargs):
print(request.data) return Response('...')

(3)在前台页面尝试登陆

  

  可以看到虽然配置的是post请求,但实际却发送的是OPTIONS请求。

3、跨域问题处理

(1)简单请求和非简单请求

  浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

  只要同时满足以下两大条件,就属于简单请求。

(1) 请求方法是以下三种方法之一:
HEAD
GET
POST
(2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

  凡是不同时满足上面两个条件,就属于非简单请求。

  如果是复杂请求,会先用options请求进行预检,通过之后才能发送post请求。

(2)配置修改account.py,添加options请求处理

from rest_framework.views import APIView
from rest_framework.response import Response
from django.shortcuts import HttpResponse class AuthView(APIView): def options(self, request, *args, **kwargs):
# 进行预检
obj = HttpResponse('')
obj["Access-Control-Allow-Origin"] = "*" # 允许你的域名来获取我的数据
obj['Access-Control-Allow-Headers'] = "Content-Type" # 允许你携带Content-Type请求头
return obj def post(self, request, *args, **kwargs):
print(request.data) # 同源策略禁止读取位于 http://127.0.0.1:8000/api/v1/auth/ 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')
obj = Response("...")
obj["Access-Control-Allow-Origin"] = "*" # 允许你的域名来获取我的数据 return obj # 返回值再加上一个响应头

  再次访问登录页面,尝试登录操作,可以看到OPTIONS请求通过后,发送POST请求,python后端也打印出request.data中的数据。

  

(3)用中间件来处理跨域问题

  上面这种方式过于麻烦了,一般还是交给中间件来处理跨域问题,为所有请求都设置头。

  /api/cors.py:

from django.utils.deprecation import MiddlewareMixin

class CORSMiddleware(MiddlewareMixin):
"""自定义中间件""" def process_response(self, request, response):
# 添加响应头 # 允许你的域名来获取我的数据
response['Access-Control-Allow-Origin'] = "*"
# 允许你携带Content-Type请求头,这里不能写*
# response['Access-Control-Allow-Headers'] = "Content-Type"
# 允许你发送GET/POST/DELETE/PUT
# response['Access-Control-Allow-Methods'] = "GET, POST" if request.method == "OPTIONS":
response["Access-Control-Allow-Headers"] = "Content-Type"
return response

4、rest-framework登录验证

(1)给models.py添加User和Token模型

class UserInfo(models.Model):
user = models.CharField(max_length=32)
pwd = models.CharField(max_length=64) class UserToken(models.Model):
user = models.OneToOneField(to="UserInfo", on_delete=models.CASCADE)
token = models.CharField(max_length=64) # 不仅可以配置token,还可以配置超时时间

  利用makemigrations和migrate完成数据迁移操作。在UserInfo表添加用户和密码。

(2)后端处理登录信息,更新并创建token信息

  重写/api/views/account.py如下所示:

from rest_framework.views import APIView
from rest_framework.response import Response
from django.shortcuts import HttpResponse
from api import models
import uuid # 网卡和时间生成的随机字符串 class AuthView(APIView): def post(self, request, *args, **kwargs):
"""
用户登录认证
:param request:
:param args:
:param kwargs:
:return:
"""
print(request.data)
ret = {'code': 1000}
# 用get方法取的话,不存在即为Null
user = request.data.get("user")
pwd = request.data.get("pwd")
user = models.UserInfo.objects.filter(user=user, pwd=pwd).first()
if not user:
ret['code'] = 1001
ret['error'] = "用户名或密码错误"
else:
uid = str(uuid.uuid4()) # 将生成的随机对象转化为随机字符串
models.UserToken.objects.update_or_create(user=user, defaults={"token":uid})
ret["token"] = uid
return Response(ret)

(3)登录验证

  在vue前端登录,显示信息如下:

  

  在python后台打印request.data信息:{'user': 'asdw', 'pwd': 'asdw131'}、{'user': 'oldboy', 'pwd': '123'}。

5、用vuex实现在各个组件中共享值

(1)全局变量配置

  1)创建/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: null,
token: null,
},
})

  组件中通过 this.$store.state.username 调用。

  2)在main.js中引入store,并放入实例化组件中

import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'
import store from './store/store' // 在vue的全局变量中设置了 $axios=axios
// 以后每个组件使用时:this.$axios
Vue.prototype.$axios = axios; Vue.config.productionTip = false; /* eslint-disable no-new */
new Vue({
el: '#app',
router,
store, // 放入实例化中
components: {App},
template: '<App/>'
})

(2)在所有组件中使用全局变量

  Login.vue:

<script>
export default {
data(){
return {
// 通过v-model双向绑定用户名和密码
username:'',
password:''
}
},
methods: {
doLogin(){
var that = this;
this.$axios.request({
url:'http://127.0.0.1:8000/api/v1/auth/',
method:'POST',
data:{
user:this.username,
pwd:this.password
},
headers:{
'Content-Type': 'application/json'
}
}).then(function (arg) {
// 拿回结果
if (arg.data.code === 1000){
// 成功的情况下
that.$store.state.token = arg.data.token;
that.$store.state.username = that.username; }else {
alert(arg.data.error)
}
}).catch(function (arg) {
// 拿到错误信息
console.log("发生错误")
})
}
}
}
</script>

  App.vue:

<template>
<div id="app"> <router-link to="/index">首页</router-link>
<router-link to="/course">课程</router-link>
<router-link to="/micro">微职位</router-link>
<router-link to="/news">深科技</router-link>
<div v-if="this.$store.state.token">
<a href="">{{this.$store.state.username}}</a>
</div>
<div v-else>
<router-link to="/login">登录</router-link>
</div>
<router-view/>
</div>
</template> <script>
export default {
name: 'App'
}
</script>

  如此就可以通过获取全局变量实现用户登录效果:

  

  但是这种登录状态,只要浏览器一刷新,登录状态就消失了,因此登录成功不仅要设置到全局变量,还要在cookie中放一份全局变量。

6、vue-cookies应用

(1)store.js

import Vue from 'vue'
import Vuex from 'vuex'
import Cookie from 'vue-cookies' // 引入cookie,npm install vue-cookies --save Vue.use(Vuex); export default new Vuex.Store({
// 组件中通过 this.$store.state.username 调用
state: {
// 默认去cookie中取值
username: Cookie.get("username"),
token: Cookie.get("token"),
},
mutations: {
// 组件中通过this.$store.commit(函数名, 参数)调用
saveToken: function (state, userToken) {
state.username = userToken.username;
state.token = userToken.token;
Cookie.set("username", userToken.username, "20min");
Cookie.set("token", userToken.token, "20min");
},
}
})

  1)注意引入cookie的方法;

  2)注意mutations方法。更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。

  3)组件中通过this.$store.commit(函数名, 参数)调用。

(2)Login.vue修改

<script>
export default {
data(){
return {
// 通过v-model双向绑定用户名和密码
username:'',
password:''
}
},
methods: {
doLogin(){
var that = this;
this.$axios.request({
url:'http://127.0.0.1:8000/api/v1/auth/',
method:'POST',
data:{
user:this.username,
pwd:this.password
},
headers:{
'Content-Type': 'application/json'
}
}).then(function (arg) {
// 拿回结果
if (arg.data.code === 1000){
// 成功的情况下
// that.$store.state.token = arg.data.token;
// that.$store.state.username = that.username;
that.$store.commit('saveToken',{token: arg.data.token, username: that.username});
}else {
alert(arg.data.error)
}
}).catch(function (arg) {
// 拿到错误信息
console.log("发生错误")
})
}
}
}
</script>

(3)刷新仍在全局显示登录用户

  

(4)添加登出注销操作

  App.vue:

<template>
<div id="app"> <router-link to="/index">首页</router-link>
<router-link to="/course">课程</router-link>
<router-link to="/micro">微职位</router-link>
<router-link to="/news">深科技</router-link>
<div v-if="this.$store.state.token">
<a href="">{{this.$store.state.username}}</a>
<a @click="logout">注销</a>
</div>
<div v-else>
<router-link to="/login">登录</router-link>
</div>
<router-view/>
</div>
</template> <script>
export default {
name: 'App',
methods:{
logout(){ // 注销
this.$store.commit('clearToken');
}
}
}
</script>

  store.js:

import Vue from 'vue'
import Vuex from 'vuex'
import Cookie from 'vue-cookies' // 引入cookie,npm install vue-cookies --save Vue.use(Vuex); export default new Vuex.Store({
// 组件中通过 this.$store.state.username 调用
state: {
// 默认去cookie中取值
username: Cookie.get("username"),
token: Cookie.get("token"),
},
mutations: {
// 组件中通过this.$store.commit(函数名, 参数)调用
saveToken: function (state, userToken) {
state.username = userToken.username;
state.token = userToken.token;
Cookie.set("username", userToken.username, "20min");
Cookie.set("token", userToken.token, "20min");
},
clearToken: function (state) {
state.username = null;
state.token = null;
Cookie.remove("username");
Cookie.remove("token");
}
}
})

  登出效果如下所示:

  

  点击注销后显示效果:

  

四、拦截器

  有些页面登录了才能访问,有些页面不需要登录即可访问。

1、页面访问登录判断

  这里以micro模块为例,给模块添加登录判断,用户未登录时访问微职业,直接跳转到登录页面。

<template>
<div>
<h1>LuffyX学位</h1>
</div>
</template> <script>
export default {
name: "index",
data() {
return { }
},
mounted(){ // 刚加载即执行
if(!this.$store.state.token){
// 重定向返回登录页面
this.$router.push({name:"login"})
}
}
}
</script> <style scoped> </style>

  但是对于组件很多的网站却不能这么处理,而是应该使用vue自带的拦截器来处理。

2、添加拦截器

(1)在路由控制中给需要拦截的路由配置meta字段

  index.js:给需要拦截的路由配置meta字段

export default new Router({
routes: [
{
path: '/index',
name: 'index',
component: Index,
},
{
path: '/course',
name: 'course',
component: Course
},
{
path: '/detail/:id', // 动态接收名字为id的值
name: 'detail',
component: Detail
},
{
path: '/micro',
name: 'micro',
component: Micro,
meta:{
requireAuth:true // 表示必须要登录
}
},
{
path: '/news',
name: 'news',
component: News,
meta:{
requireAuth:true // 表示必须要登录
}
},
{
path: '/login',
name: 'login',
component: Login
},
],
mode: 'history'
})

(2)添加配置拦截器

  main.js:

import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'
import store from './store/store' // 在vue的全局变量中设置了 $axios=axios
// 以后每个组件使用时:this.$axios
Vue.prototype.$axios = axios; Vue.config.productionTip = false; /* eslint-disable no-new */
new Vue({
el: '#app',
router,
store, // 放入实例化中
components: {App},
template: '<App/>'
}); // 拦截器 to:要去哪 next:去跳转 from:从哪来
router.beforeEach(function (to, from, next) {
if (to.meta.requireAuth) {
// 当前要去的url只有登录后才能访问
if (store.state.token) {
// token为true表示可以继续访问
next()
} else {
// token不为true跳转到登录页面
next({path:'/login',})
}
} else {
// url不需要访问即可以访问
next()
}
});

3、登录后直接显示登录前页面

  比如在访问微职业时,由于没有登录跳转到了登录页面,输入账户密码登录后,显示的内容应该是微职业的内容。

(1)修改main.js中的拦截器

  在url地址中添加返回的url:

// 拦截器  to:要去哪  next:去跳转  from:从哪来
router.beforeEach(function (to, from, next) {
if (to.meta.requireAuth) {
// 当前要去的url只有登录后才能访问
if (store.state.token) {
// token为true表示可以继续访问
next()
} else {
// token不为true跳转到登录页面
next({path:'/login', query:{backUrl: to.fullPath}})
}
} else {
// url不需要访问即可以访问
next()
}
});

(2)Login.vue中修改登录操作

<script>
export default {
data(){
return {
// 通过v-model双向绑定用户名和密码
username:'',
password:''
}
},
methods: {
doLogin(){
var that = this;
this.$axios.request({
url:'http://127.0.0.1:8000/api/v1/auth/',
method:'POST',
data:{
user:this.username,
pwd:this.password
},
headers:{
'Content-Type': 'application/json'
}
}).then(function (arg) {
// 拿回结果
if (arg.data.code === 1000){
// 成功的情况下
that.$store.commit('saveToken',{token: arg.data.token, username: that.username});
var url = that.$route.query.backUrl;
if (url) {
that.$router.push({path:url})
} else {
that.$router.push({path:'/index'})
}
}else {
alert(arg.data.error)
}
}).catch(function (arg) {
// 拿到错误信息
console.log("发生错误")
})
}
}
}
</script>

(3)登录验证

  

  登录成功后显示效果:

  

五、用户认证

1、通过token进行用户认证

(1)配置micro的url和视图

  api/urls.py:

urlpatterns = [
"""省略"""
url(r'^(?P<version>[v1|v2]+)/micro/$', course.MicroView.as_view()),
]

  Couse.py添加MicroView视图:

class MicroView(APIView):

    def get(self, request, *args, **kwargs):
token = request.query_params.get('token') # 获取到token
obj = models.UserToken.objects.filter(token=token) # 与数据库中token检验
if not obj:
return Response("认证失败")
return Response("微职位")

(2)配置Micro.vue向后端发送GET请求

<script>
export default {
name: "index",
data() {
return {
title:null
}
},
mounted(){ // 刚加载即执行
this.initMicro()
},
methods:{
initMicro(){
this.$axios.request({
url:'http://127.0.0.1:8000/api/v1/micro/', // 这个地址如果被盗,任何人都可以获取数据
method:"GET",
params:{
token:this.$store.state.token
}
}).then(function (arg) {
console.log(arg);
})
}
}
}
</script>

  这里需要注意不能只配置Url,这个地址如果被盗,则任何人都可以向后端发送请求获取数据。

  因此配置params参数,在url地址后拼接token参数来发送请求:

  

(3)django访问检验

  

  当token不正确时:

  

2、通过rest认证组件实现用户认证

(1) 在应用api下添加文件夹auth,添加auth.py文件

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from api import models class LuffyAuth(BaseAuthentication): def authenticate(self, request):
token = request.query_params.get("token")
obj = models.UserToken.objects.filter(token=token).first()
if not obj:
raise AuthenticationFailed({"code":1001, "error": "认证失败"})
return (obj.user.user, obj) # 返回用户名和token对象

(2)在MicroVIew视图类中添加认证组件 

from api.auth.auth import LuffyAuth

class MicroView(APIView):

    authentication_classes = [LuffyAuth]

    def get(self, request, *args, **kwargs):
ret = {"code":1000, "title":"微职位"}
return Response(ret)

  访问django页面验证:

  

(3)前端vue处理后端返回的数据

<template>
<div>
<h1>LuffyX学位:{{title}}</h1>
</div>
</template> <script>
export default {
name: "index",
data() {
return {
title:null
}
},
mounted(){ // 刚加载即执行
this.initMicro()
},
methods:{
initMicro(){
var that = this;
this.$axios.request({
url:'http://127.0.0.1:8000/api/v1/micro/', // 这个地址如果被盗,任何人都可以获取数据
method:"GET",
params:{
token:this.$store.state.token
}
}).then(function (arg) {
if (arg.data.code === 1000) {
that.title = arg.data.title
}
})
}
}
}
</script>

  访问http://localhost:8080/micro,效果如下所示:

  

六、vue接口归总

1、在vuex中设置apiList字段归总所有rest接口

import Vue from 'vue'
import Vuex from 'vuex'
import Cookie from 'vue-cookies' // 引入cookie,npm install vue-cookies --save Vue.use(Vuex); export default new Vuex.Store({
// 组件中通过 this.$store.state.username 调用
state: {
// 默认去cookie中取值
username: Cookie.get("username"),
token: Cookie.get("token"),
apiList: {
// 所有的接口
course: 'http://127.0.0.1:8000/api/v1/course/',
courseDetail: 'http://127.0.0.1:8000/api/v1/course/',
auth: 'http://127.0.0.1:8000/api/v1/auth/',
micro: "http://127.0.0.1:8000/api/v1/micro/",
}
},
mutations: {
/* 代码省略*/
}
})

2、替换各个模块中的url地址

  均按照如下方法替换:

url: this.store.state.apiList.micro,
url: this.store.state.apiList.course,
url: this.store.state.apiList.course + nid + '/',
url: this.store.state.apiList.auth,

  

vue+rest-framework前后端分离整合(二)的更多相关文章

  1. Flask + vue 前后端分离的 二手书App

    一个Flask + vue 前后端分离的 二手书App 效果展示: https://blog.csdn.net/qq_42239520/article/details/88534955 所用技术清单 ...

  2. dotnetcore vue+elementUI 前后端分离架二(后端篇)

    前言 最近几年前后端分离架构大行其道,而且各种框架也是层出不穷.本文通过dotnetcore +vue 来介绍 前后端分离架构实战. 涉及的技术栈 服务端技术 mysql 本项目使用mysql 作为持 ...

  3. List多个字段标识过滤 IIS发布.net core mvc web站点 ASP.NET Core 实战:构建带有版本控制的 API 接口 ASP.NET Core 实战:使用 ASP.NET Core Web API 和 Vue.js 搭建前后端分离项目 Using AutoFac

    List多个字段标识过滤 class Program{  public static void Main(string[] args) { List<T> list = new List& ...

  4. Vue+Spring Boot 前后端分离的商城项目开源啦!

    新蜂商城 Vue 移动端版本开源啦! 去年开源新蜂商城项目后,就一直在计划这个项目 Vue 版本的改造,2020 年开始开发并且自己私下一直在测试,之前也有文章介绍过测试过程和存在的问题,修改完成后, ...

  5. VUE开发(二)nginx配合vue来实现前后端分离部署

    一.引言 由于本地是采用vue+spring boot实现的前后端分离项目,本机启动的时候先启动后场服务,再单独启动vue工程,然后可以实现全流程贯穿,但是我们要部署到服务器上的时候,一般都是打一个j ...

  6. vue+rest-framework前后端分离整合

    一.vue部分 二.django路由配置 (1)项目urls.py修改如下: from django.conf.urls import url, include urlpatterns = [ # p ...

  7. ASP.NET Core 实战:使用 ASP.NET Core Web API 和 Vue.js 搭建前后端分离项目

    一.前言 这几年前端的发展速度就像坐上了火箭,各种的框架一个接一个的出现,需要学习的东西越来越多,分工也越来越细,作为一个 .NET Web 程序猿,多了解了解行业的发展,让自己扩展出新的技能树,对自 ...

  8. Springboot + Vue + shiro 实现前后端分离、权限控制

    本文总结自实习中对项目对重构.原先项目采用Springboot+freemarker模版,开发过程中觉得前端逻辑写的实在恶心,后端Controller层还必须返回Freemarker模版的ModelA ...

  9. Vue+Express实现前后端分离

    先说明一下缘由,因为自己前段时间在实习,实习期间为了参与项目开发,粗略学习了下Vue.Vuex.Vue-Router,大致会一些基础的.这里也快要做毕业设计了,趁着放假回来的这两天,学习下Node的相 ...

  10. Spring Boot + Vue + Shiro 实现前后端分离、权限控制

    本文总结自实习中对项目的重构.原先项目采用Springboot+freemarker模版,开发过程中觉得前端逻辑写的实在恶心,后端Controller层还必须返回Freemarker模版的ModelA ...

随机推荐

  1. linux的发行版

    Linux的不同版本以及应用领域 1.Linux内核及发行版介绍 <1>Linux内核版本 内核(kernel)是系统的心脏,是运行程序和管理像磁盘和打印机等硬件设备的核心程序,它提供了一 ...

  2. 【解决】Linux Tomcat启动慢--Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [236,325] milliseconds

    一.背景 今天部署项目到tomcat,执行./startup.sh命令之后,访问项目迟迟加载不出来,查看日志又没报错(其实是我粗心了,当时tomcat日志还没打印完),一开始怀疑是阿里云主机出现问题, ...

  3. ssm框架搭建出现的异常:The import org.springframework cannot be resolved

    1.检查是否有这个包;是否在maven依赖中添加了spring-context.,检查后我有这个包,而且在仓库中找到了 2.怀疑没有下完整,将其删除又导了一遍,还是报错. 3.后来重启了一遍eclip ...

  4. Covering(矩阵快速幂)

    Bob's school has a big playground, boys and girls always play games here after school.  To protect b ...

  5. HihoCoder - 1044 状压DP 初步

    本题主要难在状态的转移 定义\(dp[i][j]:\)前\(i\)个中\(j\)集合范围内的最优解 \(j\)定义为\(p_1,p_2,...,p_{m-1}\),若第\(i-j+1\)个选定,则\( ...

  6. BZOJ 3224 Treap

    部分还没调到满意的程度,效率比splay略好 #include<bits/stdc++.h> using namespace std; const int maxn = 1e6+11; u ...

  7. 关于在scrapy中使用xpath

    1. 还是以虎嗅为例,他给我返回的是一个json格式的json串 2.那么我需要操作的就是把json串转换成我们的字典格式再进行操作 str=json.loads(response.body)['da ...

  8. C#生成二維碼(ThoughtWorks.QRCode)

    本人使用的是ThoughtWorks.QRCode.dll,在網上可以下載,但要注意dll文件的完整性和準確性,本人之前下載的dll就是不正確導致調試時出現錯誤. 以下為cs文件代碼: using S ...

  9. zabbix 报警程序

    一,报警程序 本次使用的为onealert http://c.onealert.com/console/ucid/login.jsp 二,服务端安转 下面为他教的怎么安装这个东西 第一步: 找到脚本目 ...

  10. (转)8个有力的Awk内建变量

    8个有力的Awk内建变量 翻译原文:8 Powerful Awk Built-in Variableshttp://www.thegeekstuff.com/这个博客真是不错. 这篇文章是Awk Tu ...