目录说明
目录说明
基于 yicode
的项目,目录结构都有其特定含义,请同学们仔细阅读以下说明,以便更加熟练地使用 yicode
开发项目。
assets 内部资源目录
所谓的内部资源,就是项目会被项目依赖,并进行统一打包和构建的非代码类资源。
如:图片,音频,视频,字体等。
结构如下:
├─audio
├─fonts
├─images
│ ├─article
│ ├─bagua
│ ├─book
│ ├─code
│ ├─film
│ ├─friends
│ ├─game
│ ├─navigation
│ ├─novel
│ ├─softs
│ └─tool
└─videos
static 外部资源目录
所谓的外部资源目录,就是不会被项目依赖,不会进行统一打包构件,以传统的<script>
,<link>
等标签直接在 html 文件模板里面引入的资源。
如:网站收藏图标,jquery 相关库和插件,第三方没有 npm 包的文件等。
├─css
│ ├─jquery.min.js
│ ├─swiper.min.js
├─fonts
└─images
│ ├─favicon.png
└───
tpls 模板目录
单页应用 html 文件模板目录,所有的外部资源引导请对此目录下的文件进行修改。
├─tpls
│ ├─index.html
└───
index.html 文件代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>陈随易</title>
<link rel="icon" type="image/png" href="./static/images/favicon.png" sizes="32x32" />
<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no" />
</head>
<body>
<div id="app"></div>
<script src="./static/fonts/iconfont.js"></script>
</body>
</html>
layout 项目骨架目录
大部分项目,都有一些页面公共元素,比如官网项目,有顶部导航,底部信息。
后台管理项目,除了顶部栏,还有左侧的菜单面板等。
为此,理应把这些页面共用的区域,提取出来,做成所有页面的骨架,便叫做 layout
。
layout
层的结构如下:
├─layout
│ ├─default # 默认风格骨架
│ ├─header.vue
│ ├─footer.vue
│ ├─menu.vue
│ ├─index.vue
│ ├─redStyle # 红色风格骨架
│ ├─header.vue
│ ├─footer.vue
│ ├─menu.vue
│ ├─index.vue
└───
使用方式,则是在 pages
目录下的页面路由文件 route.js
中,进行 vue-router
路由配置,将骨架导入。
export default {
path: "/",
/**
* layout 框架层
* 此处采用默认的 default 框架
* 如果默认框架不符合你的需求,请不要删除此框架层的导入
* 直接修改 layout/default 目录下的默认框架层代码即可
* 如果是类似官网项目,不需要框架层,也请不要将此框架层移除
* 当做有一个全屏的框架层即可,提高需求变更的灵活性
* 也给自己留一条退路(其实主要是框架作者的强迫症)
* 如有问题或建议,请联系作者:chensuiyi.com
*/
component: () => import("@src/layout/default/index.vue"), // 导入默认骨架
children: [
{
path: "/",
component: () => import("@src/pages/index/index.vue"),
},
],
};
如果想更换项目骨架结构,将每个页面目录下的route.js
文件中的骨架导入名称修改即可。
pages 页面目录
yicode
采取的是【约定大于配置】的原则,pages
便是这个原则指导下,一个非常重要的目录。
├─pages
│ ├─index
│ ├─index.vue
│ ├─route.js
│ ├─news
│ ├─index.vue
│ ├─route.js
如上所示,pages
目录下,一个目录就表示一个【页面】,一个页面默认表示一个独立的【一级路由】。
使用 yicode new --page 页面名称
,可以自动在 pages
目录下,生成对应的页面目录和文件
生成页面元素的细节,请看后面的【页面分配】教程详解。
comps 全局组件目录
全局组件,顾名思义,就是创建后,到处都可以使用。比如 回到顶部
,天猫右侧固定导航
等。
├─comps
│ ├─test1 # 全局组件 test1
│ ├─index.vue
│ ├─test2 # 全局组件 test2
│ ├─index.vue
│ ├─index.js # 全局组件统自动导入文件
与其他框架不同的是,yicode
不仅提供一键创建全局组件命令yicode new --comp 组件名称
。
还提供了创建后,无需手动挂载,自动挂载组件到Vue
实例的功能,提高开发效率和体验。
如上创建的test1
组件,直接按如下方式书写即可。
<CompTest1></CompTest1>
注意:组件使用时,应在组件名前,加上
Comp
前缀,表示全局组件!
env 环境变量
环境变量,专门用于应对开发环境和发布环境,不同参数的切换。
其下只有两个文件,development.env
文件和 production.env
文件。
参考如下方式设置即可。
# 协议类型
protocol="http://"
# 本地存储命名空间
namespace="yicode"
mixin 全局混入
全局混入,主要用于设置大部分页面通用的 data created methods 等。
├─mixin
│ ├─index.js # 全局混入入口文件
内容如下:
/**
* 全局混入
* 此文件尽量只添加新东西,不要删除以下配置好的东西
* 一切皆有道理
* 如果明白了解,请自行发挥
* 全局混入,是为了解决 vue 组件参数复用问题
* 不要什么都放进来,请把大部分组件共用的东西放进来
* 如有问题或建议,请联系作者:chensuiyi.com
*/
import Vue from "vue";
import Vuex from "vuex";
Vue.mixin({
computed: {
...Vuex.mapState([]),
},
methods: {
...Vuex.mapMutations(["save"]),
},
});
plugins 插件目录
插件目录,用于分门别类地管理第三方引入,默认只设置了 basil.js
这一个浏览器本地存储操作库。
├─plugins
│ ├─index.js
│ ├─basil.js
router 路由目录
路由,是 vue 单页应用的灵魂之一,为了简便路由的管理,yicode
路由目录下,只有一个 index.js
文件。
其内容如下:
/**
* 此文件为路由核心入口文件
* 一般情况下,不需要动此文件
* 此文件将会自动加载当前项目 pages 目录下的所有路由
* 如有问题或建议,请联系作者:chensuiyi.com
*/
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
let routeList = [];
let importAll = require.context("@src/pages", true, /route\.js$/);
importAll.keys().map((path) => {
let router = importAll(path).default || importAll(path);
routeList.push(router);
});
// 导入自动生成的路由文件
let router = new VueRouter({
routes: routeList,
});
export default router;
此index.js
文件,担任起了统一导入项目路由的功能,无需开发者手动设置。
request 异步请求目录
目前,单页应用 + 前后分离,是 web 前端市场开发主流,异步请求更是前后端交互的核心一环。
综合实践经验,yicode
抛弃传统的单接口服务器方式,默认采用了多接口服务器配置。
├─request
│ ├─index.js
│ ├─api1.js # 请求登录服务器
│ ├─api2.js # 请求数据服务器
│ ├─api3.js # 请求日志服务器
也就是说,我们可以登录请求的是 A 服务器,数据请求指向 B 服务器,灵活管理多变的请求环境。
vuex 全局数据管理目录
vuex 官方推荐大型项目使用,但是,我认为,不管小型,中型还是大型项目,都推荐使用。
好的东西,不管什么样的项目,都应该积极使用。
为了提高开发效率,yicode
全局存储默认提供了 save
设置数据的通用方法。
具体用法请看如下代码,或查看 【进阶指南】阶段的 vuex操作
说明。
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
state: {},
mutations: {
/**
* 通用全局存储方法
* --------------------------------
* 普通项目修改 vuex 状态方式:
* 调用处:
* this.$store.emit('SAVE_NAME',{name:chensuiyi})
* 定义处:
* SAVE_NAME(state,params){
* state.userinfo.name = params.name
* }
* --------------------------------
* yicode 项目修改 vuex 状态方法
* 调用处:
* this.YiMutation('userinfo.name','chensuiyi')
* 定义处:
* 无需定义,级联赋值!!!
*/
YiMutation: (state, params) => {
// 判断路径
if (!params.path) return;
// 判断数据
if (!params.data) return;
// 分割路径
let keyPath = params.path.split(".");
// 路径长度
let keyLength = keyPath.length;
// 状态别名
let keySave = state;
// 默认通过
let isPass = true;
// 循环赋值
for (let i = 0; i < keyLength - 1; i++) {
keySave = keySave[keyPath[i]];
if (!keySave) {
isPass = false;
break;
}
}
// 提前返回
if (!isPass) return;
let keyLast = keyPath[keyLength - 1];
// 判断动作
if (params.action) {
if (params.action === "-") keySave[keyLast] = keySave[keyLast] - params.data;
if (params.action === "+") keySave[keyLast] = keySave[keyLast] + params.data;
if (params.action === "*") keySave[keyLast] = keySave[keyLast] * params.data;
if (params.action === "/") keySave[keyLast] = keySave[keyLast] / params.data;
return;
} else {
keySave[keyLast] = params.data;
}
},
},
});
export default store;