文章目录
- 前要:前端路由的概念与原理
- 1)什么是路由
- 2)SPA与前端路由
- 3)什么是前端路由
- 4)前端路由的工作方式
- 一、Vue-router简单使用
- 1)什么是vue-router
- 2) vue-router 安装和配置的步骤
- ① 安装 vue-router 包
- ② 创建路由模块
- ③ 导入并挂载路由模块
- ④ 声明路由链接和占位符
- ⑤ 声明路由的匹配规则
- 3) vue-router 简单使用
- 二、登录跳转电影热点榜单案例
- 1)注意事项一:axios
- 2)注意事项二:跨域问题
- 三、scoped样式
前要:前端路由的概念与原理
1)什么是路由
路由(英文:router)就是对应关系
2)SPA与前端路由
SPA指的是一个web网站只有一个唯一的一个HTML页面,
所有组件的展示与切换
都在唯一的一个页面内完成。
此时,不同组件之间的切换
需要通过前端路由
来实现
总结:在SPA项目中,
不同功能之间的切换
,要依赖于前端路由
来完成
3)什么是前端路由
通俗移动的概念:
地址
与组件
之间的对应关系
4)前端路由的工作方式
- 用户点击了页面上的路由链接
- 导致了URL地址栏中的值发生了变化
- 前端路由监听到了地址的变化
- 前端路由把当前地址对应的组件渲染到浏览器中
一、Vue-router简单使用
1)什么是vue-router
vue-router
是vue.js官方
给出的路由解决方案。它只能结合 vue 项目进行使用,能够轻松的管理 SPA 项目中组件的切换。
vue-router 的官方文档地址:https://router.vuejs.org/zh/
2) vue-router 安装和配置的步骤
因为我是通过命令创建vue项目的,当时已经选配好了,所以下面前三个步骤都不用自己配置
① 安装 vue-router 包
在 vue2 的项目中,安装 vue-router 的命令如下:
cnpm i vue-router@3.5.2 -S
② 创建路由模块
在
src
源代码目录下,新建router/index.js
路由模块,并初始化如下的代码:
//1. 导入Vue 和 VueRouter的包
import Vue from 'vue'
import VueRouter from 'vue-router'
//2. 调用Vue.use() 函数,把VueRouter安装为Vue的插件
Vue.use(VueRouter)
//3. 创建路由的实例对象
const routes = new VueRouter()
//4. 向外共享路由的实例对象
export default router
③ 导入并挂载路由模块
在
src/main.js
入口文件中,导入并挂载路由模块。示例代码如下:
import Vue from 'vue'
import App from './App.vue'
//1. 导入路由模块
import router from './router'
import store from './store'
Vue.config.productionTip = false
//2. 挂载路由模块
new Vue({
router, //也可以写成 router:router
store,
render: h => h(App)
}).$mount('#app')
④ 声明路由链接和占位符
在
src/App.vue
组件中,使用 vue-router 提供的< router-link > (这个也可以不用)
和< router-view >
声明路由链接(路由链接也可以不用)
和占位符:
<template>
<div id="app">
<!--定义路由链接 || 也可以不用定义-->
//<router-link to="/">首页</router-link>
//<router-link to="/login">登录</router-link>
<!--定义路由的占位符-->
<router-view></router-view>
</div>
</template>
其实使用< a >链接也行,如
< a href="#/home">首页</ a>
但更推荐使用< router-link>
并且这样不需要写#号
,在浏览器控制台看到的还是< a>链接
⑤ 声明路由的匹配规则
在
src/router/index.js
路由模块中,通过routes数组
声明路由的匹配规则。示例代码如下:
//1.导入需要使用路由切换展示的组件
import IndexView from '@/views/indexView.vue'
import LoginView from "@/views/LoginView.vue";
//2.注册路由
const routes = [
//在routers数组中,声明路由的匹配规则
{
path: '/', // path表示要匹配的地址
name: 'index', // name 表示别名
component: IndexView, //component 表示要展示的路由组件
},
{
path: '/login',
name: 'login',
component: LoginView
},
]
3) vue-router 简单使用
1.在views中创建一个页面组件
<script>
export default {
name:'indexView',
}
</script>
<template>
<div>
<h1>首页</h1>
</div>
</template>
<style scoped>
</style>
2.在router/index.js文件中导入并使用
# 导入Vue 和 VueRouter的包
import Vue from 'vue'
import VueRouter from 'vue-router'
//1.导入需要使用路由切换展示的组件
import IndexView from '@/views/indexView.vue'
# 调用Vue.use() 函数,把VueRouter安装为Vue的插件
Vue.use(VueRouter)
//2.注册路由
const routes = [
//在routers数组中,声明路由的匹配规则
{
path: '/', // path表示要匹配的地址
name: 'index', // name 表示别名
component: IndexView, //component 表示要展示的路由组件
},
]
# 创建路由的实例对象
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
# 向外共享路由的实例对象
export default router
3.在App.vue中定义路由的占位符,这样就可以实现组件切换
<template>
<div id="app">
<!--定义路由的占位符-->
<router-view>
</router-view>
</div>
</template>
<style></style>
<script>
export default {
name: 'App',
data() {
return {}
},
created() {
console.log(this) // 只要使用了路由组件 this中就有了 route router
}
}
</script>
这样启动vue项目后,在浏览器中输入对应的路由即可访问了
二、登录跳转电影热点榜单案例
1)注意事项一:axios
这里会涉及到从前端向后端发送ajax请求,所以需要安装一个axios,命令cnpm install axios -S
(-S是会把这个依赖写入到package.json中,不写的话只能在当前项目使用)
使用axios,和导入组件一样的操作
import axios from 'axios' //一样import后面不一定叫axios它只是一个重命名,可以随意叫,为了好识别不乱改
2)注意事项二:跨域问题
1.在Django中安装模块
pip3 install django-cors-headers
2.在settings中注册应用和注册中间件
INSTALLED_APPS = (
'corsheaders',
)
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware'
]
3.最后把下面的代码复制到settings文件夹中即可
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'Pragma',
)
案例开始
这里为了方便,我使用restframework-jwt快速创建登录,因为是jwt是基于auth表的登录,所以先创建一个用户,这里不就在演示了。
Django编写后端登录接口以及获取电影热点榜单接口
urls.py
from rest_framework_simplejwt.views import token_obtain_pair
urlpatterns = [
path('login/', token_obtain_pair),
]
我这里为了好一些,就定制返回格式和定制全局异常处理
serializer.py
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
class LoginSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
res = super().validate(attrs)
user = self.user
data = {'code': 100, 'message': '登录成功', 'username': user.username}
data.update(res)
return data
'设置全局,在settings中配置一下'
SIMPLE_JWT = {
"TOKEN_OBTAIN_SERIALIZER": "app01.serializer.LoginSerializer",
}
excptions.py
from rest_framework.views import exception_handler
from rest_framework.response import Response
def common_exception_handler(exc, context):
res = exception_handler(exc, context)
if res:
msg = res.data.get('detail') or res.data or '系统异常,请联系管理员'
return Response({'code': 999, 'msg': msg})
else:
return Response({'code': 888, 'msg': f"系统异常,请联系管理员:{str(exc)}"})
'配置一下自定义的全局异常处理,在settings中配置一下'
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'app01.excptions.common_exception_handler'
}
views.py配置访问电影接口
from rest_framework.views import APIView
from rest_framework.response import Response
import json
class MovieView(APIView):
def get(self, request):
with open('./movie.json', 'rt', encoding='utf-8') as f:
res = json.load(f)
return Response(res)
'urls.py'
path('movies/', views.MovieView.as_view()),
Vue+axios编写前端
配置LoginView.vue组件
<script>
import axios from 'axios'
export default {
name:'LoginView',
data(){
return {
username:'',
password:'',
}
},
methods:{
handlerSubmit(){
//发送ajax请求
axios.post('http://127.0.0.1:8000/api/v1/login/',{
username:this.username,
password:this.password
}).then(response=>{
if(response.data.code===100){
//路由跳转 vue-router支持的
this.$router.push('/')
}else{
alert(response.data.msg)
}
})
}
}
}
</script>
<template>
<div>
<h1>登录页面</h1>
<hr>
<p>username: <input type="text" v-model="username" placeholder="请输入用户名"></p>
<p>password: <input type="password" v-model="password" placeholder="请输入密码"></p>
<button @click="handlerSubmit">登录</button>
</div>
</template>
配置indexView.vue组件
<script>
import axios from 'axios'
export default {
name: 'indexView',
data() {
return {
filmlist: [],
}
},
created() {
axios.get('http://127.0.0.1:8000/api/v1/movies/').then(res => {
// console.log(res.data.status)
if (res.data.status === 0) {
this.filmlist = res.data.data.films
// console.log(res.data.data.films)
} else {
alert(res.msg)
}
})
}
}
</script>
<template>
<div>
<h1 style="margin-left:20px;">电影热点榜单</h1>
<div id="zhu" v-for="film in filmlist">
<div style="float: left;">
<img :src="film.poster" alt="" style="width:66px;height:100px;">
</div>
<div style="float:left;margin-left:10px;margin-top:-20px;">
<span>
<h4 style="padding:0;margin-bottom:12px;">{{ film.name }}</h4>
<span>观众评分 {{ film.grade }}</span><br>
主演:<span v-for="people in film.actors">
{{ people.name }}
</span><br>
<span>中国大陆|{{ film.runtime }}</span>
</span>
</div>
</div>
</div>
</template>
<style scoped>
#zhu {
border-top: 1px solid rgb(158, 158, 158);
margin: 20px;
padding: 20px;
overflow: hidden;
}
</style>
配置App.vue占位
<template>
<div id="app">
<!--定义路由的占位符-->
<router-view>
</router-view>
</div>
</template>
在router/index.js中导入组件和注册路由
// 导入Vue 和 VueRouter的包
import Vue from 'vue'
import VueRouter from 'vue-router'
//1.导入需要使用路由切换展示的组件
import IndexView from '@/views/indexView.vue'
import LoginView from "@/views/LoginView.vue";
//调用Vue.use() 函数,把VueRouter安装为Vue的插件
Vue.use(VueRouter)
//2.注册路由
const routes = [
//在routers数组中,声明路由的匹配规则
{
path: '/', // path表示要匹配的地址
name: 'index', // name 表示别名
component: IndexView, //component 表示要展示的路由组件
},
{
path: '/login',
name: 'login',
component: LoginView
},
]
// 创建路由的实例对象
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
// 向外共享路由的实例对象
export default router
这样就实现了登录后跳转到电影热点榜页面了
三、scoped样式
Scoped主要作用就是让当前样式只允许当前组件生效 别的组件无效
用个实例来说明一下
'TestView是没有设置在style标签中设置scoped样式的,我们配置好组件和路由去访问别的路由地址看看'
<script>
export default {
name:'TestView'
}
</script>
<template>
<div>
<h1>hello world</h1>
</div>
</template>
<style> //这是
h1{background-color:lightblue}
</style>
可以发现当我们切换别的路由组件时,那个组件的样式全局设置了,所以需要设置在style标签中设置scoped样式
我们再把scoped样式加上看看
可以看到已经不影响其他组件了。