百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

「如何优雅的使用Vue?」不可不知的Vue实战技巧

ztj100 2024-10-27 18:36 25 浏览 0 评论



作者: CHICAGO

转发连接:https://juejin.im/post/5e475829f265da57444ab10f

前言

在大家都会用vue的时代,我们又如何去区别是新手小白还是资深vue玩家呢? 如何让自己与刚学vue的人拉开差距呢? 其实,很多人对于vue只停留在基础使用。想要提升自己,就应该想办法将其运用到更高的层次。


本文会从以下三个方面,来进阶我们对vue的运用能力

  • 组件 : 全局组件注册
  • Render函数 : 拯救繁乱的template
  • Vue权限控制 : 高精度全局权限控制

1 -「全局组件注册」

组件是我们非常常用的东西,很多人使用组件都是通过一个一个文件去引用和注册。如果一个组件在整个项目里面的使用次数较多,每一次使用都需要引用并注册,就会显得特别麻烦

  • 一般组件应用弊端
  • 傻瓜式,太笨拙
  • 繁琐,低效
<template>
  <div>
    <h1>I am HelloWorld</h1>
    <Child1></Child1>
  </div>
</template>

<script>
import Child1 from './child1.vue'   // 引入
export default {
  name: 'HelloWorld',
  data(){
    return{
    }
  },
  components:{   // 注册
    Child1
  },
  props: {
    msg: String
  },
  methods:{
  }
}
</script>

<style scoped lang="less">
</style>

当我们在项目需要重复多次使用该组件,会导致出现很多重复的引入和注册代码,既繁琐又不雅观。因此我们可以通过一个全局的Js文件来管理,将需要多次使用的组件进行全局注册

创建全局.js文件管理全局组件

// 1 - globalComponent.js

import Vue from 'vue' // 引入vue

// 处理首字母大写 abc => Abc
function changeStr(str){
    return str.charAt(0).toUpperCase() + str.slice(1)
}

/*
    require.context(arg1,arg2,arg3)
        arg1 - 读取文件的路径
        arg2 - 是否遍历文件的子目录
        arg3 - 匹配文件的正则
    关于这个Api的用法,建议小伙伴们去查阅一下,用途也比较广泛
*/
const requireComponent = require.context('.', false, /\.vue$/)
console.log('requireComponent.keys():',requireComponent.keys())  // 打印
requireComponent.keys().forEach(fileName => {
    const config = requireComponent(fileName)
    console.log('config:',config)  // 打印
    const componentName = changeStr(
        fileName.replace(/^\.\//, '').replace(/\.\w+$/, '')   // ./child1.vue => child1
    )
    
    Vue.component(componentName, config.default || config) // 动态注册该目录下的所有.vue文件
})
// 2 - 将globalComponent.js引入main.js

import global from './components/globalComponent'
// 3 - 使用这类组件不再需要引入和注册,直接标签使用即可

<template>
  <div>
    <h1>I am HelloWorld</h1>
    <Child1></Child1>
  </div>
</template>

运行程序,我们看下是否能够正常显示并分析两句打印

Extra:路由分区以及动态添加路由

假设我们有很多路由,每一个路由都通过傻瓜式的引入方式,会导致整个项目代码量增多,繁琐,更重要的一点是增加后期维护的难度。因此我们也可以通过上面类似的方式,对路由的引入和使用进行管理,实现分区引入路由,将不同功能下的路由进行区分,通过动态的方式进行引入,即方便快捷又增加可维护

创建专门的路由.js文件管理所有的路由

总路由管理文件 - index.js

分区路由
    - index.routes.js
    - login.routes.js

在大型项目中,往往会有很多互不关联的模块,例如电商平台中的商城,个人信息,这种情况下就可以对路由进行分区
// 分区路由文件写法

export default {
    path:'/index',
    name:'Index',
    component: () => import('../views/Index.vue'),  // 懒加载式引入,当跳转到时才进行引入chunk
    children: [...]
}
// 总路由管理文件 index.js 写法
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routerList = []  // 路由数组 - 存放所有路由
function importAll(routerArr){
    // 该函数用于将所有分区路由中的路由添加到路由数组
    routerArr.keys().forEach( key => {
        console.log(key)
        routerList.push(routerArr(key).default)
    })
}
importAll(require.context('.',true,/\.routes\.js/))

const routes = [
    ...routerList
]

const router = new VueRouter({
    routes
})

export default router

运行程序,我们看下是否能够正常显示并分析两句打印

优化之后的代码,会更灵活,更具有观赏性,既便捷高效,又方便维护


2 -「拯救繁乱的template」

很多人在写组件的时候,会依赖脚手架中的<template></template>标签,其实template也存在一定的缺陷,例如:

  • template里存在一值多判断
  • 过多使用template会使代码冗余,杂乱

VUE给我们提供了一个render函数,我们可以通过这个函数巧妙的解决template造成的问题

实战 - 处理多个button

<template>
  <div>
    <h1>I am Home</h1>
    <!-- 假设按钮有多种类型,通过value来显示不同类型 -->
    <div v-if='value === 1'>
      <button>button1</button>
    </div>
    <div v-else-if='value === 2'>
      <button>button2</button>
    </div>
    <div v-else>
      <button>button3</button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Home',
  data(){
    return{
        value:1
    }
  },
  methods:{
  }
}
</script>

