vue-router进阶:路由使用归纳、路由导航守卫、导航守卫解析流程、

一、定义和理解

导航守卫的作用vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。

》》项目中应用场景举例:路由页面跳转时候进行登陆验证;路由跳转判断;

 

有多种机会植入路由导航过程中全局路由, 单个路由独享的, 或者组件级的

全局守卫包括:router.beforeEach(是全局前置守卫)、router.beforeResolve(是全局解析守卫)、router.afterEach(是全局后置钩子)

单个路由独享的导航守卫:在路由配置上直接定义 beforeEnter 守卫

组件内守卫包括:在组件内定义路由的导航守卫,有beforeRouteEnter 、beforeRouteUpdate 、beforeRouteLeave

 

每个导航守卫都接受3个参数 from 、to、next() ,参数的定义如下:

to: Route: 即将要进入的目标 路由对象

from: Route: 当前导航正要离开的路由

next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

    next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。

    next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那  么 URL 地址会重置到 from 路由对应的地址。

    next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: 'home' 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。

    next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

 

注意事项:

1、确保要调用 next 方法,否则钩子就不会被 resolved。

2、当一个导航触发时,导航守卫按照顺序调用。守卫是异步解析执行,导航在所有守卫 resolve 完之前一直处于 等待中

 

 

二、导航守卫使用

 

首先vue-router知识回顾:

0、在vue项目中使用vue-router步骤概述:

// 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }// 2. 定义路由
// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
// 我们暂时不套路讨论嵌套路由、传参、元数据、导航守卫等。
const routes = [{ path: '/foo', component: Foo },{ path: '/bar', component: Bar }
]// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({routes // (缩写) 相当于 routes: routes
})// 4. 创建和挂载根实例。
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({router
}).$mount('#app')// 现在,应用已经启动了!

 

1、可以在任何组件内通过 this.$router 访问路由器,也可以通过 this.$route 访问当前路由:

