Vue-Cli 3.0从0 开始搭建项目(篇1)
栏目: JavaScript · 发布时间: 5年前
内容简介:从0开始搭建项目,相信更多人都做过,但是你真的独立搭建整个项目了吗,有没有考虑周全,是否从UI的框架的选型、权限、图标、路由、登陆拦截、第三方工具库、性能优化等多方面搭建出适合本公司项目的人员和环境。本文总结的是Vue-Cli3.0构建项目搭建项目根据实际情况而定。 值得注意的Vue-Cli 初始化项目的命令是`vue create 项目名称`,而不是之前的`Vue init webpack 项目名称` 我这边大致选了history路由、Vuex、less、eslint、unit test等
从0开始搭建项目,相信更多人都做过,但是你真的独立搭建整个项目了吗,有没有考虑周全,是否从UI的框架的选型、权限、图标、路由、登陆拦截、第三方 工具 库、性能优化等多方面搭建出适合本公司项目的人员和环境。本文总结的是Vue-Cli3.0构建项目
搭建项目
根据实际情况而定。 值得注意的Vue-Cli 初始化项目的命令是`vue create 项目名称`,而不是之前的`Vue init webpack 项目名称` 我这边大致选了history路由、Vuex、less、eslint、unit test等
Vue-Cli官方地址webpack、babel、vue.config.js的配置
vue.config.js的相关配置
// vue.config.js const path = require('path') const resolve = dir => { return path.join(__dirname, dir) } // 线上打包路径,请根据项目实际线上情况 const BASE_URL = process.env.NODE_ENV === 'production' ? '/' : '/' module.exports = { publicPath: BASE_URL, outputDir: 'dist', // 打包生成的生产环境构建文件的目录 assetsDir: '', // 放置生成的静态资源路径,默认在outputDir indexPath: 'index.html', // 指定生成的 index.html 输入路径,默认outputDir pages: undefined, // 构建多页 productionSourceMap: false, // 开启 生产环境的 source map? configureWebpack: { // webpack 的配置 plugins: [ new MyAwesomeWebpackPlugin() ] }, chainWebpack: config => { // webpack的配置(链式操作) // 配置路径别名 // config.resolve.alias // .set('@', resolve('src')) // .set('_c', resolve('src/components')) }, css: { modules: false, // 启用 CSS modules extract: true, // 是否使用css分离插件 sourceMap: false, // 开启 CSS source maps? loaderOptions: { less: { modifyVars: { // 定制主题 'primary-color': '#1DA57A', 'link-color': '#1DA57A', 'border-radius-base': '2px', }, javascriptEnabled: true, } } }, devServer: { port: 8080, // 端口 proxy: '' // 设置代理 } } 复制代码
babel.config.js
使用 babel-plugin-import
(按需加载组件代码和央视的babel插件),下面的配置使用该插件引入 vue-antd-design
// babel.config.js module.exports = { presets: ["@vue/app"], plugins: [ [ "import", { libraryName: "ant-design-vue", libraryDirectory: "es", style: true } ] ] }; 复制代码
UI框架(Ant-design-vue)
全局引入
不多说。想说的是全局引入有13MB,50多个组件,全部引入有点大。其实在我以前做过的项目当中基本上都是全局引入,不知大佬们写代码会不会有“洁癖”,局部引入或是自己写,哈哈
局部引入
// main.js import { Button } from "ant-design-vue" import "ant-design-vue/dist/antd.less" // 或者是 import "ant-design-vue/lib/button.less" Vue.use(Button) 复制代码
使用babel-plugin-import(高级配置)
vue-and-design官方地址 配置就在上方的 babel.config.js
中。 我们下面看看 main.js
是怎么使用的
// main.js import { Button,Menu,Drawer,Radio,Layout,Icon} from 'ant-design-vue'; Vue.use(Drawer) Vue.use(Button) Vue.use(Menu) Vue.use(Radio) Vue.use(Layout) Vue.use(Icon) 复制代码
哎呀,貌似篇幅很长,不过加载的文件大小确实小了很多
路由配置
一定要配置路由,就得想好文件目录怎么设置。这里参考了唐老师的搭建项目的目录
路由配置,篇幅有限。我只选出一部分
// router.js import Vue from "vue"; import Router from "vue-router"; import { notification } from "ant-design-vue"; import NotFound from "./views/404"; import Forbidden from "./views/403"; Vue.use(Router); const router = new Router({ mode: "history", base: process.env.BASE_URL, routes: [ { path: "/user", hideInMenu: true, component: () => import( "./layouts/UserLayout"), children: [ { path: "/user", redirect: "/user/login" }, { path: "/user/login", name: "login", component: () => import( "./views/User/Login") } ] }, { path: "/", meta: { authority: ["user", "admin"] }, // 用来做权限管理 component: () => import( "./layouts/BasicLayout"), children: [ // dashboard { path: "/", redirect: "/dashboard/analysis" }, { path: "/dashboard", name: "dashboard", meta: { icon: "dashboard", title: "仪表盘" }, component: { render: h => h("router-view") }, children: [ { path: "/dashboard/analysis", name: "analysis", meta: { title: "分析页" }, component: () => import( "./views/Dashboard/Analysis") } ] }, // form { path: "/form", name: "form", component: { render: h => h("router-view") }, meta: { icon: "form", title: "表单", authority: ["admin"] }, children: [ { path: "/form/basic-form", name: "basicform", meta: { title: "基础表单" }, component: () => import("./views/Forms/BasicForm") }, { path: "/form/step-form", name: "stepform", hideChildrenInMenu: true, meta: { title: "分布表单" }, component: () => import( "./views/Forms/StepForm"), children: [ { path: "/form/step-form", redirect: "/form/step-form/info" }, { path: "/form/step-form/info", name: "info", component: () => import( "./views/Forms/StepForm/Step1") } ] } ] } ] }, { path: "/403", name: "403", hideInMenu: true, component: Forbidden }, { path: "*", name: "404", hideInMenu: true, component: NotFound } ] }); export default router; 复制代码
总结下分为三部分:用户模块、主要内容、403/404页面。 用户下面有子模块login,主要内容(一般是导航菜单的内容)有仪表盘 dashboard
和表单 form
,仪表盘下面有分析页 anlysis
,表单下面有基础表单 basicForm
// App.vue <div id="app"> <router-view /> </div> 复制代码
BasicForm.vue
路由大概到这里 这个写法觉得很巧妙
路由守卫
如果没有权限跳到登陆页面, 登陆成功之后没有权限进入403页面,更多路由守卫知识点击
router.beforeEach((to, from, next) => { // to 即将要进入的目标 路由对象 // from 当前导航正要离开的路由 // next if (to.path !== from.path) { NProgress.start(); } const record = findLast(to.matched, record => record.meta.authority); if (record && !check(record.meta.authority)) { if (!isLogin() && to.path !== "/user/login") { next({ path: "/user/login" }); } else if (to.path !== "/403") { notification.error({ message: "403", description: "你没有权限访问,请联系管理员咨询。" }); next({ path: "/403" }); } NProgress.done(); } next(); }); // 全局后置钩子 router.afterEach(() => { NProgress.done(); }); 复制代码
权限管理
菜单路由
在路由配置那里有个元数据信息,那里设置了哪些用户具有菜单权限。 在真实的环境中是后端返回这个用户的菜单,有的话就渲染出来
// 检查 用户的权限 export function check(authority){ const current = getCurrentAuthority(); return current.some(item => authority.includes(item)); } 复制代码
按钮权限
这里是自定义指令的方式做的,更多自定义指令的参数点击
import { check } from "../utils/auth"; function install(Vue, options = {}) { Vue.directive(options.name || "auth", { inserted(el, binding) { if (!check(binding.value)) { el.parentNode && el.parentNode.removeChild(el); } } }); } export default { install }; 复制代码
然后在 main.js
中使用
// main.js import Auth from './directives/auth'; Vue.use(Auth); 复制代码
其它相关
Nprogress 过渡组件
yarn add nprogress npm install --save-dev nprogress 复制代码
函数式组件
更多 点击
之前创建的锚点标题组件是比较简单,没有管理任何状态,也没有监听任何传递给它的状态,也没有生命周期方法。实际上,它只是一个接受一些 prop 的函数。 在这样的场景下,我们可以将组件标记为 functional,这意味它无状态 (没有响应式数据),也没有实例 (没有 this 上下文)。
<script> import { check } from '../utils/auth' export default { functional: true, props: { authority: { type: Array, required: true } }, render(h, context){ const { props,scopedSlots } = context; return check(props.authority) ? scopedSlots.default(): null } } </script> 复制代码
render()函数还是一个挺有意思的存在
不知道在哪里看过一句话,码而不思则殆,思而不码还是殆
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 从零开始搭建一个mock服务
- 从零开始搭建创业公司后台技术栈
- 从零开始搭建一个react项目开发
- 从零开始搭建基于 Mesos 的私有容器平台
- 从0开始使用sinopia搭建私有npm仓库
- 从0开始Go语言,用Golang搭建网站
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Pragmatic Programmer
Andrew Hunt、David Thomas / Addison-Wesley Professional / 1999-10-30 / USD 49.99
本书直击编程陈地,穿过了软件开发中日益增长的规范和技术藩篱,对核心过程进行了审视――即根据需求,创建用户乐于接受的、可工作和易维护的代码。本书包含的内容从个人责任到职业发展,直至保持代码灵活和易于改编重用的架构技术。从本书中将学到防止软件变质、消除复制知识的陷阱、编写灵活、动态和易适应的代码、避免出现相同的设计、用契约、断言和异常对代码进行防护等内容。一起来看看 《The Pragmatic Programmer》 这本书的介绍吧!