关于在组件的局部作用域引入css样式
-
1. 通常使用做法:
在组件内部script标签内引入, 会在该组件运行时被加载, 并暴露到全局, 对同时运行在实例中的的兄弟及父组件页面, 可能会造成样式污染的问题
-
2. 推荐在引入第三方css资源时使用的做法:
在组件内部加有scoped
属性的style
标签内部, 并且最好在该组件最外层容器的内部进行引入; 前提是要使用scss或者less预处理器进行编译, 否则无法这样在选择器内引入css文件
-
3. 针对在组件中单独引入bootstrap.css但加scoped属性引入无效, 造成无法实现局部引入bootstrap的处理方式
问题描述: 在项目中, 尝试在组件内单独引入bootstrap, 使用第二种方式,并无法实现, 有两个问题:- 加scoped属性会造成bootstrap样式引入无效, 故需取消scoped属性,
- 虽然取消了scoped 属性,可以成功引入样式, 但在组件内部容器引入bootstrap.css文件, 并无法形成单独的作用域,
解决方法: 当前使用的预处理器为scss, 同时在bootstrap-npm包中也提供有scss样式资源, 需直接引入.scss样式文件, 在vue解析的时候, 会通过预处理器 按照书写及引入的先后顺序编译样式同时引入资源, 引入的样式会全部在所在组件容器里进行编译及渲染, 从而形成单独的作用域
关于异步路由与异步组件
异步路由
使用异步路由可以根据URL自动加载所需页面的资源, 并且不会造成页面阻塞,较适用于移动端页面, 建议主页面直接import, 非主页可使用异步路由
// 使用方式 :
{
path: '/order',
component: () => import('./views/order.vue')
}
异步组件
不需要首屏加载的组件都可以使用异步组件的方式来加载, 包括需要触发条件的动作也使用异步组件(如弹框), 用v-if来控制显示时机, 引入组件的promise即可
演示:
// 在异步子组件中,mounted 函数中是无法获取到子组件的实例的,所以我们需要对组件异步加载做了一些特殊的控制,
// 其中 import().then() 则是在加载完子组件的 .js 文件后,实例化子组件之前的回调,
// 如果需要处理出错的情况,则 import().then().catch() 即可。
// 以上代码只是注入了一个 created 函数,如果要注入其他生命周期函数,例如 mounted,也是类似的:
<template>
<div>
<my-demo ref="demo"></my-demo>
</div>
</template>
<script>
export default {
components: {
MyDemo: () => import('./Demo').then(component => {
// 清理已缓存的组件定义
component.default._Ctor = {}
if (!component.default.attached) {
// 保存原组件中的 created 生命周期函数
component.default.backupCreated = component.default.created
// 保存原组件中的 mounted 生命周期函数
component.default.backupMounted = component.default.mounted
}
// 注入一个特殊的 created 生命周期函数
component.default.created = function() {
// 子组件已经实例化完毕
// this 即为子组件 vm 实例
console.log(this)
if (component.default.backupCreated) {
// 执行原组件中的 created 生命周期函数
component.default.backupCreated.call(this)
}
}
// 注入一个特殊的 mounted 生命周期函数
component.default.mounted = function() {
if (component.default.backupMounted) {
// 执行原组件中的 mounted 生命周期函数
component.default.backupMounted.call(this)
}
}
// 表示已经注入过了
component.default.attached = true
return component
})
}
}
</script>