1. 样式穿透
在使用vue脚手架快速搭建的项目中,如果你想在父组件中对子组件中的样式进行更改,那么你就需要使用样式穿透;
前提:在vue中为了实现组件的私有化,不会污染全局样式,那么常常需要使用scoped继续对当前模块的样式进行样式隔离;那么在父组件和子组件自然也是用使用了样式隔离;
1.2样式穿透实现方法和代码演示
样式穿透的语法:父组件css选择器 >>> 子组件css选择器;
子组件:给h1添加class类名;
<template>
<div>
<h1 class="h1">
MyCom组件
</h1>
</div>
</template>
父组件:
父组件先使用import导入components中的组件;
再在使用components字段注册组件;
import MyCom from "../components/MyCom.vue";
export default{
components:{
MyCom
}
}
父组件模板中使用子组件
<template>
<div class="about">
<MyCom :count="count" :arr="arr" @event="accept"></MyCom>
</div>
</template>
使用 样式穿透改变子组件中h1标签中的文字颜色;
<style scoped>
.about >>> h1{
color: violet;
}
</style>
2. public文件夹下的静态资源和assets的静态资源引入方式有什么区别?动态引入有什么注意点?
2.1 概念
静态资源引入:public中的资源需要使用绝对路径直接引用,路径直接写文件名即可;;assets中的资源引入需要使用相对路径,也可以使用@代表src文件夹的绝对路径;
动态资源引入:public中的资源使用动态引入与静态资源引入一样,都是使用绝对路径字符串引入即可;assets则不同,动态资源引入需要使用require函数,函数参数是相对路径的字符串格式的地址或者@代表src的绝对路径地址;
2.2 代码演示
<template>
<div>
<h1>静态引入资源</h1>
<img src="favicon.ico" alt="">
<img src="@/assets/logo.png" alt="">
<h1>动态引入资源</h1>
<img :src="imgUrl1" alt="">
<img :src="imgUrl2" alt="">
</div>
</template>
export default {
data(){
return{
imgUrl1:'favicon.ico',
imgUrl2:require('@/assets/logo.png')
}
}
}
这里代码是在脚手架快速搭建的项目中。component中的helloWorld中进行测试。
3.Vue中搭建代理服务器
3.1 代理服务器
由于浏览器的同源策略的限制,所以在使用浏览器去请求数据时候常常会因为跨域问题,导致数据请求不到;但是在服务端则没有限制,所以前端想要去目标服务器请求获取数据去渲染页面时,代理服务器将前端请求拦截下来,将请求地址和路径进行重写,然后打开跨域请求,再由代理服务器去发请求,获取结果后,将结果返回给前端,这就是代理服务器的原理;
3.2 配置代理服务器
在vue.config,js文件中添加配置对象,然后进行配置设置;
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true, //如果该字段为true 接着去查看package.json的browserslistrc是否在低级浏览器范围内
// 如果处于低级浏览器范围内 会把node_modules 下载的第三方高级的代码的写法进行babel转换
// 如果字段设置为false,会把node-modules第三方高级的代码写法原封不动进行打包,会导致低级浏览器访问报错的问题
publicPath:"/" ,// 启动页地址
outputDir:"dist" ,// 打包之后的文件名
lintOnSave:false , // 保存的时候是否检查语法
productionSourceMap: false, // 生产环境是否生成 SourceMap
// 1.添加devServe配置对象,开发环境服务器配置
devServer:{
// 服务器运行后,浏览器可以自动打开
open:true,
// 配置主机地址
host:"localhost",
// 配置端口号
port:"8080",
// 配置代理服务器
proxy:{
// 属性发请求时候为路径添加路径前缀,eg:http://m.douyu.com/api/rppm/list?page=10
// /myDouyu一般会加在服务器地址的后面 /myDouyu/api/room/list?page=10
"/myDouyu":{
target:"http://m.douyu.com/" , //目标服务器地址
pathRewrite:{
"^/myDouyu":"" //路径重写
},
changeOrigin:true //实现跨域 改变请求源
}
}
// 这是一个请求酷我音乐的配置
//proxy: {
// "/kuwo": {
// target: "http://www.kuwo.cn",
// changeOrigin: true,
// pathRewrite: {
// "^/kuwo": ""
// },
// 添加请求头
// onProxyReq: function (proxyReq, req, res) {
// proxyReq.setHeader('Cookie', 'kw_token=W1JK96FJ6R')
// proxyReq.setHeader('csrf', 'W1JK96FJ6R')
// }
// },
// }
}
})
4.vue路由守卫与vue生命周期函数
4.1 keep-alive与vue生命周期函数activated
在使用router-link进行路由导航跳转传值时,每一次的路由导航跳转传值都会经历闯将到销毁的完整时间周期;但是如果使用keep-alive标签将route-view标签包裹,则每一个路由导航传值智慧经历一次创建和销毁;而路由跳转传值则会触发
beforeCreate created 创建实例前 / 后的执行的钩子函数
beforeMount mounted 组件模板挂载到页面前/ 后的执行的钩子函数
beforeUpdate updated 数据更新前 / 后执行的钩子函数
beforeDestroy destroyed 组件销毁之前 / 后执行的钩子函数
activated deactivated 组件激活 / 失活时候执行的钩子函数;在使用keep-alive将route-view标签包裹后,进行路由跳转时候触发;
errorCaptured 当子孙组件出现错误的时候触发;
4.2 vue 路由守卫
4.2.1 路由守卫的分类及作用
导航守卫:分为三种守卫 全局守卫(3个) 路由独享守卫(1个) 组件守卫(3个)
全局守卫:在路由文件下index.js文件下定义,使用路由调用此三个函数,分别为beforeEach、beforeResolve、afterEach;
路由独享守卫:在路由文件下路由配置对象的routes字段的设置匹配规则的对象中使用该函数,只有一个是beforeEnter;
组件守卫:在views文件夹下的组件对象中; 分别为beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave;
作用:1.路由拦截(例如页面再范围个牛的时候需要登录的验证,如果登录过了,直接显示,没有登录,现在去登录界面);
2.还可以终止路由跳转;
4.2.2 代码演示
#index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
,beforeEnter: (to, from, next) => {
console.log('路由独享守卫,在我们进入路由之前触发');
next()
}
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
// 全局守卫需要再路由器文件下进行定义
// to属性 是目标路由对象
// from属性 从哪个路由跳转过来
// next函数 函数交给下一个路由守卫进行执行
// 如果回调函数里面添加next参数 需要手动调用next函数,如果不加next,则可以直接触发下一个钩子函数,next可以实现终止路由跳转
router.beforeEach((to,from,next)=>{
//全局的前置守卫可以进行登录界面是否要显示,例如个人中心,购物车,收藏等界面需要登录之后才能访问,可以再改守卫添加判断;
console.log('全局前置守卫 beforEach,只要路由发生变化,钩子函数就会被触发,类似watch监听$route的变化');
next();
})
router.beforeResolve((to,from,next)=>{
console.log('全局解析守卫');
next()
})
router.afterEach((to,from,next)=>{
console.log('全局后置守卫可以理解为导航跳转过程的最后一个守卫,钩子函数不同添加next函数的调用');
})
export default router
// #AboutView.vue
export default{
// 组件内的守卫定义在路由界面里面
// 发请求除了在created还可以在beforeRouteEnter里面发请求;
beforeRouteEnter (to, from, next) {
console.log('进入路由组件之前触发',this,11111);
next(vm=>console.log(`afterEach后置守卫执行完之后会把组件实例this传进beforeRouterEnter的next回调里面,参数就是this组件对象`,vm,111111))
next();
},
beforeRouteUpdate(to,from,next){
console.log(`当前路由组件更新的时候,当动态路由发生变化的时候,
或者是拼接字符串传数据的这个数据发生变化,
about/?name = 213 =>about/?name = 345`);
next()
},
beforeRouteLeave (to, from, next) {
console.log('离开这个路由组件之前触发,一般会在此钩子函数中寻味是否要离开该页面');
var answer = window.confirm('确认离开吗?')
if(answer){
next();
}else{
// 停留在该页面路由不能在跳转
next(false); // 终止跳转
}
},
beforeCreate(){
console.log(this,22222);
},
created(){
console.log(this,3333);
}
}
4.2.3 导航守卫的过程
导航守卫的过程
1.先在失活的组件里面先去执行组件离开的守卫(beforeRouteLeave)
2. 调用全局的前置守卫(beforeEach)
附加:会去执行组件守卫的beforeRouteUpdate
3. 执行路由独享守卫(beforeEnter)
4. 执行进入组件内的守卫(beforeRouteEnter)
5. 执行全局解析守卫(beforeResolve)
6. 执行全局后置守卫(afterEach)
7. 最后把afterEach的this传递到组件内部this对象里面