// Home.vue
export default {computed: {username () {// 我们很快就会看到 `params` 是什么return this.$route.params.username}},methods: {goBack () {window.history.length > 1? this.$router.go(-1): this.$router.push('/')}}
}

 

2、动态路由匹配时使用this.$route.params获取路由的路径参数

应用场景:需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。又像 /user/foo 和 /user/bar 都将映射到相同的路由。

 

注意:可以在一个路由中设置多段“路径参数”,如下:

模式匹配路径$route.params
/user/:username/user/evan{ username: 'evan' }
/user/:username/post/:post_id/user/evan/post/123{ username: 'evan', post_id: '123' }

当使用路由参数时,例如从 /user/foo 导航到 /user/bar原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用

参数或查询的改变并不会触发进入/离开的导航守卫。可以通过观察 $route 对象来应对这些变化,或使用  beforeRouteUpdate 的组件内守卫。

 

3、复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route 对象:

const User = {template: '...',watch: {'$route' (to, from) {// 对路由变化作出响应...}}
}

或者使用 2.2 中引入的 beforeRouteUpdate 导航守卫:

const User = {template: '...',beforeRouteUpdate (to, from, next) {// react to route changes...// don't forget to call next()}
}

 

4、在router配置文件中使用通配符 (*)捕获所有路由或 404 Not found 路由

注意:通常含有通配符的路由应该放在最后。路由 { path: '*' } 通常用于客户端 404 错误。如果你使用了History 模式,请确保正确配置你的服务器。

同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:谁先定义的,谁的优先级就最高

当使用一个通配符时,$route.params 内会自动添加一个名为 pathMatch 参数。它包含了 URL 通过通配符被匹配的部分:

// 给出一个路由 { path: '/user-*' }
this.$router.push('/user-admin')
this.$route.params.pathMatch // 'admin'
// 给出一个路由 { path: '*' }
this.$router.push('/non-existing')
this.$route.params.pathMatch // '/non-existing'

 

5、使用vue-router嵌套路由时,在路由定义文件中使用children 配置:

注意事项:以 / 开头的嵌套路径会被当作根路径。 这让你充分的使用嵌套组件而无须设置嵌套的路径。

const router = new VueRouter({routes: [{ path: '/user/:id', component: User,children: [{// 当 /user/:id/profile 匹配成功,// UserProfile 会被渲染在 User 的 <router-view> 中path: 'profile',component: UserProfile},{// 当 /user/:id/posts 匹配成功// UserPosts 会被渲染在 User 的 <router-view> 中path: 'posts',component: UserPosts}]}]
})

 

6、vue-router路由导航可以在组件中使用<router-link :to="..."> 的形式外,还有JS编程式的导航(包括可以调用 this.$router.push(location, onComplete?, onAbort?) 和 router.replace(location, onComplete?, onAbort?),以及router.go(n) )

注意事项:

  • 如果提供了 pathparams 会被忽略;
  • 如果目的地和当前路由相同,只有参数发生了改变 (比如从一个用户资料到另一个 /users/1 -> /users/2),你需要使用 beforeRouteUpdate 来响应这个变化 (比如抓取用户信息);
  • router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。router.replace 方法它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。
  • 在 2.2.0+,可选的在 router.push 或 router.replace 中提供 onComplete 和 onAbort 回调作为第二个和第三个参数。这些回调将会在导航成功完成 (在所有的异步钩子被解析之后) 或终止 (导航到相同的路由、或在当前导航完成之前导航到另一个不同的路由) 的时候进行相应的调用。
const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)// 后退一步记录,等同于 history.back()
router.go(-1)

router.push、 router.replace 和 router.go 跟 window.history.pushState、 window.history.replaceState 和 window.history.go好像, 实际上它们确实是效仿 window.historyAPI 的。

 

7、当需要在一个组件页面展示多个路由视图 router-view ,需要给视图命名:

<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>
const router = new VueRouter({routes: [{path: '/',components: {default: Foo,a: Bar,b: Baz}}]
})

注意:正确使用 components配置 (带上 s):

 

8、vue-router路由重定向和别名使用

“重定向”的意思是,当用户访问 /a时,URL 将会被替换成 /b,然后匹配路由为 /b;重定向不能指向自身,会形成死循环。

“别名”的意思是给路由取“小名”,/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。

const router = new VueRouter({routes: [{ path: '/a', redirect: '/b' },{ path: '/b', redirect: { name: 'foo' }},{ path: '/c', redirect: to => {// 方法接收 目标路由 作为参数// return 重定向的 字符串路径/路径对象}},{ path: '/a', component: A, alias: '/b' }]
})

 

9、vue-router使用路由进行组件传参时,通过props取代 $route.params 可以降低耦合度:

注意:在组件中使用 $route 会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,限制了其灵活性。通过props取代,这样你便可以在任何地方使用该组件,使得该组件更易于重用和测试。

如果 props 被设置为 trueroute.params 将会被设置为组件属性。

const User = {  //$route 的耦合template: '<div>User {{ $route.params.id }}</div>'
}
const router = new VueRouter({routes: [{ path: '/user/:id', component: User }]
})const User = { //通过 props 解耦props: ['id'],template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({routes: [{ path: '/user/:id', component: User, props: true },// 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:{path: '/user/:id',components: { default: User, sidebar: Sidebar },props: { default: true, sidebar: false }}]
}) 

如果 props 是一个对象,它会被按原样设置为组件属性。当 props 是静态的时候有用。

const router = new VueRouter({routes: [{ path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }]
})

 

你可以创建一个函数返回 props。这样你便可以将参数转换成另一种类型,将静态值与基于路由的值结合等等。

const router = new VueRouter({routes: [{ path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }]
})

 

 

开始导航守卫使用demo:

注意事项:注意导航守卫并没有应用在跳转路由上,而仅仅应用在其目标上。

1、全局前置守卫 router.beforeEach

const router = new VueRouter({ ... })router.beforeEach((to, from, next) => {// ...
})

 

2、全局解析守卫 router.beforeResolve

在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。

 

 

3、全局后置钩子router.afterEach

和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

router.afterEach((to, from) => {// ...
})

 

4、路由独享的守卫router.beforeEnter

是在路由配置上直接定义 beforeEnter 守卫:

const router = new VueRouter({routes: [{path: '/foo',component: Foo,beforeEnter: (to, from, next) => {// ...}}]
})

 

5、组件内的守卫 beforeRouteEnter、beforeRouteUpdate (2.2 新增)、beforeRouteLeave

const Foo = {template: `...`,beforeRouteEnter (to, from, next) {// 在渲染该组件的对应路由被 confirm 前调用// 不!能!获取组件实例 `this`// 因为当守卫执行前,组件实例还没被创建},beforeRouteUpdate (to, from, next) {// 在当前路由改变,但是该组件被复用时调用// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。// 可以访问组件实例 `this`},beforeRouteLeave (to, from, next) {// 导航离开该组件的对应路由时调用// 可以访问组件实例 `this`// 一般来控制弹框和跳转。}
}

关于beforeRouteEnter 守卫 不能 访问 this的解决方式是:通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。

注意:beforeRouteEnter 是支持给 next 传递回调的唯一守卫。对于 beforeRouteUpdate 和 beforeRouteLeave 来说,this 已经可用了,所以不支持传递回调,因为没有必要了。

beforeRouteEnter (to, from, next) {next(vm => {// 通过 `vm` 访问组件实例})
}

 

这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。

beforeRouteLeave (to, from , next) {const answer = window.confirm('Do you really want to leave? you have unsaved changes!')if (answer) {next()} else {next(false)}
}

 

 

三、导航守卫解析流程:

  1. 导航被触发。
  2. 在失活的组件里调用离开守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  5. 在路由配置里调用 beforeEnter
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫 (2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

 

 

 

四、其他:路由元信息、过渡动效、数据获取、滚动位置、懒加载

 

路由元信息:

定义路由的时候可以设置meta字段,可以存储该路由相关信息(例如:设置每个路由的title,取路由的title设置为选项卡的标题);还可以用来设置页面权限要求

 {path: '/router2',name: 'router2',component:router2,meta:{title:"router2"}}
// 全局前置守卫
router.beforeEach((to,from,next) => {console.log(to);console.log(from);if(to.meta.title) {document.title = to.meta.title;} else {document.title = '我是默认的title'}next();
});

 

 

路由过渡动效:

Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。

const Foo = {template: `<transition name="slide"><div class="foo">...</div></transition>`
}const Bar = {template: `<transition name="fade"><div class="bar">...</div></transition>`
}<!-- 使用动态的 transition name -->
<transition :name="transitionName"><router-view></router-view>
</transition>// 接着在父组件内
// watch $route 决定使用哪种过渡
watch: {'$route' (to, from) {const toDepth = to.path.split('/').lengthconst fromDepth = from.path.split('/').lengththis.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'}
}

 

 

路由数据获取:(分别有导航完成前和完成后获取)

有时候,进入某个路由后,需要从服务器获取数据。例如,在渲染用户信息时,你需要从服务器获取用户的数据。我们可以通过两种方式来实现:

  • 导航完成之后获取:先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示“加载中”之类的指示。
  • 导航完成之前获取:导航完成前,在路由进入的守卫中获取数据,在数据获取成功后执行导航。从技术角度讲,两种方式都不错 —— 就看你想要的用户体验是哪种。

导航完成后获取数据,我们会马上导航和渲染组件,然后在组件的 created 钩子中获取数据。

export default {data () {return {loading: false,post: null,error: null}},created () {// 组件创建完后获取数据,// 此时 data 已经被 observed 了this.fetchData()},watch: {// 如果路由有变化,会再次执行该方法'$route': 'fetchData'},methods: {fetchData () {this.error = this.post = nullthis.loading = true// replace getPost with your data fetching util / API wrappergetPost(this.$route.params.id, (err, post) => {this.loading = falseif (err) {this.error = err.toString()} else {this.post = post}})}}
}

我们在导航转入新的路由前获取数据。我们可以在接下来的组件的 beforeRouteEnter 守卫中获取数据,当数据获取成功后只调用 next 方法。

export default {data () {return {post: null,error: null}},beforeRouteEnter (to, from, next) {getPost(to.params.id, (err, post) => {next(vm => vm.setData(err, post))})},// 路由改变前,组件就已经渲染完了// 逻辑稍稍不同beforeRouteUpdate (to, from, next) {this.post = nullgetPost(to.params.id, (err, post) => {this.setData(err, post)next()})},methods: {setData (err, post) {if (err) {this.error = err.toString()} else {this.post = post}}}
}

 

路由滚动行为:

使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。 vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动。

注意: 这个功能只在支持 history.pushState 的浏览器中可用。

当创建一个 Router 实例,你可以提供一个 scrollBehavior 方法:

const router = new VueRouter({routes: [...],scrollBehavior (to, from, savedPosition) {// return 期望滚动到哪个的位置}
})

scrollBehavior 方法接收 to 和 from 路由对象。第三个参数 savedPosition 当且仅当 popstate导航 (通过浏览器的 前进/后退 按钮触发) 时才可用。

这个方法返回滚动位置的对象信息,长这样:

  • { x: number, y: number }
  • { selector: string, offset? : { x: number, y: number }} (offset 只在 2.6.0+ 支持)

如果返回一个 falsy (译者注:falsy 不是 false,参考这里)的值,或者是一个空对象,那么不会发生滚动。

举例:

scrollBehavior (to, from, savedPosition) {return { x: 0, y: 0 }
}

对于所有路由导航,简单地让页面滚动到顶部。

返回 savedPosition,在按下 后退/前进 按钮时,就会像浏览器的原生表现那样:

scrollBehavior (to, from, savedPosition) {if (savedPosition) {return savedPosition} else {return { x: 0, y: 0 }}
}

如果你要模拟“滚动到锚点”的行为:

scrollBehavior (to, from, savedPosition) {if (to.hash) {return {selector: to.hash}}
}

 

 

路由懒加载:

当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。

一个能够被 Webpack 自动代码分割的异步组件。

const Foo = () => import('./Foo.vue')

在路由配置中什么都不需要改变,只需要像往常一样使用 Foo

const router = new VueRouter({routes: [{ path: '/foo', component: Foo }]
})

 

 

 

五、应用demo

vue路由登陆验证:

前言:vue的项目的登录状态如果用vuex状态管理,页面一刷新vuex管理的状态就会消失,所以,会将登录的状态写到web Storage中进行存储管理。

步骤:

1、router/index.js 》在需要登录验证的路由元信息里加入登录验证标识requiresAuth:true

      routers: [{ path: '/home',name: 'home',component: Home,meta: {  requiresAuth: true  }},{path: '/login',name: 'Login',component: Login},]

2、登陆组件从服务端获取到token,将登录状态写入web Storage里

      login() {this.$api.login().then(function(res) {//调用axios二次封装的login方法,关闭mockjs时会传递到nodejssessionStorage.setItem('accessToken', res.data.token) // 成果返回后放置token到Cookie //console.log("登陆响应",JSON.stringify(res.data));router.push('/home')  // 登录成功,跳转到主页}).catch(function(res) {alert(res);});},

 

3、router/index.js 》再路由配置文件中使用全局前置导航守卫

//全局前置导航守卫,导航跳转前进行token登陆令牌判断
router.beforeEach((to, from, next) => {if(to.path === '/login')  {  next()  }else {if(to.meta.requiresAuth && !sessionStorage.getItem('accessToken')) {next({ path: '/login' })}else { //如果不需要登录验证,或者已经登录成功,则直接放行next() }  }});

 

 

官网API:https://router.vuejs.org/zh/guide/advanced/navigation-guards.html

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/553975.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谷歌浏览器内存不足 Chrome浏览器内存释放技巧分享

谷歌Chrome浏览器内存占用过高的问题一直困扰着不少使用者&#xff0c;除了少用占用内存的扩展插件及控制打开的标签页数量外&#xff0c;还有不少方法可以解决这一问题!下面小编就来分享一个快速释放Chrome浏览器内存的小技巧&#xff0c;小伙伴们可不要错过了。 方法步骤 在…

ChatGPT/GPT4+AI绘图+论文写作+编程结合到底有多强大?带你详细了解

ChatGPT在论文写作与编程方面具备强大的能力。无论是进行代码生成、错误调试还是解决编程难题&#xff0c;ChatGPT都能为您提供实用且高质量的建议和指导&#xff0c;提高编程效率和准确性。此外&#xff0c;ChatGPT是一位出色的合作伙伴&#xff0c;可以为您提供论文写作的支持…

月亮的传说故事

古时候&#xff0c;有个地方夜晚总是漆黑一片&#xff0c;天空就像笼罩着一块黑布。因为在这里&#xff0c;月亮从来没有升起过&#xff0c;星星也不闪烁。其实在上帝创造世界时&#xff0c;晚上还是很明亮的。 有一次&#xff0c;有四个年轻人离开了这片国土&#xff0c;来到…

mockjs语法规范、设置mockjs拦截响应时间、Mock.Random占位符生成随机数据

首先回顾vue-cli项目中使用mockjs步骤&#xff1a; 1、安装mockjs、axios&#xff08;http请求库&#xff09;&#xff1b; cnpm install mockjs axios --save 2、在项目中新建一个mock.js文件&#xff0c;用于定义接口返回的数据&#xff1b; const Mock require(mockjs) …

vue-cli项目布署问题解决:空白页、静态资源文件404错误、refrenceError:promise未定义(部分浏览器不支持ES6语法)

&#xff08;前言&#xff1a;文章记录vue-cli项目打包使用IIS布署遇到的几个错误及解决方式&#xff09; 首先简单理解webpack打包&#xff1a; 个人理解&#xff1a;项目开发中我们构建 "低耦合高内聚" 的组件/模块来代码重用、降低项目复杂性&#xff0c;提升开发…

优酷视频APP的缓存视频在哪里

针对喜爱刷剧的网民&#xff0c;要是有空余就爱播放视频&#xff0c;但是视频会应用很多的总流量&#xff0c;这应该怎么办呢?我们可以在有Wifi的地区把视频缓存到手机里&#xff0c;随后在沒有wifi的地区看缓存文件的含有就可以了。下边就一起来看一下怎样缓存文件优酷吧。 …

转:javascript方法--bind()

javascript方法--bind() bind方法&#xff0c;顾名思义&#xff0c;就是绑定的意思&#xff0c;到底是怎么绑定然后怎么用呢&#xff0c;下面就来说说我对这个方法的理解。 语法 fun.bind(this,arg1,arg2,...) bind()方法会创建一个新的函数&#xff0c;称为绑定函数,fun方法…

win7系统每次开机都需要疑难解答的原因与解决方法

最近有些win7旗舰版的用户发现自己的电脑每次开机都无法正常连接网络&#xff0c;需要自己手动点击一下疑难解答才可以恢复正常连接&#xff0c;非常麻烦&#xff0c;那么Win7旗舰版系统每次开机都需要疑难解答怎么办呢?下面小编就给大家带来了win7系统每次开机都需要疑难解答…

Win7旗舰版禁止修改文件属性的设置方法

大家都知道文件有只读、隐藏和存档三个属性&#xff0c;但是属性默认是可以修改的&#xff0c;如果一不小心修改错误的话&#xff0c;就可能导致文件丢失、损坏、被隐藏等等。为了避免这些问题的发生&#xff0c;我们可以禁止修改文件属性来保护文件的安全&#xff0c;下面介绍…

npm error enoent:no such file or directory...are-we-there-yet ; package.json文件和node_modules模相互转化

vue-cli项目一段时间没有变动&#xff0c;几个星期后继续编辑安装 npm install vue-skeleton-webpack-plugin 插件时报错 npm error enoent:no such file or directory...are-we-there-yet 错误 产生错误的原因&#xff1a;This is still an active issue on Modulus. Ive fo…

简单地使用webpack进行打包,一些常见打包错误

本质上&#xff0c;webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时&#xff0c;它会递归地构建一个依赖关系图(dependency graph)&#xff0c;其中包含应用程序需要的每个模块&#xff0c;然后将所有这些模块打包成一个或…

win7空文件夹删不掉的原因及解决方法

大家在清理系统垃圾的时候&#xff0c;会发现有些文件夹明明已经空了但是就是删不掉&#xff0c;时间长了电脑就会积累很多空的文件夹&#xff0c;拖慢电脑的运行速度。Win7系统中空文件夹删不掉怎么解决?就此问题&#xff0c;下面跟大家分析一win7空文件夹删不掉的原因及解决…

(亲测)vue-cli项目添加骨架屏多种方式,自动生成骨架屏

vue-cli项目首页加载缓慢想要使用骨架屏效果&#xff0c;经过几天的踩坑&#xff0c;这里学习并记录一下vue项目自动生成骨架屏方法。 添加骨架屏&#xff0c;其优势在于&#xff1a; 写于HTML文件中&#xff0c;独立于Vue框架&#xff0c;节省了JS加载时间JS全局环境创建的执…

win7系统屏幕键盘打开教程

我们在电脑没有接入键盘或者键盘失灵等情况下&#xff0c;如果想要输入内容&#xff0c;可以使用系统自带的屏幕键盘。只需要在控制面板中打开屏幕键盘就可以使用了&#xff0c;下面就让我们一起看看win7系统屏幕键盘打开教程吧。 1、首先点击左下角的“开始”&#xff0c;在右…

Vue-cli 项目优化归纳(打包、源码、用户体验)

前言&#xff1a;vue-cli项目开发打包部署后&#xff0c;存在问题有首次首页加载过慢&#xff0c;包括加载缓慢问题&#xff0c;需要进行vue项目优化。下面是对vue性能优化方法进行归纳&#xff0c;后面会对方法进行亲测。 主要包括&#xff1a;代码包打包优化、编码优化、用户…

win7系统图标太大的缩小教程

win7系统图标太大怎么办?图标大小直接影响了系统的第一观感&#xff0c;一个大小合适的图标能够让用户在使用时拥有更舒服的操作体验&#xff0c;也能在一定程度上避免视力和精神的消耗。一般来说图标不宜太大&#xff0c;如果太大了我们可以将它缩小&#xff0c;下面就一起看…

JS中的prototype、__proto__与constructor,原型和原型链

理解原型的几个关键点&#xff1a; 1、所有的引用类型&#xff08;数组、函数、对象&#xff09;可以自由扩展属性&#xff08;除null以外&#xff09;; 2、所有的引用类型&#xff08;对象&#xff09;都有一个’_ _ proto_ _属性(也叫隐式原型&#xff0c;它是一个普通的对…

win7系统图标异常修复方法

我们在使用win7的时候有可能会碰到图标异常的情况&#xff0c;一般来说都是因为误操作了某些程序或者被某些软件暗改了&#xff0c;这时候我们需要手动去重新设置一下图标&#xff0c;方法也很简单&#xff0c;下面就一起看看win7系统图标异常修复方法吧。 win7系统图标异常修…

彻底理解cookie,session,token

转载自&#xff1a;https://www.cnblogs.com/moyand/p/9047978.html 发展史 1、很久很久以前&#xff0c;Web 基本上就是文档的浏览而已&#xff0c; 既然是浏览&#xff0c;作为服务器&#xff0c; 不需要记录谁在某一段时间里都浏览了什么文档&#xff0c;每次请求都是一个新…

硬盘基本知识(磁头、磁道、扇区、柱面),格式化容量计算

计算差&#xff1a; 在购买硬盘之后&#xff0c;细心的人会发现&#xff0c;在操作系统当中硬盘的容量与官方标称的容量不符&#xff0c;都要少于标称容量&#xff0c;容量越大则这个差异越大。标称40GB的硬盘&#xff0c;在操作系统中显示只有38GB&#xff1b;80GB的硬盘只有7…