前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >前端项目搭建实战(Vue)

前端项目搭建实战(Vue)

原创
作者头像
逃跑计划
发布2022-08-03 21:04:15
1.7K4
发布2022-08-03 21:04:15
举报
文章被收录于专栏:我的前端体系我的前端体系

网上开源的前端框架都写得很好,但是功能比较庞杂,于是着手搭建了一套自己的模板:

1.路由配置

首先我们要通过路由配置整体的页面结构(Home、About、Login)

代码语言:javascript
复制
Vue.use(VueRouter);

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/About.vue'),
  },
  {
    path: '/login',
    name: 'Login',
    component: () => import('../views/Login.vue'),
  },
];

const router = new VueRouter({
  routes,
});

同时我们需要对路由做一定的控制,比如未登录时只允许访问登录页,以及对页面跳转做一些样式上的优化。

代码语言:javascript
复制
router.beforeEach((to, from, next) => {
  // 虚拟进度条,采用 NProgress 组件
  NProgress.start();
  let token = cookies.get('token');
  // 如果没有 token 则跳到登录页
  if (!token) {
    if (to.fullPath !== '/login') {
      next({ path: '/login' });
    } else {
      next();
    }
    return NProgress.done();
  } else {
    // 如果有 token 访问登录页则跳到首页;刷新时自动获取角色信息保存在 vuex 中
    if (!store.state.role) {
      const role = GET_ROLE();
      store.commit('setState', role);
    }
    if (to.fullPath === '/login') {
      next({ path: '/' });
    } else {
      next();
    }
    NProgress.done();
  }
});

2.Vuex 全局状态管理

在路由配置中我们将角色信息存储在了 Vuex 中,Vuex 的配置如下:

代码语言:javascript
复制
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    // 角色信息
    role: '',
  },
  mutations: {
    setState(state, role) {
      state.role = role;
    },
  },
  actions: {},
  modules: {},
});

在页面中我们可以通过 mapState 访问 store 中的数据

代码语言:javascript
复制
import { mapState } from 'vuex';
computed: mapState(['role']),

<h3>我是:{{ role }}</h3>

3.组件库选用 Element-ui

组件库的选用纯看个人喜好

代码语言:javascript
复制
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

4.自定义过滤器

自定义时间过滤器,在 main.js 全局注册时间过滤器,传入模板字符串解析为对应格式

代码语言:javascript
复制
// 定义时间过滤器
Vue.filter('dateFormat', function (originDate, pattern) {
  // 根据给定的时间字符串,得到特定的时间
  var dt = new Date(originDate);
  var y = dt.getFullYear();
  var m = (dt.getMonth() + 1).toString().padStart(2, '0');
  var d = dt.getDate().toString().padStart(2, '0');
  var hh = dt.getHours().toString().padStart(2, '0');
  var mm = dt.getMinutes().toString().padStart(2, '0');
  var ss = dt.getSeconds().toString().padStart(2, '0');
  return eval('`' + pattern + '`');
});

在页面中使用

代码语言:javascript
复制
<h3>当前时间:{{ time | dateFormat('${y}-${m}') }}</h3>
time
time

5.自定义指令

在 main.js 中注册全局指令

代码语言:javascript
复制
// 权限指令
Vue.directive('perm', {
  // 绑定元素插入父节点时触发
  inserted: (el, binding) => {
    const hasPermission = (roleArr) => {
      return roleArr.includes(store.state.role);
    };
    if (!hasPermission(binding.value)) {
      // 如果不满足条件,则移除当前绑定节点
      el.parentNode.removeChild(el);
    }
  },
});

在页面中使用,当角色为 admin 时,第一行不显示

代码语言:javascript
复制
<h3>
学生可以看到: 我是<span v-perm="['student']">{{ role }}</span>
</h3>
<h3>大家可以看到: 我是<span v-perm="['student', 'admin']">{{ role }}</span>
</h3>
directive
directive

6. svg 封装

新建 SvgIcon.vue 文件

代码语言:javascript
复制
<template>
  <svg :class="svgClass" aria-hidden="true" v-on="$listeners">
    <use :xlink:href="iconName" />
  </svg>
</template>

<script>
export default {
  name: 'SvgIcon',
  props: {
    // svg图标名称
    name: {
      default: '',
    },
    // 自定义样式
    className: {
      type: String,
      default: '',
    },
  },
  computed: {
    iconName() {
      return `#icon-${this.name}`;
    },
    svgClass() {
      return ['svg-icon', this.className ? this.className : ''];
    },
  },
};
</script>

<style scoped>
.svg-icon {
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
</style>

全局注册该组件

代码语言:javascript
复制
Vue.component('SvgIcon', SvgIcon);

这样我们就可以通过 SvgIcon 访问内存中存在的 svg 图标了,我们还需要做的就是将 svg 文件加载到内存中,

svg-sprite-loader 的官方解释是:一个用于创建 svg 雪碧图的 Webpack 加载器。这个加载器现在已经被 JetBrains 公司收录和维护了。通俗的讲:svg-sprite-loader 会把你引入的 svg 塞到一个个 symbol 中,合成一个大的 svg,最后将这个大的 svg 放入 body 中。symbol 的 id 如果不特别指定,就是你的文件名。

代码语言:javascript
复制
chainWebpack(config) {
  // 配置路径别名
  config.resolve.alias.set('components', resolve('src/components'));
  // 已有配置排除掉svg
  config.module.rule('svg').exclude.add(resolve('src/svg'));
  // 添加svg-sprite-loader
  config.module
    .rule('icons')
    .test(/\.svg$/) // 设置test
    .include.add(resolve('src/svg')) // 加入include
    .end() // add完上下文进入数组,使用end回退
    .use('svg-sprite-loader') // 添加loader
    .loader('svg-sprite-loader') // 切换上下文到loader
    .options({ symbolId: 'icon-[name]' })
    .end();
},

// main.js -- 将 svg 文件引入内存中
import '@/svg/icons';
// icons.js
const req = require.context('../svg', false, /\.svg$/);
req.keys().map(req);

这样就可以通过 name 属性访问 svg 了

代码语言:javascript
复制
<SvgIcon name="404" className="icon-style" />
svg
svg

7.axois 封装

axios 建议只做简单封装即可

代码语言:javascript
复制
import axios from 'axios';
import cookies from '@/utils/js-cookie';
// 创建请求实例
function createRequest() {
  const request = axios.create({
    baseURL: '/api',
    timeout: 10000,
  });

  request.interceptors.request.use((config) => {
    // 自动携带 token
    const token = cookies.get('token');
    config.headers.token = token;
    return config;
  });

  return request;
}

export const request = createRequest();

// api.js
import { request } from './service';

export function GET_BOOK_LIST() {
  return request({
    url: '/catalog/book/',
    method: 'get',
    headers: { 'content-type': 'application/x-www-form-urlencoded' },
    params: {
      type: 'book',
    },
  });
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.路由配置
  • 2.Vuex 全局状态管理
  • 3.组件库选用 Element-ui
  • 4.自定义过滤器
  • 5.自定义指令
  • 6. svg 封装
  • 7.axois 封装
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档