Ant Design of Vue 学习 svn本地服务器 svn客户端 本地发布 ‘isRootMenu‘ is underfined
目录一.设计语言学习1. 版本要求2. 按需引入文件配置的2种方式3. 组件列表4.引入单个组件注意5.配置.babelrc二.搭建项目1.安装vue的脚手架 vue/cli (vue/cli2版)2.新建项目3.版本控制(1). 安装svn服务端(2). 发布到svn服务器4.开发项目步骤、一些配置和一些注意文件的用途(1). 端口...
目录
1.安装vue的脚手架 vue/cli (vue/cli2版)
(2). 因为路由的路径要保存到store中,所以要在router/index.js中引入 store
(4). 在未真正从后台取数前,或许可以使用mock随机生成数据。
(7). 配置component、动态路由数据、加载到router中
前言:一下一切都是我摸索中写的,不一定对,如果有写的不对,会误导大家的地方,请前辈们指正。
一.设计语言学习
1. 版本要求
(1). 现代浏览器和 IE9 及以上(需要 polyfills)
对于 IE 系列浏览器,需要提供 es5-shim 和 es6-shim 等 Polyfills 的支持。
如果你使用了 babel,强烈推荐使用 babel-polyfill 和 babel-plugin-transform-runtime 来替代以上两个 shim。
( 避免同时使用 babel 和 shim 两种兼容方法,以规避 #6512 中所遇问题 )
(2). ant-design-vue v1.3.8 稳定版
(3). Node.js v8.9 或以上
2. 按需引入文件配置的2种方式
(1). 使用 babel-plugin-import(推荐)。babel-plugin-import 是一个用于按需加载组件代码和样式的 babel 插件。
// .babelrc or babel-loader option
{
"plugins": [
["import", { "libraryName": "ant-design-vue", "libraryDirectory": "es", "style": "css" }] // `style: true` 会加载 less 文件
]
}
注意:webpack 1 无需设置
libraryDirectory
。
然后只需从 ant-design-vue 引入模块即可,无需单独引入样式。等同于下面手动引入的方式。
// babel-plugin-import 会帮助你加载 JS 和 CSS
import { DatePicker } from 'ant-design-vue';
这个配置在类似vue-cli@2的 .babelrc文件中
https://www.jb51.net/article/135232.htm https://www.cnblogs.com/wulinzi/p/8079509.html
(2). 手动引入
import DatePicker from 'ant-design-vue/lib/date-picker'; // 加载 JS
import 'ant-design-vue/lib/date-picker/style/css'; // 加载 CSS
// import 'ant-design-vue/lib/date-picker/style'; // 加载 LESS
3. 组件列表
https://github.com/vueComponent/ant-design-vue/blob/master/site/components.js
4.引入单个组件注意
(1). 在开发时,import { Button } from 'ant-design-vue';
的写法会引入了 antd 下所有的模块,
这会影响应用的网络性能。( 因为from的时候是从所有中找,就会先把所有都加载了。)
可以通过以下的写法来按需加载组件。
import Button from 'ant-design-vue/lib/button';
import 'ant-design-vue/lib/button/style'; // 或者 ant-design-vue/lib/button/style/css 加载 css 文件
(2). 如果你使用了 babel,那么可以使用 babel-plugin-import 来进行按需加载,加入这个插件后。你可以仍然这么写:
import { Button } from 'ant-design-vue';
插件会帮你转换成 ant-design-vue/lib/xxx
的写法。另外此插件配合 style 属性可以做到模块样式的按需自动加载。
注意,babel-plugin-import 的
style
属性除了引入对应组件的样式,也会引入一些必要的全局样式。如果你不需要它们,建议不要使用此属性。你可以import 'ant-design-vue/dist/antd.css
手动引入,并覆盖全局样式。
5.配置.babelrc
使用vue-cli@2和vue-cli@3的配置是不同的
如果配置env(环境)字段 https://excaliburhan.com/post/babel-preset-and-plugins.html
transform-es2015-modules-commonjs // 将modules编译成commonjs
二.搭建项目
1.安装vue的脚手架 vue/cli (vue/cli2版)
全局:npm install -g @vue/cli (这是用vue/cli3)
固定文件夹:npm install vue-cli (这个安装的是vue/cli2) 如果安装完了想升级 ,执行一遍 npm install @vue/cli
查看版本 vue -V 或 vue --version
2.新建项目
用vue/cli3:vue create antd-demo
用vue/cli2:vue init webpack ant_design
在问到Vue build时 ,build是项目打包时的命令,use arrow keys(可通过上下键进行选择,通常选一,就是直接回车就可以了)
问Install vue-router,是否初始化路由,选y,路由是必备项
这里问到ESLint时可选y,代码检查,是否用ESLint来校验你的代码。(如果想代码更规范,可选,但比如多一个或少一个空格,都是报警告信息,这个不是必选)。
如果选了yes(一般如果选了NO,别人的代码有一些带空格的校验,你更新别人的代码时,会把空格更新上,就显示很多行代码都更新了,不好判断具体别人都改哪些,需要一条条去找)
第一个选项是标准的,具体校验规则可在网上搜索。
最后一个是自己去配规则,可以自己设置一些规则,同时跟自己编辑器保存自动格式化的规则统一,如果是多人开发,就把workspace setting.json也上传到git,整个项目组的都统一格式化配置。
(这里可选none,以后就只配空格的校验,让代码提交时,自己把空格加上)
Set up unit tests (Y/n) --->是否建立单元测试,不用选,一般用不上
Setup e2e tests with Nightwatch:是否安装e2e测试,不选,一般用不上
Should we run `npm install` for you after the project has been created? (recommended) (Use arrow keys):是否创建完项目就直接自动安装包,如果自己搭着玩,可选y,有其他需求,比如发到服务器上进行管理,供他人下载,就选最后一个,上传服务器后,再手动安装 npm install
没有默认让它安装包,
如果想把项目发布到服务器进行版本管理,建议不要先安装包,
① 因为会生成package-lock.json文件(下面有说)
② 因为上传服务器网速慢,可以先传项目,把项目从服务器检出后,再安装包。
cd到目录下,或者用软件打开项目,如果想加入别的包,可以改变package.json,再安装包 npm install。
初始化的包,生产环境dependencies只有2个包
安装包时,会出现警告提示,一些包的依赖包版本过低,当其他包需要同样的高版本的依赖包时,会安装高版本的包。
警告可略。
提高版本:
browserslist@2.11.3:browserslist 2在读取其他工具中使用的browserslist>3.0配置时可能失败。
查看后,有高版本的。
browserslist 目标浏览器配置表 https://www.jianshu.com/p/bd9cb7861b85。
安装方法:(1). 在安装所有包之前,在package.json中的dependencies中加入
(安装后,再写到文件里,再执行npm install也可以,程序会跳过已安装的包,安装新的包。)
(2). npm install ant-design-vue
(3).安装到生产环境的包,安装时,把包信息写入到package.json中, npm install 包名 -S
npm install Xxx --save 安装模块,并把模块名和版本号添加到dependencies 部分。
npm install xxx --save-dev 安装模块,把模块名和版本号写在devdependencies部分。
-P 相当于 --save-prod, 添加dependencies 里面所有的包。在 -D -O 不存在时,-P 就是默认值
-S 相当于 --save; 添加dependencies 里面所有的包。
-D 相当于 --save-dev; 添加devDependencies 里面所有的包,
-O 相当于 --save-optional, 添加在 optionalDependencies 里面的包,
--no-save: 阻止保存记录在dependencies 中,
卸载包 npm uninstall xxx --save
在项目中:要学习ant design vue ,安装这个包,官网最稳定版本1.3.9 ,但这个可能是针对vue/cli3
所以安装低一点的版本 npm install ant-design-vue@1.3.8 --save
要到后台取数 要安装axios npm install axios@0.18.0 --save
在写界面时,需要用到echart的话,要安装echart npm install echarts --save
需要本地储存一些信息,全局使用,要安装vuex
在安装axios时遇到问题,官网最新版是0.19.0,兼容写的是ie11,不太确定ie11之前的兼容性。
所以选择安装 0.18.0 兼容到ie8以上 https://www.npmjs.com/package/axios/v/0.18.0
一般的包都是用es5写的,具体可以从git上看下源码,也有很少es6写的。比如一些第三方插件。
3.版本控制
(1). 安装svn服务端
在写项目之前,考虑要修改代码,对比不同版本的代码,所以要进行版本控制。
可以选用git 版本控制,但很多项目使用git不安全,所以,可以使用其他方式控制,比如svn。
用码云有免费的私有空间,但以后也许会收费。
在本地安装svn的服务端,作为版本管理的服务器。
在官网下载:https://www.visualsvn.com/server/download/
打开安装
文档:https://www.visualsvn.com/server/getting-started/
可选地,在启动安装之前调整默认配置设置。
- 地点。指定VisualSVNServer安装目录。该选项只能在第一次安装时配置。
- 储存库。指定存储Subversion存储库的根目录。建议在第一次安装时保留默认存储库位置。安装服务器后,可以更改存储库根目录。读这篇文章KB 22如果计划将存储库存储在网络共享上。
- 服务器端口。指定VisualSVNServer将用于通过HTTP(S)访问存储库的TCP端口。安装服务器后,可以更改服务器端口。
- 使用安全连接。指定是否使用安全HTTPS协议访问存储库。建议继续启用HTTPS协议。安装服务器后,可以调整此选项。
- 备份。指定用于Subversion存储库备份的默认目标位置。
VisualSVNServer允许在安装期间选择身份验证模式。有两种身份验证模式:subversion authentication和Windows认证(建议用于ActiveDirectory环境)。读这篇文章KB 39:理解VisualSVN服务器身份验证选项想了解更多信息。
以后可以使用VisualSVN服务器管理器控制台重新配置身份验证模式。注意,在接下来的步骤中,安装程序将生成评估许可证,或者如果选择Windows身份验证,将请求您提供足够的许可密钥,因为在免费社区许可下无法获得此功能。
安装完成打开
新建版本库
有三种储存数据的方式 FSFS 和 BDB 和 VDFS (BDB在新版中以废弃)
区别:https://blog.csdn.net/weixin_34342207/article/details/85744176
VDFS:https://www.visualsvn.com/server/features/multisite-replication/
没有数据锁定,可以立即将现有的基于FSFS的存储库转换为VDFS存储库,反之亦然。
选用基础的FSFS的。
给仓库命名,这个仓库是以后用来存项目的,在新发起项目时,在这个仓库中新建文件或者项目结构,这个之后说。
选择仓库结构,选最基础的
如果选高级:https://blog.csdn.net/mynamepg/article/details/79064304
设置权限,选择默认的了。
点击create
Finish 完成
https://wenku.baidu.com/view/95f3eeaef18583d048645986.html
创建用户
lyq 123456
创建组,并添加成员
给仓库添加权限
如果在上面配置的时候,选customize 这里应该就没有Everyone了。
接下来,把本地的项目配置到SVN的仓库。
(2). 发布到svn服务器
先在服务器端新建个文件或项目结构,用于保存要发布的项目。不建文件夹也能导,会乱七八糟的存在仓库中。
新建文件夹
新建项目结构
如果是项目结构,就多了3个空文件夹
所以,新建个文件夹就行了,结构不用这样的。
有了可以存项目的地方,可以把本地项目导入到服务器了。
安装svn客户端 https://www.visualsvn.com/visualsvn/download/tortoisesvn/
第二个选项默认是没选的,要选第一个,和图无关。为的是安装一个svn.exe文件
右击本地项目 → TortoiseSVN → 导入 → 到服务器地址 ,例如本地的https://LIYQ:9080/svn/ProjectLibrary/ant_design
发布项目时,因为有速度限制,所以开始不要安装包,如果安装了,先把项目的node_modules文件夹的删除,再导出。
写好地址,点击确定
https://LIYQ:9080/svn/ProjectLibrary/ant_design
关于忽略文件:https://blog.csdn.net/hemingwang0902/article/details/6904205
如果需要认证,输入用户名密码,如果不想每次都输,就保存认证,确定
导出完成了
(3). 导出项目到本地
右击要导出的地方,SVN检出(K)
为了和本地的有区别,文件名加_v,表示这是带版本更新的从服务器导出的项目。
导出成功
可以看到,本地的项目和检出的项目的区别,检出的项目带个绿色的对号。
这时,用软件打开,就会看到版本管理了。
原本地项目项目没有版本管理
检出项目有了
完美,可以开始愉快的写项目了 ^_^
可以安装包了,之后的修改,就提交就可以了。
当开发完成,把项目部署到其他服务器时,就打包成服务器能识别的压缩文件。dist 这个以后再研究。
4.开发项目步骤、一些配置和一些注意文件的用途
了解项目的目录:https://blog.csdn.net/zbl744949461/article/details/80433572
(1). 端口
在本地启动服务,先写定合适的端口,防止和本地其他项目冲突。
配置config文件下的index.js 的dev的 port 默认8080。
(2). 做主页
思路:主页考虑做一个主架构,
header有logo,切换页签,用户头像等
左侧有导航菜单,和根据头部的切换页签变化。菜单有收起功能
中间上部有打开tab页有关闭功能,还有当前页的面包屑
中间主体是根据菜单变换的子路由页面
在src文件夹下新建2个文件夹 layout(主页文件) 和 views(子页文件)
在src/assets文件夹下新建css文件,用于存放全局的css设置
layout下有页面 index.vue 和 用到的components(index用到的组件)文件夹 和 error-page(放错误界面)文件夹,
index.vue 中至少先写一个template标签,不然路由时会报错
如果错误页面就只有1、2个,不放文件夹里,单独放出来和index.vue并列也可以。
layout文件夹下是不让用户删除的。
理论上主页可以都写到同一个界面里,但都写在一个界面里,代码很长,不方便多人调试,
为了方便多人调试,做成index.vue和引用的组件一起使用。
pages文件夹下有demo(开发的事例,以后如果用户不需要,删除也可以)文件夹。
(3). 配置路由
默认项目的组件路由指向的是src/assets/components/HelloWorld.vue
假如要改成新的界面 src/layout/index.vue
在router下的index.js修改
import 时,from的是文件夹,会默认找文件夹下的index.vue文件,找不到会报错。
项目要实现从后台获取路由信息,并配置路由。前端实现动态引入组件,并按需加载组件的功能。
所以,先不用import把所有组件导入。
用resolve来回调,resolve 就是 promise 的 resolve 回调,组件加载成功后调用。
这是异步加载组件,当你访问 / ,才会加载 ./layout/index.vue。
如下:
虽然动态调用组件成功了,但组件所用的代码还是会在打包时打包在同一个js文件夹里?,这样执行很慢?
使用 vue-cli构建的项目,在 默认情况下 ,会将所有的js代码打包为一个整体比如index.js。
当使用存在多个路由代码的时候,index.js可能会超大,影响加载速度。
用require.ensure后,这个每个路由页面除了index.js 还会有一个当前路由页面的js这样拆分了index.js的体积。
require.ensure这个函数是一个代码分离的分割线,表示 回调里面的require是我们想要进行分割出去的,
即require('./layout'),把./layout/index.js分割出去,形成一个webpack打包的单独bundle。
可以在①模块执行时才运行代码,只有②在满足某些条件时才加载依赖项。
https://www.cnblogs.com/weiyuanquyu/p/8432044.html
https://webpack.docschina.org/api/module-methods/#require
https://www.jianshu.com/p/9fa38e536033
第一个参数是什么意思呢?[], 其实就是 当前这个 require.ensure所依赖的其他 异步加载的模块。
你想啊?如果A 和 B都是异步加载的,B中需要A,那么B下载之前,是不是先要下载A啊?,
所以ensure的第一个参数[],也是请求下载的模块,如果想加载A require.ensure(['A.js'],function) 即可。
代码如下:(bundle名可以省略)
这只是获取了一个组件,要获得所有的routes,先从后台获取,在通过 router.addRoutes([所有路由数组]),
把所有路由加载进来。
注:路由中如果配置path之类的, 或 有唯一性的值,不要重复,不然菜单获取后会报错,虽然不影响使用,但不好看。
如下,就是有多个path:/form。
(4). 引入组件
在main.js中 引用ant design vue的插件,并注册成全局组件,在任意地方都可以使用。
vue.use()全局注入一个插件,从而不需要在每个组件文件中import插件。
https://segmentfault.com/a/1190000016256277
https://blog.csdn.net/weixin_42283462/article/details/80600623
引入插件 import Antd from 'ant-design-vue'
引入样式 import 'antd-design/dist/antd.css'
全局注册 Vue.use(Antd);
在webstorm软件中显示的安装包文件下没显示这个css文件,但实际目录下有。
引入全局预设样式 import './assets/css/reset.css' 这个./ 指的应该是main.js的相对路径文件夹src
(5). package-lock.json的作用
https://www.cnblogs.com/cangqinglang/p/8336754.html
其实用一句话来概括很简单,就是锁定安装时的包的版本号,
并且需要上传到git,以保证其他人在npm install时大家的依赖能保证一致。
根据官方文档,这个package-lock.json 是在 `npm install`时候生成一份文件,
所以,在项目上传到服务器之前,不要先安装包
5.改变组件样式
当要改变引用的组件渲染后出现元素的样式,私有化的要用到>>>
https://blog.csdn.net/WXY19951125/article/details/83176417
.tagParent 是在引用组件上定义的, .ant-tabs-tab是页面上占时没有、未被初始化的元素。
三.项目开发
1.左侧菜单
分成了3部分做
在index.vue中引入leftMenu组件,在leftMenu中引用submenu组件
ant 的菜单组件,因组件内部会动态更改a-sub-menu的属性,如果拆分成单组件,无法将属性挂载到a-sub-menu上。
官方使用了函数式组件 https://github.com/vueComponent/ant-design-vue/blob/master/components/menu/demo/SubMenu.vue
如果不使用函数式组件,会报错
functional:函数式组件
https://cn.vuejs.org/v2/guide/render-function.html#%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BB%84%E4%BB%B6
2.顶部头菜单
切换顶部头菜单的选项,左侧菜单随之变化。
需要从后台获取菜单数据,并动态生成菜单目录。
考虑到这种数据联动变化,使用vuex全局来管理数据和路由子菜单。
3. vuex全局管理数据
vuex的功能是 读取数据,保存数据,操作数据
keep-alive 的功能是缓存切换路由页面,界面做了操作,切换回来,操作还在。
vuex是一个专门为vue.js设计的集中式状态管理架构。
安装vuex https://vuex.vuejs.org/zh/installation.html
npm install vuex --save
flux 架构: https://facebook.github.io/flux/docs/in-depth-overview.html#content
深入响应原理:https://cn.vuejs.org/v2/guide/reactivity.html
使用步骤: http://www.php.cn/js-tutorial-394689.html
在src文件夹下新建个文件夹vuex,在文件夹下新建文件store.js
在store.js中引用 vue 和 vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vuex.store构造器的使用 https://vuex.vuejs.org/zh/api/
const store = new Vuex.Store({ ...options })
store状态管理有5个核心,分别是state、getter、mutation、action以及module
暂时用其中的三个
const store = new Vuex.Store({
state:{},
getter:{},
mutation:{}
})
导出store
export default store 或者 export {store as default};
不建议用 export {store};
用默认导出default的原因 在
https://blog.csdn.net/zbl744949461/article/details/80433572 10 import和export中有写。
在main.js中引入这个对象,挂载到Vue的原型上
import store from './vuex/store'
Vue.prototype.$store=store
state:https://vuex.vuejs.org/zh/guide/state.html
便于全局管理 ,Vuex 通过 store
选项,提供了一种机制将状态从根组件“注入”到每一个子组件中
在new Vue的实例中,放入store,便于全局使用管理。 vue这个构造函数是怎么工作的。
4.后台获取菜单数据,配置路由菜单
(1). main.js中引入axios
这步是以后用的,在配置路由菜单这里没用,可以先不引用。
https://blog.csdn.net/connie_0217/article/details/78703112
import axios from 'axios'
Vue.prototype.$axios=axios;
(2). 因为路由的路径要保存到store中,所以要在router/index.js中引入 store
import store from './vuex/store'
先定义个常量 空路由 并导出
const router new Router();
// const router = new Router({routes: [] }) (注:如果要这样写,这里不要写错了?,是routes?,这是必须吗?)
export default router
要使用路由,在new Vue时,要把路由传入。
在main.js中import router from './router'
new Vue 时加入 这2步在vue cli中默认就有。
(3). 从后台获取数据方法
要从后台拿到返回数据,需要axios,考虑到拿到的数据有的是和我们设定要求的数据格式一样,有的不一样,
如果不一样,就需要提前处理成一样的。考虑到这样的需求,将这个获取和处理的过程,放到另外一个js文件中执行,
在当前文件只使用 已处理好的数据 格式。可以看看 vue-element-admin 找找灵感
在src文件夹下新建permission.js文件(许可),并把这个文件引入到router/index.js中。
从后台取数需要axios 在permission.js中引入axios (是的,axios是这里要用的,所以在这里引用)
import axios from 'axios'
考虑要导出,所以先定义个常量,这个常量如果是个函数,获取后台数据,并返回值,它就是变量了,
所以,把让它接收一个内置方法,让这个方法去处理后台返回的数据。
这样,这个常量可以被导出使用了,也不会变成变量。
const findMenusByService = function(处理数据,动态构建路由的函数){
//获取后台数据
axios.get('先写静态数据json地址').then(res =>{
//如果后台返回的数据格式不对,预先处理
//处理后,使用函数方法,动态构建路由
构建路由方法(res);
});
}
导出 常量 函数对象
export default findMenusByService;
也可以这样写:因为这个aaa是个参数,向上面的写法,就是告诉程序员,这里以后要用的方法名是什么。上面的比较好。
动态获取路由的方法,在index.js中写。
(4). 在未真正从后台取数前,或许可以使用mock随机生成数据。
可以看看vue-element-admin的mock 文件目录。
https://panjiachen.github.io/vue-element-admin-site/zh/guide/essentials/mock-api.html#easy-mock
如果使用mock 语法:https://github.com/nuysoft/Mock/wiki
在static文件夹下建mock文件夹,或者在src同级新建个mock文件夹(不推荐,麻烦,需要安装express),
在其面写一个routers.json,
在static下创建的好处是,axios获取本机json数据时,可直接获取,不在static中的,需要配置。
在vue-cli生成的项目的目录结构中,除了static目录下是能够被外面访问,其他任何路径下的文件都不能被外面直接访问到。
想要访问需要修改build–webpack.dev.conf.js文件
要安装express: http://www.expressjs.com.cn/starter/installing.html
https://www.runoob.com/nodejs/nodejs-express-framework.html
配置如下:https://blog.csdn.net/m0_38134431/article/details/83786085
https://segmentfault.com/q/1010000011628771
关于静态文件:不确定解析:https://blog.csdn.net/Mr_YanYan/article/details/78783091
如果没配置,直接写,会报如下错误
基于真正的数据要在后台取,所以将 存假数据的mock文件夹 写在static下,简化取数步骤。
routers.json中,写嵌套路由的路由地址格式 https://router.vuejs.org/zh/guide/essentials/nested-routes.html
这里的 .指src文件夹?(不懂)
格式:
默认应该有默认的路径path,默认的组件component,如上默认找layout文件夹下的index.vue,
path是显示在url地址上#后面的,不是真实路径。
根目录组件是./layout下的index.vue,里面的要嵌套子组件,新建放置子组件的组件,这样写对吗
?其他路由的子组件在子组件中渲染,component的路径为./layout/RouterView.vue
? 在index.vue中导入RouterView,使用。
注:每次写嵌套路由,都要从外到内,先写最外父组件,再写子组件,再写子子组件,每一层都不能少。
多余的逗号,ie8以上都可以兼容,但如果有多余的逗号,虽然不会报错,但获取数据时,json就不是个json对象了,
变成了一串字符串,这样,在获取数据时就会有问题。
当有多余逗号时,控制台打印 console.log(res,data)是这样:
没有多余逗号才会打印正确,是这样:
所以,不要有多余逗号,如果后台传过来的有的话,一般没有。要做好处理。怎么处理?
当要使用从定向时,不要和本身的path相同,如果相同,会一直循环执行。
比如:
浏览器会报错
(5). 打印默认的可配置的路由路径
因为是后台配置路由再返回到前台,所以,在控制台打印出所有可以路由的地址,方便后台使用。
这个地址不准备在前台更改,如果有增加和删除,在后台配置进行。
所以,这个保存路径的对象,应该是个常量。
展示的界面在layout或pages文件夹下,所以,只要匹配这2个文件夹下的vue文件就好了。
layout下的component文件夹里的组件是index.vue专用的,需要父级传参,这个参数不是定义在store中,不是全局的。
所以。这个文件夹下的组件,不准备给用户用,如果使用路由引入,因为没传参,可能回报错。
pages下的界面是展示界面,不用父级传参,如果想要首页传参,在首页把参数写在store中,这样就可以全局获取了。
(keys不要匹配带.vue结尾,后台配置路径不加.vue,所以只配默认目录和可用的layout和pages目录及子目录下的组件)
配置默认的目录是因为可以用./layout这样的目录取到下面的index.vue,所以要加./layout这样的目录
如果没有默认写法,用下面的正则
const availableContext= require.context('..',true,/(layout|pages)(?!.components).*.vue$/);
Ⅰ 有默认目录,就要显示2种,文件夹目录,和不带.vue结尾的,正则要改成以下:
const availableContext= require.context('..',true,/\/(?:pages|layout)(?!.components)(?![^\.]*\.vue).*$/);
写正则的思路:
① 首先要在相对路径 ..下的目录: /\//
② 在pages或layout下 : /\/(?:layout|pages)/
这里用(?:x|y)而不用(x|y) 是什么考虑,应该都是消耗字符的
https://blog.csdn.net/shashagcsdn/article/details/80017678
③ 去掉components文件夹下的组件
(?!.components)
③ 去掉带.vue结尾的路径
(?!.*\.vue)
④ 考虑到以后要用require.ensure([],function) 可能都会用[]作为导入组件的依赖项,
layout/component下的组件依赖index.vue,但实际index.vue是最先导进来的,
如果以后单独使用layout/component下的组件,这里没有和依赖一起打包,不知道会不会有问题。
所以想在可给后台使用的组件目录中,去掉layout/component下的组件地址。
待写。
⑤ 还有些想不明白,再思考。
于是这样写了:
require.context('..',true,/\/(layout|pages)(?!.*\.vue)/);
正则:https://deerchao.net/tutorials/regex/regex.htm
require.context:https://www.jianshu.com/p/c894ea00dfec
一个webpack的api,通过执行require.context函数获取一个特定的上下文,主要用来实现自动化导入模块。
只是模块,css不行。
加快Vue项目的开发速度 https://juejin.im/post/5c106485e51d450e657571a6
require.context函数接受三个参数
directory {String} -读取文件的路径
useSubdirectories {Boolean} -是否遍历文件的子目录
regExp {RegExp} -匹配文件的正则
用keys()属性获取所有文件路径,展示到控制台,直接打印容易和数据混用,使用console.info()方法,打印信息,规范打印。
Ⅱ const availablePageKeys = availableContext.keys();
Ⅲ console.info('generate routers', {availablePageKeys} );
代码:
调用require.context函数执行后 返回的是一个函数webpackContext(req){},并且这个函数有3个属性 (这些在之后会用)
① resolve {Function} -接受一个参数request,
request为test文件夹下面匹配文件的相对路径,返回这个匹配文件相对于整个工程的相对路径
② keys {Function} -返回匹配成功模块的名字路径组成的数组
③ id {String} -执行环境的id,返回的是一个字符串,主要用在module.hot.accept,应该是热加载?
https://segmentfault.com/a/1190000017160862
https://www.cnblogs.com/zhouyideboke/p/10948294.html
console.log(availableContext) 查看更多这个函数的上下文的js文件,
用availableContext(路径)可以得到一个对象?
(6). 前置导航守卫,做验证,并配置component
思路:二.4.(3)配置路由
在路由跳转前做一些验证,比如登录验证,是网站中的普遍需求。
在这个项目,点击跳转路由前,
① 首先需要从后台获取路由数据,
② 然后判断 所有可跳转的路由组件 是否 在本地存在,有,给它的组件属性赋值,没有就赋404。
③ 新建个空数组常量dynamicRouter,用于以后保存 动态路由数据。(这个写在导航守卫外面定义)
④ 要把动态路由数据存到store中,用于给左侧菜单和顶部菜单使用。
⑤ 然后把整理好的动态路由数据通过 router.addRoutes(动态路由数据)到router(开始设置的是个空路由),
⑥ 再进行next()跳转。
⑦ 因为用了addRoutes()方法,为了确保addRoutes已完成,要用到hack方法跳转:next({...to,replace:true})
// hack方法 确保addRoutes已完成,设置replace:true,这样导航就不会留下历史记录。
因为要在跳转路由前实现这些需求,给路由一个全局前置导航守卫,用来处理这些需求,处理完,再跳转。
简单的例子:
因为网站地址现在默认访问路径就是"/",所以,就是执行到/了,导航守卫通过next()就跳转了。
next()方法传参和不传参的不同,
next()传参的时候会再次进入路由钩子,容易出现n多次循环就导致堆栈溢出而报错(如下图)。
而直接调用next()就不会在进入这个钩子。
所以我们在使用时,为了不让它一直循环执行,要给它条件判断执行。
前置导航守卫用router.beforeEach() 方法
https://cn.vuejs.org/v2/guide/migration-vue-router.html#router-beforeEach-changed
导航守卫:https://router.vuejs.org/zh/guide/advanced/navigation-guards.html
嵌套路由:https://router.vuejs.org/zh/guide/essentials/nested-routes.html
前辈解析:https://www.cnblogs.com/WQLong/p/8135553.html
三个参数:
- to:router即将进入的路由对象
- from:当前导航即将离开的路由
- next:Function,进行管道中的一个钩子,如果执行完了,则导航的状态就是 confirmed (确认的);否则为false,终止导航。
为了解决next()传参重复进入钩子循环这个问题,加一个判断:
测试:
加判断条件,在第一次进入导航守卫时,a的长度是0,a数组加入6,执行传参的next(),
这时再执行,a的长度就不是0了,就去执行next()了。
扩展运算符... :将一个数组转为用逗号分隔的参数序列
执行过程:
第一次打开网址,通过访问/目录时,调用导航守卫,
这时,动态路由还是空的,执行方法findMenuByService,给路由加内容,再执行就不是空的了,就会跳next()方法。
这里用!dynamicRouter.length 可以包含很多种情况,比单一的 dynamicRouter.length == 0 好。
(7). 配置component、动态路由数据、加载到router中
具体配上一步的a方法,a是用来生成路由的,起个好听的名字generateRouter。
① const dynamicRouter=[]; 初始动态路由列表为空
② generateRouter方法:
generateRouter方法中设置的 常量f方法 就是 用来配置component 和 动态路由数据dynamicRouter 的。
from:路由数据
to:要写进的数组
第一次执行是从后台获取的路由数据,经f处理,写到dynamicRouter数组中。
③ f方法:
最终要把解析好的目录push到dynamicRouter中,先要验证每个目录对应的路由组件是否存在。
具体细节步骤:
Ⅰ新建 常量 component = item.component 这是后台返回的组件路径
Ⅱ 新建 变量route ,route的其他属性直接定义在route上,组件要验证,先不挂在route上
Ⅲ 如果组件存在,
❈ 处理思路,要给每个组件属性赋上组件。
① 首先,如果用import引入组件给每个组件,就会一个个组件都加载进来,
当项目打包时路由里的所有component都会打包在一个js中,成一个很大的index.js文件。
造成进入首页时,需要加载的内容过多,时间相对比较长。
当你用require.ensure这种方式引入的时候,会将你的component分别打包成不同的包,
只用访问这个路由网址时才会加载这个包,第一次加载后会缓存。
加载组件的时候是按需加载,通过resolve ↓
component: resolve => require(['../pages/home.vue'], resolve),
异步组件:https://cn.vuejs.org/v2/guide/components-dynamic-async.html#%E5%BC%82%E6%AD%A5%E7%BB%84%E4%BB%B6
resolve
就是 promise
的 resolve
回调,组件加载成功后调用
https://segmentfault.com/q/1010000017913060
② 给组件赋值
https://webpack.docschina.org/api/module-methods/#require
https://www.cnblogs.com/leaf930814/p/8109747.html
route.component = 判断组件是否在项目真正的组件列表里存在,
如果存在,等于上,如果不存在,就挂404页面,
使用some()方法判断本地所有可路由的组件路径有没有和后台返回的匹配的,
如果全部循环有一个匹配上返回true,如果所有都匹配不上,返回false。
后台配置路径可能不加.vue这个后缀,在这里要判断下。在原值和加后缀2中情况下,有一种成立就可以。
availablePageKeys.some(key =>{
return key == component || key ==component+'.vue';
});
用数组的some()方法验证 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/some
require.ensure()方法,以异步方式加载到单独的包中。在使用CommonJS模块语法时,这是动态加载依赖项的唯一方法。
官方文档: https://webpack.docschina.org/api/module-methods/#require-ensure
https://blog.csdn.net/zhbhun/article/details/46826129
需要的时候才下载依赖的模块,requi.ensure的模块只会被下载下来,不会被执行,
只有在回调函数使用require(模块名)后,这个模块才会被执行。所以要用 return xxx 调用下。
`${expression}` 模板字面量 和 字符串占位符字 http://www.softwhy.com/article-9991-1.html
Ⅳ 如果item有子项,route.children=[],再执行一遍f(item.children,route.children) (这个route.children=[]必须写吗,如果为了让它是初始化值是[],在新建变量route时,就写上不好吗,想了下,因为新建变量时,没有子项,就不需要这个属性,这个是动态的,写在这里判断很好。)
④ 并将dynamicRouter保存到store中
先在store的state属性中定义个属性RouterData,用来保存路由列表,这个数据以后要给左侧菜单和顶部菜单使用。
使用store要先在文件里导入store
store.state.RouterData = dynamicRouter;
给router动态添加更多的路由规则 https://router.vuejs.org/zh/api/#router-addroutes
⑤ router.addRoutes(dynamicRouter);
(8).路由配置成功标志
如果没有成功 在console.log(router)时,ready:false。 如果成功,会变成true。
5.关联菜单
路由配置成功后,和菜单关联在一起。
回到主页 layout/index.vue
(1). 获取store路由数据
因为路由的状态是依赖的响应式属性变化,所以在计算属性里写获取。
前提:在main中,把store绑定在vue的原型上,这里才能用this调用。(在 3.vuex全局管理数据 有写)
vue 生命周期:https://blog.csdn.net/zbl744949461/article/details/86134414
computed:{
routes(){
return this.$store.state.RouterData ;
}
}
(2). 初始化菜单
打开界面时,要对界面的顶部菜单和左侧菜单进行初始化配置。
首先考虑到,根目录的菜单选项,不是顶部菜单和左侧菜单要使用的,所以,要先剔除掉根目录菜单。
在router.json中,给根目录加入属性 isRoot
在index 中,每个对象,如果有isRoot,isRoot就是true,没有就是undefined。
(3). 初始化顶部菜单
① 如果使用顶部菜单,顶部菜单会切换左侧菜单,所以先初始化顶部菜单。
假如顶部菜单如下图,默认显示4个,多余的放在。。。中,默认选中第一个。
关于顶部菜单的顺序,是否要在路由里加入排序的值(或者用key),让后台排好返回,
或者前台根据排序的值(或key值)排序。
② 考虑有的项目不需要顶部菜单,那要在data中写个参数enableTopMenu,用于判断要不要使用顶部菜单。
用就写true 不用就写false。
③ 定义初始化菜单的方法
如果使用菜单,顶部菜单数据就是过滤掉根目录以外的数组中的对象。
④ 在哪里执行这个方法
有2种方案,(watch在mounted之前执行)
Ⅰ 在watch 中 通过观察 enableTopMenu为真,在侦听开始之后被立即调用执行。
Ⅱ 在mounted中调用,如果在这里,就在方法里加判断。
调用后,数据要传到子组件中使用。
初始化顶部菜单,需要除了根目录以外的所有顶级菜单,name和key
(4). 初始化左侧菜单
(5). 顶部菜单切换左侧菜单
主题配置
假如项目要配置多种主题
比如首页框架,要用6个组件和路由的子界面。
① 先有个全局的css文件 reset.css 定义些基础样式,比如字体。
② 假如要3种主题风格,就要有3个css文件用来存放这些主题样式。
原方案想,首页框架的6个组件,分别在组件内部写自己的样式,在主题文件里写一些颜色,字体的变化。
后来想,如果主题有宽窄,位置布局变化,那改变主题后,可能会与组件自己的样式冲突,要来回反复改。
于是,样式都写在主题css文件中,组件中不写。这样,即使有修改总字体需求,要3个文件一起改,
但在主题自己的定位布局特色中,不会和其他地方的css冲突。
③ 还要注意 主题有全局class名 比如 .vaa-dawnblue .vaa-darkblue .vaa-red
组件里的命名要带独立前缀,防止与以后用户的命名冲突,比如 vaa-main-top-menu
这样即使用户用top-menu 也不会与我们的定义有冲突
④ 引用ant design vue 的组件,组件也有不同的样式 这些组件,每个组件建立单独的css文件,用来放置预设样式
打包常见错误:https://www.cnblogs.com/hjvsdr/p/8064880.html
四. 问题
1.jsx不懂,啥时候去学???
在"快速上手"中,jsx是怎么用的。https://baike.baidu.com/item/JSX/1686693?fr=aladdin
https://github.com/vuejs/babel-plugin-transform-vue-jsx
更多推荐
所有评论(0)