<style scoped lang="less">
</style>

上面这种写法,当出现多种类型的button,就会显得杂乱无章,当然,很多人会选择去封装一个button组件,那么这个组件的封装,又是一个技巧点,利用VUE的render函数,减少不必要的template,因此ru我们可以这样写

// 创建一个button.vue文件 写法如下

<script>
export default {
    props:{
        type:{
            type:String,
            default:'normal'
        },
        text:{
            type:String,
            default:'button'
        }
    },
    render(h){
        /*
            h 类似于 createElement, 接受2个参数
            1 - 元素
            2 - 选项
         */
        return h('button',{
            // 相当于 v-bind:class
            class:{
                btn:true,
                'btn-success':this.type === 'success',
                'btn-danger':this.type === 'danger',
                'btn-warning':this.type === 'warning',
                'btn-normal':this.type === 'normal',
            },
            domProps:{
                innerText: this.text || '默认'
            },
            on:{
                click:this.handleClick
            }
        })
    },
    methods:{
        handleClick(){
            this.$emit('myClick')
        }
    }
}
</script>

<style scoped>
.btn{
    width: 100px;
    height:40px;
    line-height:40px;
    border:0px;
    border-radius:5px;
    color:#ffff;
}
.btn-success{
    background:#2ecc71;
}
.btn-danger{
    background:#e74c3c;
}
.btn-warning{
    background:#f39c12;
}
.btn-normal{
    background:#bdc3c7;
}
</style>
//  引入

<template>
  <div>
    <h1>I am Home</h1>
    <!-- 按钮根据value显示不同类型的button -->
    <Button type='success' text='button1' @myClick='...'></Button>
  </div>
</template>

<script>
import Button from './button.vue'
export default {
  name: 'Home',
  data(){
    return{
        value:1
    }
  },
  components:{
      Button
  },
  methods:{
  }
}
</script>

<style scoped lang="less">
</style>

上面这种写法,根据value来显示不同类型的button,我们只需要通过value去修改type,text等,就可以实现这一目的,而不需要去创建多个<button>,通过v-if去判断

优化之后的代码,避免了一值多判断的缺点,减少冗余,更加灵活, 这种方式较适合业务简单,使用次数多的组件


3 -「高精度全局权限处理」

权限的控制由前端处理的场景很多,例如根据后台返回内容,判断该人是否对此功能有权限,进而去修改元素v-if / v-show,这种情况下,当这个功能在多处地方出现,就会导致我们做很多很多不必要的重复代码,如果判断条件繁琐的情况,更加冗余,代码量也会增加很多。因此我们可以造一个小车轮,挂在全局上对权限进行处理

实战 - 处理某按钮显示权限问题

这种场景出现几率极高,尤其是处理含有多种角色的项目,如果这一类型的权限判断有多次处理,每一次出现都经历判断的话,代码将会异常难看且冗余,因此我们可以通过全局权限判断来处理

/*
    在项目里新建一个common文件夹用于存放全局 .js 文件
    这种全局文件夹做法相当普遍,一般项目里都应该有这样一个文件夹来管理全局的东西
*/

// common/jurisdiction.js  用于存放与权限相关的全局函数/变量

export function checkJurisdiction(key) {
    // 权限数组
    let jurisdictionList = ['1', '2', '3', '5']
    let index = jurisdictionList.indexOf(key)
    console.log('index:',index)
    if (index > -1) {
        // 有权限
        return true
    } else {
        // 无权限
        return false
    }
}
// 将全局权限Js挂载到全局中
// main.js

import { checkJurisdiction } from './common/jurisdiction'

