一.前端的思想
1.风格
- 选项式optional:传统的vue2写法,有面向对象思想,便于理解,适合渐进增强页面。
- 原始cdn版本:<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
- esm版本:<script type="module"> import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'</script>
- 生产环境:cdn:官方
- 组合式:更加灵活,配合组件开发,适合构建单页应用。
- SFC开发:用vite或webpack
- 优点:没有vue对象的this陷阱,代码更自由、清晰
- 生产搭配:ts、jsx
- nuxt、ssg/ssr-vue3-nodejs-npm/yarn-vite:静态站点渲染
- 优势: 高度和cdn节点配合,提高seo排名和首页速度
- sfc-vue3-npm/yarn-vite:组合式开发
- 优势:代码进一步内聚,极快的调试速度
- sfc-vue2-npm/yarn-webpack:选项式开发
- 优势:组件开发代码内聚,响应式数据解决前后端分离。
- webcomponent:允许原生的组件开发
- 优势:模块分离
- 缺点:无法与原生互动
- jquery-layui-asp/jsp:传统的原生js开发和服务端渲染
- 特点:需要配合动态页面渲染使用,一样能实现功能
- 缺点:文件高度耦合混乱,性能表现不佳。
- 后端选型:tp、.netcore、gin、java-springcloud、django、node-koa2
- nuxt、ssg/ssr-vue3-nodejs-npm/yarn-vite:静态站点渲染
- 项目进阶:
- 亮点:
- 动态权限:动态路由
- 低代码管理:自动表单和查库代码。
- 断点续传、大文件上传:前后端同步传输数据
- 微服务:jwt鉴权、缓存、中间件解耦
- 优化:首屏速度,防抖、jvm、
- 数据说明:
- 难点:
- echarts:数据重叠渲染问题
- 虚拟列表:懒加载的实现
- 说个时间段2015-7~2016-7:从jquery到基础es6,重要的思想,开发的基本姿态——调试、ide、合作、linux运维
- 2016-7~2017-7:从spa入手,linux运维持续、spring系列、git、java
- 2017-7~2018-7:spring、vue、linux、golang、vue源码、各种开源库
- 2018-7~2019-7:音视频、go、ffmpeg、mac开发、持续linux
- 2019-7~2020-7:electron、mysql原理、嵌入式、持续的go和vue生态、材料学
- 2020-7~2021-7:油猴,开启一些难题解决文档、视频领域、c++、
- 2021-7~2022-7:nuxt3、车、电力、uniapp、各种面试级别的细节、
- 2022-7~2023-7:无
- 同步:
如何看待关注点分离?
一些有着传统 Web 开发背景的用户可能会因为 SFC 将不同的关注点集合在一处而有所顾虑,觉得 HTML/CSS/JS 应当是分离开的!
要回答这个问题,我们必须对这一点达成共识:前端开发的关注点不是完全基于文件类型分离的。前端工程化的最终目的都是为了能够更好地维护代码。关注点分离不应该是教条式地将其视为文件类型的区别和分离,仅仅这样并不够帮我们在日益复杂的前端应用的背景下提高开发效率。
在现代的 UI 开发中,我们发现与其将代码库划分为三个巨大的层,相互交织在一起,不如将它们划分为松散耦合的组件,再按需组合起来。在一个组件中,其模板、逻辑和样式本就是有内在联系的、是耦合的,将它们放在一起,实际上使组件更有内聚性和可维护性。
即使你不喜欢单文件组件这样的形式而仍然选择拆分单独的 JavaScript 和 CSS 文件,也没关系,你还是可以通过资源导入功能获得热更新和预编译等功能的支持。
- 响应式:底层使用代理的观察者模式,一个dom能实时对变量的"观察"订阅。
- 本质mvvm:数据改变——视图层数据改变
- 网页:数据—(响应式)—虚拟dom—(diff算法)—真实dom(document)
- 客户端:数据——图形组件对象化
- 游戏引擎(图形引擎):数据——图形组件对象化
- 本质mvvm:数据改变——视图层数据改变
2.开发工具和扩展
全局开发:
eslint(js代码提示)、code fomatter(整理)、autoclosed(节省力气)、gitlent(代码管理)、
restclient、live、open in browser、md-preview、
nodejs:document this(快速注解)
volar:vue3的intelligence和typescript支持
vnler:vue2的intelligence支持
vue-cli的typescript支持:不推荐,不支持
flex:Flexible.js做响应式布局
3.选项式开发-vue对象
- 更换语法
- Vue全局方法createApp():代替new vue()
- mount(#id):代替el:#id
- data域:统一使用
data(){return{mes:1}}
- 更新细节
- v-once:只渲染一次
- v-html:<span v-html>以原始html值渲染dom节点
- {{}}插值表达式:支持原始javascript表达式如{{msg.split()}}
- v-bind:
- 绑定多个值:使用不带参数的v-bind
objectOfAttrs: { id: 'container', class: 'wrapper' }
- 绑定属性值:<a [attributename]="url">
- v-for:
- 不会渲染的<div>:
<template v-for ="item in items">
- :key="id":绑定状态,不用重新渲染
- 不会渲染的<div>:
- v-on:可为其增加子触发条件@click.
- .right、.left:按左右鼠标键
- .ctrl:按ctrl键组合
- v-model:
- placeholder属性:默认值
- :class:不用字符串拼接,而是用boolean值的对象控制
- :class="{attr:isTrue}"
- {a,b}数组形式:变量控制class值
- :style:支持使用变量
- watch:{}监听变量的回调方法
- 插槽:作用是父的dom节点插入到子节点中(反向插入组合)
- <template-name>:父组件在标签中插入内容
- <slot>:写在子组件
- 传双绑变量:子父组件的v-model传值
- 子组件 :
- 父组件:
- 一些项目常用配置
4.vite
- vite和webpack的区别:都是打包js代码,主要差别在开发阶段
- 安装:npm create vite@latest:生成一个需要install的项目(需网络)
- cli:
npm i @vue/cli -g
- cli:
- 初始化项目:npm create vite@latest my-vue-app --template vue
- cli:
vue create vue-cli-name
需要提前装好cli才有的命令(直接装好依赖,需要网络)
- cli:
- vite:npm run dev
- 只是启动服务器启动快
- 原生esm语句+请求时构建(编译)快+按需加载
- webpack:npm run server、需要全部文件构建和加载
- 安装:npm create vite@latest:生成一个需要install的项目(需网络)
- yarn命令和npm命令:都是管理依赖和命令
- 先安装命令:同cnpm:
npm i yarn -g
- yarn:效率更高、版本锁,npm5.0后没区别
- 构建:yarn——npm install
- 运行调试:yarn dev——npm run dev
- 先安装命令:同cnpm:
5.组合式开发-sfc文件
- 变量和函数:data域与method变为接近于原生定义
- ref响应式基础类型:生成了一个对象x,里面由isref属性,value是一个对源的引用
- x=ref("0")普通值:随意改变x也能响应
- x=ref([])数组:此时可以通过x.value获取的能给他赋值,且能响应
- x=ref({})对象:用x.value使用方式能改变x,x.count是响应
- x=ref(object.name)对象的属性:但无法改变object的值,需要用toref才能引用object——应用:prop对象的值,需要toref解构。
- reactive创建proxy对象代理数组和对象:
- y=reactive({})对象:能通过该proxy改变值y.xxProp和响应渲染数据,但不能赋值(改变源)
- 但该代理对象的值需要监听时:需要用getter函数
- 如果由源对象:不会跟踪改变
- y=reactive([])数组:能通过b[0]=x改变某一项或push数据和响应渲染数据,但不能赋值(改变源)
- y=reactive(object.name)对象的值:不行,没意义,因为object已经被reactive了。
- 代理基础类型:不行,但可以reactive({value:18}),此时在模板中使用需要手动.value,效果一样
- y=reactive({})对象:能通过该proxy改变值y.xxProp和响应渲染数据,但不能赋值(改变源)
- 注意:赋值reactive([])时,需要用
-
const getList = ()=>{ let newArr = [1,2,3,4] arr.push(...newArr) }
- ref响应式基础类型:生成了一个对象x,里面由isref属性,value是一个对源的引用
- 生命周期和watch
- 函数lambda:watch(()=>{})
- onMounted(()=>{})
- props和emit
- defineProps({})
- defineemit({})
- 大坑:reactive()
- 路由vue-router:路由对象是全局的
- history模式:Createxxhistory()
- hash:哈希字符#隔离
- web:传统的h5模式
- 定义:createRoute({conponents})和use(route)
- 组件使用routes:userRouter()组件跳转、useRoute()上层传递的对象、
- 路由切换:router.push({name:,path:,query:})
- 二级路由:children{}
- history模式:Createxxhistory()
- pinia:vuex的替代品
- 作用:代替服务器的session域存储对象功能
- 定义:defineStore({})、storeToRefs()将store对象的属性转为响应式变量
- 使用:引入对象直接使用const store=xxstore()
- 取属性:直接取
- 用方法:直接用method域中的方法
- optional和composion对比:
- 组件:
- 选项式:可以兼容cdn式开发,export default{} +components注册
- 组合式:适合构建工具内开发,不用export,名字随便命名
- js:
- 选项式:导入整个文件夹默认导入的是index,default+自定义命名。
- 组合式:主页面对象:createApp()——new vue({}),子js,需要const一个命名对象。
- 组件:
6.webcomponent
- 简介:原生支持的组件化开发
- 实现:基于模块化modul和自定义标签元素
- 意义:实现跨框架和原生的组件组合
- 初始化:npm init custom-element
- 配置:vite的build命令和vue主页的识别
- 源码:导出一个或多个文件夹下的vue组件(原生支持)
- 使用:
npm run build
生成js- 模块导入:<script type="module">
- 自定义标签:<custom-element>
7.详解路由
二.模块
1.echarts
- 可视化:以图表的形式展现数据,展现数据趋势
- 应用:销量统计、流量统计、图书数量统计
- 简介:
- 技术:基于zrender的矢量图形库
- 应用:支持多种数据结构和图标类型
- 全局对象:echarts
- connect([c1,c2]):关联数据产生联动——toolbox的保存图片,重置按钮
- registerTheme:('name',{}):配合init(,theme)使用默认dark、color、可去官网自定义
- init(dom,theme):初始化容器
- 图表实例echartsInstance:myEchart
- setoption():多次调用可以实现增量的动画效果
- resize():一般同步windows.onresize
- showLoading()、hideLoading():加载动画的显示
- on('click',function(arg){})监听图表的点击事件:
- legendselectchanged图例改变事件
- off('click'):注销事件
- dispatchaction():传入对象模拟触发事件({})
- type:'类型'heightlight高亮、
- clear()可再次setoption()更新数据
- dispose()销毁对象
- option对象
- title:标题
- textstyle:配置文字样式
- borderxx:文字边框
- left、top:位置
- xAxis: x轴,多对多的主键之一
- data:xDataArr主轴数组
- axisLabel:控制x轴值样式,interval文字间隔
- type:类目值'catagory'
- posision:只有四个top、bottom
- offset:相对默认第一位置的偏移量
- axisTick:show:显示坐标刻度
- axisLine:show显示轴线
- axisLineLabel:轴标签的样式
- yAxis:y轴,一般type是数值value
- series:是一个对象数组,由主轴多对多绑定(一个类目有多个属性)
- {name、type:bar/pie、data:yDataArr}:legend相关的控制值多对多的主键之二
- markPoint:data:[]特殊值标记
- markline:data:[]特殊值标行
- lable:标记每个值
- barwidth:宽度
- theme:主题
- backgroundColor背景颜色:
- grid:图标依附的网格盒子
- show
- borderwidth、color:颜色
- left、width:控制大小
- tooltip:鼠标滑过提示
- trigger类型:item在柱上显示、axis线性在线上就能显示
- triggerOn:默认是滑过mouseover、click
- formatter内容:默认如上,{a}系列名(series.name)、{b}类目值(x轴)、{c}value,也可用回调函数形式arg对象形式封装数据:seriesName、name、data(value)、
- toolbox:工具栏按钮
- feature:saveAsImage{}导出图片、magictype:type:[]图表类型互转按钮、dataZoom缩放、dataview、restore重置
- legend:控制series里的对象数组显示的,data需要和series.name配合、
- animation:true开启动画
- animationDUration动画时长配合使用,
- datazoom:
- type:slider滚轮和inside鼠标缩放
- xAxisIndex:控制x还是y轴
- title:标题
- 柱状bar:多数据,分类的数据大小对比明显,可能为线柱结合
- 横:更适合多对多(某列对某列)
- 时间、人物
- 时间、厂区
- 时间、团队
- 机型
- 竖:更适合数据多
- 设计工件:xaxis人(一行数组)、series:name月份,data:数量(一行数组)
- 横:更适合多对多(某列对某列)
- 饼图pie:清楚的比例
- seies:
- data:一定是{name:value:}对象数组
- lable:fomatter:回调形式percent比例、value值
- radius:[]设置圆环半价
- roseType:南丁格尔图
- selectedMode:选中效果
- seies:
- 折线图line:总体趋势,上下降趋势
- series:
- markArea:区域阴影值
- smooth:true开启平滑
- linestyle:控制线的样式
- areaStyle:color控制阴影颜色
- stack:all开启数组数据堆叠
- xAxis
- boundaryGap:控制x轴间隔
- yAxis
- scale:从最小值显示y轴
- series:
- 散点图scatter:探究双变量的相关性
- xAxia、yAxia:设置双值轴type:value
- series:
- symbolsize:(arg)=>{}控制不同点的大小,arg是data数组
- itemStyle:color:(arg)=>{}控制颜色
- effectsactter涟漪动画:showoneffect:开启
- map地图
- echarts.registerMap('name',data)注册一个地图数据
- geo
- type:map
- map:上面注册的
- center:中心点、zoom:缩放比例
- series:控制与geo关联的颜色样式
- data:[]还是namevalue对象数组
- visualMap:配合series
- inrange:渐变色
- min、max:控制条
- 雷达图
- radar:
- indicator:data[]各个维度最大值
- series:数组
- type
- data:还是namevvalue数组
- radar:
- 技巧1:对象数组转单列数组技巧:取每个对象的单列或多列值push到axisData[]
- 技巧二:使用map()将对象数组过滤出单列值
- 无lengen:data一定是json对象,ret是其中一个key,值是对象数组列表,两列Names[]、Values[]
- 多地区有lengen:第一层多个region获取不同lengen{name,array}
- 具体:common.mouth是Names[]类目轴,series数组:seriesArr——代表上边name+data的集合
- 总结
- 主题
- init(dom,theme)
- js构建:底层通过registerTheme()方法注册了方法
- color:主题>全局>局部,会根据
- itemstyle:设置在series则是全局,在data里则是单个
- color:设置渐变
- emphasis:高亮
- itemstyle:具体设置
- 多轴:
- xAxis:data[]为空,默认填充0,1
- series:data[]为对象 {name:'a',value:1},,formatter时取name值替代xAxis的data[]、value就是正常值
- 多个series+空xAxis+多层grid:实现不等分的series:bar代替xAxis
2.canvas
3.scss和Less
- scss:
- 作用:简化css开发
- less:
- 作用:提高css中的重用性、
- 语法:
- @变量:属性用@{x},值用@x
- url:
- 嵌套:子.div{#id{}}
- 多属性重用:{.class}
4.axios
- Ajax思想:异步请求,局部刷新
- es5实现:xmlhttprequset的回调函数
- es6实现:fetch基于promise对象,用then()链式调用处理结果
- vue的好兄弟:axios支持拦截、自动转换、易用的特点
- 使用:
5.typescript
- 简介:微软出品,旨在解决js的弱类型问题,使其接近后端语言
- 变量:增加类型let x:{type:string,required:true}
6.flex布局
Flex 布局教程:语法篇 - 阮一峰的网络日志 (ruanyifeng.com)
- display:flex
- 特点:弹性、子元素不允许float、clear、vertical-align,子可设比例。
- 父div:主轴(水平),交叉轴(垂直),对齐和换行的位置
- flex-direction:row、row-reverse主轴和起点。默认row
- flex-wrap:nowrap是垂直布局/wap宽度不够换行否,不换行则会压缩,默认nowrap
- flex-flow:简写上面2个
- justify-content:当子div有分掉剩余空间的样式时不生效center在主轴对齐方向,space-around
- align-items:center单轴在交叉轴对齐方向,stretch默认值无宽度则会占满整个交叉轴
- align-content:center、start多条主轴在交叉轴对齐方向,stretch默认值
- 子div:大小和排名
- order:排名顺序,从0开始
- grow:除去已设置的剩余空间的放大比例,会覆盖自身的width。0消失,其他数字是比例。
- shrink:除去已设置0表示不变的剩余空间的缩小比例,从1开始,未设置默认为1。
- flex-basis:auto表示原本大小,子div的大小
- flex:一次定义上面3个
- align-self:单独定义交叉轴对齐
- grid:grid广泛应用于elementui、bootstrap、原生grid
- container:固定大小,相当于父容器,能放很多行。
- 对应<main>或其他容器
- row:按内容划分高度
- column:按父容器等比例划分宽度,但无法自动换行。
- 与flex区别:flex能换行但无比例,grid规定列数能换行。
- container:固定大小,相当于父容器,能放很多行。
- element库:<el-xx :column=x>
- 总样式::style=boxshadow:
- 布局容器:<el-container>一个div容器只能放4种大型子标签——<el-head><el-main><el-aside><el-footer>和<el-container>
- 属性:direction:有head和footer变为vertical
- 应用:cotainer里嵌套好整体,加入main就可以使用grid布局
- 布局:<el-row><el-col :span>默认的flex布局容器
- 属性:gutter间隔、offset、justify、align
- 应用:单row用来作顶层导航
- 注意点:row
- 图标:<el-icon >可嵌入svg标签<Edit/>
- 原始svg:只可通过style控制样式
- 属性:color、:size控制图标大小
- 应用:通过属性或标签可方便内嵌图标,快速图标——使用:icon属性
- 菜单:<el-menu :default-openeds="['1', '3']"> ,<el-sub-menu>一级选择包含标题和展开,<el-menu-item-group>展开组
- 属性:index索引
- 滚动条<el-scrollbar: 超过高度则触发滚动条
- 属性:max-height="400px"
- 应用:数据列表
- 卡片:自带阴影和卡片布局
- 卡片区域 <el-space> :间隔固定
- 属性:spacer="|"分隔符属性:wrap :size="size"设置分隔符大小,:fill设置是否填充space容器
- 卡片<el-card>:<template #header><div class="card-header">可替换的卡片头
- 应用:经典博客,首页
- 卡片区域 <el-space> :间隔固定
- 全局配置:应用在一些设置上
- element表单:
- 滚动条:<el-slider v-model="size" />
- 开关: <el-switch v-model="fill" />
- 单行:<el-input>
- 重要属性:clearable=clearable、formatter
- 自动补全输入框:<el-autocomplete>
- 多行:
- 下拉选择:<el-cascader v-model="value" :options="options" @change="handleChange" />选择的升级,自动级联同一个value
- 多选optionbutton:
- 单项radiobutton:
- 按钮:
- 日期选择:
- element数据展示:
- 反馈组件:
- 导航组件:
三.uniapp
1.简介
- 平台通用性:语法吸收各个语言,可打包成各种平台应用。
- 组件:支持npm、vite打包,同vue语法
- 开发工具:hbuilder、插件、sdk
- 性能:比原生强
2.使用
四.ssr和ssg
1.ssr
- 简介:服务端
- 作用:提高seo排名(博客),和首页加载速度(电商)
- 副作用:提高服务器负载,增加复杂度
- 区别于ssg:ssr需要动态渲染ajax页面,ssg更适合文章类、关于页面。
- 例如这个就是ssg页面,能上cdn保存
- 原理:
- 首页就是index.vue(app.vue
- )会让nodejs服务端进行路由匹配+组件渲染(渲染谁都一样快,但网络传输需要时间)
- 并将打包的bunlle.js异步加载返回
- 上手:
- 环境:需要一个node.js服务器
-
- 约定式开发:pages(views)、layout、assests目录下的组件不需要模块引入。
-
- 安装项目:
npx nuxi init nuxt-app
- 环境:需要一个node.js服务器
- 对比和区别:
- 组件components:
- nuxt:components目录下和layouts目录下直接可用文件同名组件,嵌套时可使用文件夹前缀
- vue3:导入和导出imports 组件 from path
- 路由注册router.js:
- nuxt:pages下的index.vue作为默认/路由所在,<NuxtPage><NuxtChild>搞定坑位,
- vue3:需要层层注册routes信息
- 相同:第一层路由坑就在app.vue——<NuxtPage>
- 路由传参:
- nuxt:命名page1-[id]定义键值,多层参数添加page1文件夹xx-[name],访问时即可加上values值
- vue3:push时添加querry字段或param字段,link to添加?或restful参数/id/3
- 路由跳转:只是第一层
- nuxt:在app.vue里使用<NuxtPage></NuxtPage>作为路由坑,<NuxtLink></NuxtLink>作为按钮跳转,
- vue3:在app.vue里使用<route-view>
- 路由嵌套:多层时
- nuxt:parent使用<NuxtChild></NuxtChild>自动跟踪目录下的文件同名路径<NuxtLink to="/parent/child">/parent/child</NuxtLink>
- vue3:需要为该路径path配置children:[]
- 布局:布局模板相当于组件
- nuxt:<NuxtLayout name="default">在pages的index.vue引用一个名为default.vue的布局组件,而default.vue可以是footer、各种组件。
- vue3:
- 固定布局模式:自己设置一个layout目录下,其由很多footer等组成。为index.vue设置一个/layout路由会加载出固定布局,在布局模板下路由跳转用layout/xx
- 不同页面模式:可引用布局组件,并使用插槽
- 组件components:
- Composables:相当于utils方法或是某个Store下的方法
- 嵌套限制:无法在utils嵌套文件夹
- 数据请求:直接抛弃axios
- 1.使用useAsyncData()异步方法需要配置一些信息
- 2.useFetch(url,data)相当于是service(url,data)
- 路由守卫middleware:
- defineNuxtRouteMiddleware((to, from) => {})
- 单独守卫
- SEO:nuxt3为seo而生
- 为单独页面配置<meta>属性:useHead()
2.ssg
五.读源码
1.渲染机制
- 虚拟dom:存在内存,
- 意义:虚拟 DOM 带来的主要收益是它让开发者能够灵活、声明式地创建、检查和组合所需 UI 的结构,同时只需把具体的 DOM 操作留给渲染器去处理。
- diff算法:首尾节点法。
2.补充一下细节
- data:
- 组件的data为什么必须是函数:因为对象实例是公用的,函数则是返回新的对象。
- method和watch的区别:
- 是否有缓存
- watch和computed区别
- watch:重点在于监听数据变化,只能监听一个对象
- computed:重点在于监听多个数据,且不能处理异步代码。
- v-model:
- .lazy:把input事件改成change事件
- .number:
- 动态组件:<keep-alive>
- 功能:缓存一个组件到内存中
- 新的生命周期:activated()和deactivated()
- :include属性:规定需要缓存的组件
- 应用:解决输入信息不需要重填的体验
- 作用域插槽:<slot :>
- 应用场景:当需要将子组件数据做不同方式渲染的时候
本文作者为byzhj,转载请注明。