文章目录
- 前要:前端路由的概念与原理
- 1)什么是路由
- 2)SPA与前端路由
- 3)什么是前端路由
- 4)前端路由的工作方式
- 一、Vue-router简单使用
- 1)什么是vue-router
- 2) vue-router 安装和配置的步骤
- ① 安装 vue-router 包
- ② 创建路由模块
- ③ 导入并挂载路由模块
- ④ 声明路由链接和占位符(router-view/router-link)
- router-link补充
- ⑤ 声明路由的匹配规则
- 3) vue-router 简单使用
- 二、登录跳转电影热点榜单案例
- 1)注意事项一:axios
- 2)注意事项二:跨域问题
- 三、scoped样式
- 四、混入(mixin)
- 1) 定义混入
- 2) 局部导入混入
- 2) 全局导入混入
- 五、插件
- 1)介绍
- 2)插件的使用
前要:前端路由的概念与原理
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:routerstore,render: h => h(App)}).$mount('#app')
④ 声明路由链接和占位符(router-view/router-link)
在
src/App.vue
组件中,使用 vue-router 提供的< router-link > (这个也可以不用)
和< router-view >
声明路由链接(路由链接也可以不用)
和占位符:
'''< router-link>:该标签是一个vue-router中已经内置的组件,它会被渲染成一个<a>标签。< router-view>:该标签会根据当前的路径,动态渲染出不同的组件。网页的其他内容,比如顶部的标题/导航,或者底部的一些版权信息等会和< router-view>处于同一个等级。在路由切换时,切换的是< 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>链接
router-link补充
- tag:tag可以指定router-link之后渲染成什么组件,比如,此时就是一个button了;
- replace:增加replace属性,就相当于replaceState;
- class:可以为标签增加样式,比如选中的会自动赋值router-link-active;
- active-class=“active”:选中的;也可以在router组件中配置linkActiveClass: ‘active’;
⑤ 声明路由的匹配规则
在
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 = TrueCORS_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_pairurlpatterns = [path('login/', token_obtain_pair),]
我这里为了好一些,就定制返回格式和定制全局异常处理
serializer.py
from rest_framework_simplejwt.serializers import TokenObtainPairSerializerclass LoginSerializer(TokenObtainPairSerializer):def validate(self, attrs):res = super().validate(attrs)user = self.userdata = {'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_handlerfrom rest_framework.response import Responsedef 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 APIViewfrom rest_framework.response import Responseimport jsonclass 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样式加上看看
可以看到已经不影响其他组件了。
四、混入(mixin)
混入(mixin)
提供了一种非常灵活的方式,来分发Vue组件中的可复用功能
。一个混入对象可以包含任意组件选项。
当组件使用混入对象时,所有混入对象的选项将被"混合"进入该组件本身的选项。换句话说,
mixin是对vue组件的一种扩展,将一些公用的常用数据或者方法,构建成一个可被混入的数据结构,被不同的vue组件进行合并,就可以在不同的vue组件中使用相同的方法或者基础数据。
如果只是提取公用的数据或者通用的方法,并且这些数据或方法, 不需要组件间进行维护,就可以使用mixin(类似于js中封装的一些公用的方法)
1) 定义混入
在src文件夹下创建一个mixin/index.js
export default {data(){return {name:'王三多'}},methods:{getName(){console.log('来自mixin/index的点击事件')alert('彭于晏')}}}
2) 局部导入混入
在想要使用的组件中导入使用即可
<template><div><h1>混入的使用</h1><hr><button @click="getName">点我弹出名字</button><br><span>当前组件的定义的名字:{{name}}----->{{age}}</span></div></template><script>//局部使用混入import mixin from '@/mixin'export default {name: 'MixinsView',data(){return{name:'张三丰',age:20,}},mixins:[mixin], //可以导入多个混入,有多个想用直接在这个数组中追加即可}</script>
注意:
如果混入的对象与当前组件使用混入的有同名选项时,这些选项将以恰当的方式进行"合并",如果发生冲突时以当前组件数据优先使用。
2) 全局导入混入
混入也可以进行全局注册。使用时格外小心!一旦使用全局混入,它将影响每一个之后创建的 Vue 实例。
在mian.js中导入
//混入的全局导入、可以导入多个混入,注意名称需要不一样import mixin from '@/mixin'Vue.mixin(mixin)
五、插件
1)介绍
什么是Vue插件,它和Vue组件有什么区别?
通常插件是一种遵循一定规范的应用程序接口编写出来的程序,是一个库
。而组件则更倾向于一个单一的功能,一个控件或对象
。Vue官网给我们的解释是:插件通常用来为 Vue 添加全局功能、组件是可复用的 Vue 实例。
vue插件的作用:主要是用于增强功能,可以把它看做一个工具库,可以提供很多强大的功能,比如一些强大的自定义指令、一些强大的工具方法、过滤器等。
插件是一种能为Vue添加全局功能的工具代码
官网说到,插件的功能范围没有严格的限制——一般有下面几种:
-
添加全局方法或者 property。如:vue-custom-element
-
添加全局资源:指令/过滤器/过渡等。如 vue-touch
-
通过全局混入来添加一些组件选项。如 vue-router
-
添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
-
一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如 vue-router
2)插件的使用
本质:Vue.js 的插件包含一个 install 方法的一个对象。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象(插件使用者传递的数据)。
定义插件在src文件夹下新建一个文件夹plugins/index.js
-es5及以前// 此类中必须要有 静态方法 install 静态方法中不能调用成员属性或方法 this不能用// static install(Vue,options){-es6之后export default {install(Vue){console.log(Vue)//使用插件能干什么?1.设置全局变量Vue.prototype.$name='jack'2.可以把axios做成全局,这样每个组件就可以直接使用this.$axiosVue.prototype.$axios=axios3.设置全局函数,以后再任意组件中 this.add(1,2)调用方法Vue.prototype.$add=(a,b)=>{return a+b+99}4.使用混入,只要这样设置后,就不用再全局里面注册混入了,这样任意组件一样能用Vue.mixin({data(){return{name:'oscar',age:22,}},methods:{ShowName(){alert('名字为:'+this.name+' '+'年龄为:'+this.age)}}})}}
注册插件在main.js中注册
import plugins from '@/plugins'Vue.use(plugins)
在任意组件中使用即可
<script>export default {name:'PluginsView',methods:{handlerClick(){// console.log(this.$axios)console.log('自定义插件的属性:'+this.$name)console.log('自定义插件的方法:'+this.$add(9,1))}},}</script><template><div><h1>插件的使用</h1><hr><button @click="handlerClick">点击查看控制台</button><p/><button @click="ShowName">点我查看自定义插件混入</button></div></template>
补充Python中和js中往类中放属性
'python中'class Person:passPerson.name='jack'p=Person()print(p.name)'js中'new Vue() //Vue类Vue.prototype.$name='jack' //往类中放属性,与python中有些区别'这里的prototype就是原型,在属性名前加$是为了防止被污染作区分'this.$router //this代指Vue实例this.$name //从对象中取