// 优雅操作 - VUE自定义指令
Vue.directive('permission',{
  inserted(el, binding){
    // inserted → 元素插入的时候
    
    let permission = binding.value // 获取到 v-permission的值

    if(permission){
      let hasPermission = checkJurisdiction(permission)
      if(!hasPermission){
        // 没有权限 移除Dom元素
        el.parentNode && el.parentNode.removeChild(el)
      }
    }else{
      throw new Error('需要传key')
    }
  }
})
// 使用方式

<template>
  <div>
    <h1>I am Home</h1>
    <!-- 按钮根据value -->
    <div v-permission="'10'">
      <button>权限1</button>
    </div>
    <div v-permission="'5'">
      <button>权限2</button>
    </div>
  </div>
</template>

// 无需再通过value去判断,直接通过v-permission的值进行判断即可

运行程序,我们看下是否能够正常显示并分析打印

可以看到 v-permission = "'10'"是没有权限且不显示,v-permission = "'5'"是具有权限且显示


总结

以上三个方面操作起来看似简单,但很多人在写代码的时候,喜欢停留在业务上,只考虑能否实现,实际上,很多大型项目都需要有这些理念去减少代码量,减少冗余,在合适的场景下使用合适的方法才能提高自己的能力

? Tips: 如果文章有错误的地方,希望指出,觉得有用的小伙伴点个赞哦 QAQ

推荐Vue学习资料文章:

「实践」深入对比 Vue 3.0 Composition API 和 React Hooks

前端网红框架的插件机制全梳理(axios、koa、redux、vuex)

深入Vue 必学高阶组件 HOC「进阶篇」

深入学习Vue的data、computed、watch来实现最精简响应式系统

10个实例小练习,快速入门熟练 Vue3 核心新特性(一)

10个实例小练习,快速入门熟练 Vue3 核心新特性(二)

教你部署搭建一个Vue-cli4+Webpack移动端框架「实践」

2020前端就业Vue框架篇「实践」

详解Vue3中 router 带来了哪些变化?

Vue项目部署及性能优化指导篇「实践」

Vue高性能渲染大数据Tree组件「实践」

尤大大细品VuePress搭建技术网站与个人博客「实践」

10个Vue开发技巧「实践」

是什么导致尤大大选择放弃Webpack?【vite 原理解析】

带你了解 vue-next(Vue 3.0)之 小试牛刀【实践】

带你了解 vue-next(Vue 3.0)之 初入茅庐【实践】

实践Vue 3.0做JSX(TSX)风格的组件开发

一篇文章教你并列比较React.js和Vue.js的语法【实践】

手拉手带你开启Vue3世界的鬼斧神工【实践】

深入浅出通过vue-cli3构建一个SSR应用程序【实践】

怎样为你的 Vue.js 单页应用提速

聊聊昨晚尤雨溪现场针对Vue3.0 Beta版本新特性知识点汇总

【新消息】Vue 3.0 Beta 版本发布,你还学的动么?

Vue真是太好了 壹万多字的Vue知识点 超详细!

Vue + Koa从零打造一个H5页面可视化编辑器——Quark-h5

深入浅出Vue3 跟着尤雨溪学 TypeScript 之 Ref 【实践】

手把手教你深入浅出vue-cli3升级vue-cli4的方法

Vue 3.0 Beta 和React 开发者分别杠上了

手把手教你用vue drag chart 实现一个可以拖动 / 缩放的图表组件

Vue3 尝鲜

总结Vue组件的通信

手把手让你成为更好的Vue.js开发人员的12个技巧和窍门【实践】

Vue 开源项目 TOP45

2020 年,Vue 受欢迎程度是否会超过 React?

尤雨溪:Vue 3.0的设计原则

使用vue实现HTML页面生成图片

实现全栈收银系统(Node+Vue)(上)

实现全栈收银系统(Node+Vue)(下)

vue引入原生高德地图

Vue合理配置WebSocket并实现群聊

多年vue项目实战经验汇总

vue之将echart封装为组件

基于 Vue 的两层吸顶踩坑总结

Vue插件总结【前端开发必备】

Vue 开发必须知道的 36 个技巧【近1W字】

构建大型 Vue.js 项目的10条建议

深入理解vue中的slot与slot-scope

手把手教你Vue解析pdf(base64)转图片【实践】

使用vue+node搭建前端异常监控系统

推荐 8 个漂亮的 vue.js 进度条组件

基于Vue实现拖拽升级(九宫格拖拽)

