1,路由配置导入不同的组件,如果项目太大了,一个个引入太繁杂了。
const routers= [];
const files = require.context('./routers', false, /\.js$/);
files.keys().forEach(key => {
routers.push(...files(key).default)
})
// 获取到文件的内容,拿到默认的导出结果,放到最开始的routers文件夹中,如果遇到*,路由会被放到最后面
2,vue里面处理computed的方法
export const forEachValue = (obj, callback) => {
Object.keys(obj).forEach(key => callback(obj[key], key))
}
forEachValue(options.getter, (fn, key) => {
computed[key] = () => {
return fn(this.state);
}
Object.defineProperty(this.getters, key, {
get: () => this._vm[key]
})
})
3,vuex里面可以使用createNamespacedHelpers函数获取某个命名空间里面的state getter等
import {createNamespacedHelpers} from 'vuex';
let [mapState, mapGetter] = createNamespacedHelpers('myName');
// 函数里面传入的就是命空间,会返回这个命名空间里面的的state和getter
4,vuex的模块化引入module文件处理
// rootModule是vuex的主入口文件配置
const files = require.context('./module', false, /\.js$/);
files.keys().forEach(key => {
let moduleName = key.replace(/\.\//, '').replace(/\.js/, '');
let store = files(key).default;
let module = rootModule.modules = (rootModule.modules || {});
module[moduleName] = store;
module[moduleName].namespaced = true;
})
5,nodejs打包的一些配置
const args = process.argv.slice(2);
// 可以获取到npm 运行的script命令的参数,arg取到的值是一个数组,可以用来判断不同环境下不同的打包参数
const path = require('path');
path.resolve(dir);
// 获取文件夹的绝对路径
const fs = require('fs');
fs.readdirSync(absPath, options);
// 用于同步读取给定目录的内容。该方法返回一个数组,其中包含目录中的所有文件名或对象。 options参数可用于更改从方法返回文件的格式。
new File(path).isDirectiory()
// 判断传入的路径是否是一个文件夹
6,Object.isExtensible()
方法判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。
7, $route.matched 一个数组,包含当前路由的所有嵌套路径片段的路由记录 。路由记录就是 routes 配置数组中的对象副本 (还有在 children 数组)。
const router = new VueRouter({
routes: [
// 下面的对象就是路由记录
{ path: '/foo', component: Foo,
children: [
// 这也是个路由记录
{ path: 'bar', component: Bar }
]
}
]
})
router.isReady() 当路由器完成初始化导航时,返回一个 Promise,这意味着它已经解析了所有与初始路由相关的异步输入钩子和异步组件。如果初始导航已经发生了,那么 promise 就会立即解析。这在服务器端渲染中很有用,可以确保服务器和客户端的输出一致。需要注意的是,在服务器端,你需要手动推送初始位置,而在客户端,路由器会自动从 URL 中获取初始位置。
// 将
router.onReady(onSuccess, onError)
// 替换成
router.isReady().then(onSuccess).catch(onError)
// 或者使用 await:
try {
await router.isReady()
// 成功
} catch (err) {
// 报错
}
8,router-view的原理
rputer-view本质上是一个函数式的组件,functional: true。函数式组件是无状态的,里面
不能访问this,然后会在组件的render函数执行过程中拿到当前使用了router-view组件的
$router.mached。拿到当前组件的parent组件,判断当前的parent.$Vnode是否为
router-view,然后把路由匹配到的组件的_Vnode挂载到router-view里面。
PS:函数式组件的用处在于创建动态的标题,或者再流程系统中,创建统一的头部或者底部区域。
9,循环创建列表或者表单内容的时候,最好不要用index作为组件的key,最好用后端返回的唯一id作为key。
因为一个列表做循环渲染,如果是正常的顺序,index就是0,1,2,3,4,如果我们给数组做了个倒
序处理,这个时候diff算法就会把页面上列表全部重新创建,而不是复用,而我们需要的是复用之前
已经创建好的列表项。还有如果是删除节点的时候,也会因为删除的项的key不是按顺序来的,就会
导致vue感知不到变化,错误的复用了节点。
PS:此外也别用随机数作为key,因为随机数每一个都不一样,会导致没有复用的情况,性能开销比较大。
diff的特点是同层比较,首先比较新旧父级是否是相同节点,是的话就对比子节点,不是的话就销毁重建。
父级是相同节点就对比子节点,新的有children,旧的没有,就直接新增子节点。新的没有children,
旧的有,就删除子节点。新旧都有children,就进入diff算法对比。
比对节点是否复用其中就有比较key一步,先比较vnode的tag,再比较key等等。
10,router.getMatchedComponents(url)
用来获取传入的url下匹配到的所有的组件component。
该方法现在被删除,因为匹配的组件可以从 router.currentRoute.value.matched
中获取:
router.currentRoute.value.matched.flatMap(record =>
Object.values(record.components)
)