手摸手,带你用vue撸后台 系列二(登录权限篇)

手摸手,带你用vue撸后台 系列三(实战篇)

前端框架用vue还是react?清晰对比两者差异

Vue组件间通信几种方式,你用哪种?【实践】

浅析 React / Vue 跨端渲染原理与实现

10个Vue开发技巧助力成为更好的工程师

手把手教你Vue之父子组件间通信实践讲解【props、$ref 、$emit】

1W字长文+多图,带你了解vue的双向数据绑定源码实现

深入浅出Vue3 的响应式和以前的区别到底在哪里?【实践】

干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)

基于Vue/VueRouter/Vuex/Axios登录路由和接口级拦截原理与实现

手把手教你D3.js 实现数据可视化极速上手到Vue应用

吃透 Vue 项目开发实践|16个方面深入前端工程化开发技巧【上】

吃透 Vue 项目开发实践|16个方面深入前端工程化开发技巧【中】

吃透 Vue 项目开发实践|16个方面深入前端工程化开发技巧【下】

Vue3.0权限管理实现流程【实践】

后台管理系统,前端Vue根据角色动态设置菜单栏和路由

作者: CHICAGO

转发连接:https://juejin.im/post/5e475829f265da57444ab10f

相关推荐

从IDEA开始,迈进GO语言之门(idea got)

前言笔者在学习GO语言编程的时候,GO语言在国内还没有像JAVA/Php/Python那样普及,绕了不少的弯路,要开始入门学习一门编程语言,最好就先从选择一个好的编程语言的开发环境开始,有了这个开发环...

基于SpringBoot+MyBatis的私人影院java网上购票jsp源代码Mysql

本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目介绍基于SpringBoot...

基于springboot的个人服装管理系统java网上商城jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目介绍基于springboot...

基于springboot的美食网站Java食品销售jsp源代码Mysql

本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目介绍基于springboot...

贸易管理进销存springboot云管货管账分析java jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目描述贸易管理进销存spring...

SpringBoot+VUE员工信息管理系统Java人员管理jsp源代码Mysql

本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目介绍SpringBoot+V...

目前见过最牛的一个SpringBoot商城项目(附源码)还有人没用过吗

帮粉丝找了一个基于SpringBoot的天猫商城项目,快速部署运行,所用技术:MySQL,Druid,Log4j2,Maven,Echarts,Bootstrap...免费给大家分享出来前台演示...

SpringBoot+Mysql实现的手机商城附带源码演示导入视频

今天为大家带来的是基于SpringBoot+JPA+Thymeleaf框架的手机商城管理系统,商城系统分为前台和后台、前台用的是Bootstrap框架后台用的是SpringBoot+JPA都是现在主...

全网首发!马士兵内部共享—1658页《Java面试突击核心讲》

又是一年一度的“金九银十”秋招大热门,为助力广大程序员朋友“面试造火箭”,小编今天给大家分享的便是这份马士兵内部的面试神技——1658页《Java面试突击核心讲》!...

SpringBoot数据库操作的应用(springboot与数据库交互)

1.JDBC+HikariDataSource...

SpringBoot 整合 Flink 实时同步 MySQL

1、需求在Flink发布SpringBoot打包的jar包能够实时同步MySQL表,做到原表进行新增、修改、删除的时候目标表都能对应同步。...

SpringBoot + Mybatis + Shiro + mysql + redis智能平台源码分享

后端技术栈基于SpringBoot+Mybatis+Shiro+mysql+redis构建的智慧云智能教育平台基于数据驱动视图的理念封装element-ui,即使没有vue的使...

Springboot+Mysql舞蹈课程在线预约系统源码附带视频运行教程

今天发布的是由【猿来入此】的优秀学员独立做的一个基于springboot脚手架的Springboot+Mysql舞蹈课程在线预约系统,系统项目源代码在【猿来入此】获取!https://www.yuan...

SpringBoot+Mysql在线众筹系统源码+讲解视频+开发文档(参考论文

今天发布的是由【猿来入此】的优秀学员独立做的一个基于springboot脚手架的在线众筹管理系统,主要实现了普通用户在线参与众筹基本操作流程的全部功能,系统分普通用户、超级管理员等角色,除基础脚手架外...

Docker一键部署 SpringBoot 应用的方法,贼快贼好用

这两天发现个Gradle插件,支持一键打包、推送Docker镜像。今天我们来讲讲这个插件,希望对大家有所帮助!GradleDockerPlugin简介...

取消回复欢迎 发表评论: