关于less:Less基础使用秘籍让你的CSS更高效

Less(Leaner Style Sheets 的缩写) 是一门向后兼容的 CSS 扩大语言。,它扩大了CSS(层叠样式表)的性能并提供了更灵便、更弱小的款式定义和管理机制。通过应用 Less,开发人员能够编写可保护、可重用的款式代码,并以简洁的语法实现简单的款式成果。本文将介绍 Less 的基本概念和个性,以及如何应用它来简化 CSS 开发过程。想要学习更多的常识,可拜访 犀牛书 的 Less 中文文档。 装置要装置 Less,首先须要确保本地已装置 Node.js 环境,而后运行如下命令,将 Less 装置到零碎的全局环境中: npm install less -g装置结束,可在控制台运行命令lessc -v,如果呈现相干的版本信息,阐明曾经装置胜利。 编译运行在 IED 编辑器如 Vscode 中,新建一个以 .less 为后缀的文件,文件内容可放入如下 Less 格局的款式元素。 @width: 10px;@height: @width + 10px;#header { width: @width; height: @height;}.less文件建设结束并填写内容后,下一步可用命令lessc [option option=parameter ...] <source> [destination]将其编译为以.css为后缀的文件。例如,要将 index.less 编译为 index.css,可用如下命令: lessc index.less index.css编译实现后,即可生成 .css 文件,详情如下图所示: 根本用法变量(Variables)用@申明变量并应用: @width: 10px;@height: @width + 10px;#header { width: @width; height: @height;}输入: ...

June 20, 2023 · 3 min · jiezi

关于less:Less用法小记

正文办法一:通过双斜杠//的形式来进行正文,应用此办法来进行正文在编译成css后,正文在css文件中不会进行展现。办法二:通过斜杠加型号/** */的形式来进行正文,正文会留在编译生成的css文件中。 变量 变量的根底应用变量的定义是通过@变量: 变量值的模式实现的。 @width: 100px; // 这里肯定须要有分号结尾.box { width: @width;}// 编译后果.box { width: 100px;} 变量的扩大应用less变量不仅仅能代表平时的css属性值,有其它很多的场景下也能应用到less变量。 选择器@selector: h2;@{selector} { color: red;}// 编译后果h2 { color: red;} URL门路在less应用门路来引入文件时,须要在门路两边加上单引号或者双引号 @images: '../images'; // 这里必须要有引号.box { background-image: url('@{images}/img.jpg'); // 这里也必须要是应用引号,并且在门路中应用变量时须要大括号包裹变量}// 编译后果.box { background-image: url('../images/img.jpg')}在应用import关键字引入其它less时,变量也能发挥作用 // external.less@color: red;// index.less@path: '../style/'@import '@{path}/external.less'.box { color: @color;}// 编译后果.box { color: red;} 属性名变量值是属性名或属性名一部分时,在援用的时候须要带上大括号。 @color: color;.box { @{color}: green; background-@{color}: red;}// 编译后果.box { color: green; background-color: red;} 混合办法有写过css的同学应该晓得,在一些状况下,局部类选择器有雷同的css属性设置,如果如果想要在各个类选择器中复用这部分css属性,那么须要把公共的css属性独自拿进去,并且为每个类选择器设置这些公共css属性,而后再独自为每个类选择器设置各自的css属性。 ...

January 8, 2023 · 4 min · jiezi

关于less:less预处理插件开发

最近在做less的一些语法上的解决,想把less的变量在编译时主动转为css的变量应用形式,进而学习了一下less的预处理插件开发。 less反对的插件分为两种模式,一种是一般插件,次要是扩大less的运行时语法(less默认函数)插件,通过@plugin语法应用。这种形式的次要应用请参考官网文档,本文不做探讨。 预处理插件能够对编译的源码在编译前,编译后和编译中进行一些代码调整。也能够增加一些对less进行扩大,如文件系统的扩大等。因为官网还没有对这一块有对应的文档形容,所以本文用于在官网文档进去之前,依据本人的应用教训记录的一些最佳实际。 预处理插件代码构造一个简略的预处理插件的格局为: class LessPlugin { constructor(options) { this.minVersion = [3, 0, 0]; this._options = options; } install(less, pluginManager, functions) { // 插件初始化逻辑 } setOptions() {} printUsage() { return ''; }}插件须要是一个领有install办法的对象,会被注入三个参数less, pluginManager, functions: less: 以后less对象;pluginManager: 插件管理器,用于注册具体的插件;functions:外部办法管理器,@plugin应用的一般插件就是通过functions.add增加下来的预处理插件次要是通过pluginManager对象增加,它的要害API有: addVisitor: 增加ast语法拜访器,能够在编译过程中批改或者查看语法操作;addPreProcessor: 增加预处理器,能够配置源码在通过less解决前进行预处理的hookaddPostProcessor: 增加后处理器,能够配置源码在通过less解决后进行后续加工的hookaddFileManager: 增加一个文件管理器,能够扩大文件解析,次要是解决@import的资源导入解析问题能够查看官网举例的插件列表.另外插件对象中请尽量设置minVersion属性,用来表明该插件兼容的最低的less版本;setOptions是用于承受less命令行形式执行时传入的参数,在构造函数中承受的选项是因为创立插件对象采取类的形式,所以能够在构建函数中承受这个对象创立的前置参数,也就是能够用于应用代码的形式配置插件时的传入的选项;printUsage也是在应用命令行形式注入插件(--plugin=xxxx),打印帮忙的时候输入的提示信息。 构建过程中批改源码的插件addVisitor能够加一个less的ast语法处理器,在编译过程中对语法进行解决(如将less变量的应用改为css变量的应用)。一个简略的语法拜访器的插件创立为: class LessPlugin { // ... install(less, pluginManager, functions) { // 注册拜访器,拜访器为一个对象 pluginManager.addVisitor(new ExampleVisitor(less, this._options)); } // ...}class ExampleVisitor { constructor(less, options) { this._less = less; this._options = options; this._visitor = new less.visitors.Visitor(this); } run(root) { return this._visitor.visit(root); } // ...其余代码}对于拜访器对象,咱们同样采取class形式创立。个别状况下,都须要将less对象传入,用于拜访less相干api。 ...

November 7, 2022 · 2 min · jiezi

关于less:lessscss-常用-mixinfunction集合

less&scss 罕用 mixin&function汇合scssmixin:返回款式汇合定义:@mixin 变量名(参数) { 款式 }调用:@include 变量名(参数);mixin 根底用法 // 单行文本溢出@mixin oneRowOverflow { white-space: nowrap; overflow: hidden; text-overflow: ellipsis;}mixin 传参 // 多行文本溢出@mixin multipleRowsOverflow($width, $row) { width: $width; display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; word-break: break-all; text-overflow: ellipsis; -webkit-line-clamp: $row;}mixin 参数默认值 // 多行文本溢出@mixin multipleRowsOverflow($width: 100%, $row: 2) { width: $width; display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; word-break: break-all; text-overflow: ellipsis; -webkit-line-clamp: $row;}mixin + 条件 // 弹性盒布局@mixin flexLayout($justify: null, $align: null, $direction: null) { display: flex; @if $direction !=null { flex-direction: $direction; } @if $justify !=null { justify-content: $justify; } @if $align !=null { align-items: $align; }}mixin + while循环 ...

September 28, 2022 · 1 min · jiezi

关于less:wallysWiFi-6E-80211ax-4×4-MUMIMO-6GHz-QCN9074

WiFi 6E (802.11ax) 4×4 MU-MIMO 6GHz QCN9074 Single Band Wireless ModuleQCN9074 802.11ax 4x4 MU-MIMO 6GHz wifi6E QCN9074 11ax 4x4 6G M.2 **DR9074-6E(PN02.7)** https://www.wallystech.com/Ne... MT7915/MT 7975/IPQ6000/IPQ6018/IPQ6010/IPQ4019/IPQ4029/ipq4018/IPQ8072/IPQ8074/QCN9074/QCN9072/QCN9024/IPQ5018/BY:Wallys Communications (Suzhou ) Co., LTDEMAIL:sales3@wallystech.com Wallys Communications (SuZhou) Co., Ltd., http://www.wallystech.com,which is a professional supplier specializing in product design, manufacturing and offering superior OEM/ODM/JDM services in wireless communications. As a specialized manufacturer and exporter for these products in China,We sincerely hope to establish business relations with your esteemed corporation. We mainly develop high power wireless products based on Quacomm chip such asIPQ6000/IPQ6018/IPQ6010/IPQ4019/IPQ4029/IPQ8072/IPQ8074/QCN9074 and so on . Features Qualcomm Atheros QCN90746GHz, max 23dBm per chain, up to 4949MbpsSingle Band 6GHz 4×4 WiFi 6E (802.11ax)4 spatial streams (4SS)M.2 E Key InterfacePCI Express 3.0 InterfaceApplications Security SurveillanceCommercial radio coverageHotel Wireless applicationCountry coverageForest fire protection engineeringSome special scene applicationProduct Description ...

June 30, 2022 · 2 min · jiezi

关于less:记录TypeError-thisgetOptions-is-not-a-function

明天写我的项目的时候须要用到less,而后装置了less和less-loader,然而之后在写router下的index文件时报错: TypeError: this.getOptions is not a function查问后发现时less-loader版本装置过高。解决办法:第一步: npm uninstall less-loader第二步: npm install less-loader@6.0.0 参考:https://blog.csdn.net/qq_4243...

April 23, 2022 · 1 min · jiezi

关于less:Linux之less命令

Linux中的less命令次要用来浏览文件内容,与more命令的用法类似,不同于more命令的是,less命令可往回卷动浏览以看过的局部。less的用法比起more更加的有弹性。在more的时候,咱们并没有方法向后面翻,只能往后面看,但若应用了less时,就能够应用 [pageup] [pagedown]等按键的性能来往返回后翻看文件,更容易用来查看一个文件的内容!除此之外,在less外头能够领有更多的搜寻性能,不止能够向下搜,也能够向上搜。命令格局less [参数] 文件 命令性能less和more相似,然而应用less能够随便浏览文件,而more仅能向前挪动,却不能向后挪动,more启动时会加载整个文件。而且less在查看之前不会加载整个文件。命令参数Down arrow,Enter,e,或者j --向前挪动一行。Up arrow,y或k -- 向后挪动一行。Space bar 要么 f – 后退一页。b – 向后挪动一页。/pattern – 向前搜寻匹配的模式。?pattern – 向后搜寻匹配的模式。n – 反复上一个搜寻。N – 反向反复先前的搜寻。g – 转到文件的第一行。Ng – 转到文件中的第N行。G – 转到文件的最初一行。p – 转到文件结尾。Np – 进入文件的N%。h – 显示帮忙。q – 退出less。查看文件> less rumenz.txtps查看过程信息并通过less分页显示> ps -ef | less查看命令历史应用记录并通过less分页显示> history | less浏览多个文件> less 1.txt 2.txt输出:n后,切换到 1.txt输出:p后,切换到 2.txt全屏导航ctrl + F - 向前挪动一屏ctrl + B - 向后挪动一屏ctrl + D - 向前挪动半屏ctrl + U - 向后挪动半屏单行导航j - 向前挪动一行k - 向后挪动一行其它导航G - 挪动到最初一行g - 挪动到第一行q / ZZ - 退出 less 命令搜寻性能> less /入门 rumenz.txtn – 向前查找下一个匹配的文本N – 向后查找前一个匹配的文本原文链接:https://rumenz.com/rumenbiji/... 微信公众号:入门小站 ...

December 22, 2021 · 1 min · jiezi

关于less:css多主题色的实现

CSS 主题切换计划形式一: css / var()1. 定义2套主题色彩变量,属性选择器.root[theme='theme-red'] { --color-bg: rgba(255, 87, 87, 0.05); --font-text-color-title: rgba(255, 87, 87, 0.85); --font-text-color-base: rgba(255, 87, 87, 0.65); --primary: #ff5757;}.root[theme='theme-blue'] { --color-bg: rgba(0, 229, 255, 0.05); --font-text-color-title: rgba(0, 229, 255, 0.85); --font-text-color-base: rgba(0, 229, 255, 0.65); --primary: #00e5ff;}2. 主页面中增加属性theme, 值为相应的主题 theme-red 或 theme-blueimport React, { useEffect, useRef, useState } from 'react';import styles from './theme.less';interface ThemePageProps {}const themeMap = { 红色: 'theme-red', 蓝色: 'theme-blue',};const ThemePage: React.FC<ThemePageProps> = () => { const containerRef = useRef<HTMLDivElement>(null); const [theme, setTheme] = useState('theme-red'); useEffect(() => { containerRef.current?.setAttribute('theme', theme); }, [theme]); return ( <div className={styles.root} ref={containerRef}> <div className={styles.content}> <div className={styles.title}>我是题目</div> </div> <div className={styles.btnWrap}> {Object.entries(themeMap).map(([key, value]) => ( <span key={value} onClick={() => setTheme(value)}> {key} </span> ))} </div> </div> );};export default ThemePage;3. 应用主题变量.root { display: flex; flex-direction: column; background-color: var(--color-bg); height: 100vh;}.content { display: flex; align-content: center; justify-content: center; flex-direction: column; .title { text-align: center; font-size: 20px; color: var(--font-text-color-title); } .info { text-indent: 2em; font-size: 16px; color: var(--font-text-color-base); }}.btnWrap { display: flex; justify-content: center; margin-top: 20px; span { width: 120px; height: 32px; display: flex; align-items: center; justify-content: center; color: var(--primary); border: 2px solid var(--primary); background-color: #fff; border-radius: 10px; margin-right: 20px; cursor: pointer; &:hover { font-weight: bold; } }}4.编译后的文件.theme__root__3Nghz[theme='theme-red'] { --color-bg: rgba(255, 87, 87, 0.05); --font-text-color-title: rgba(255, 87, 87, 0.85); --font-text-color-base: rgba(255, 87, 87, 0.65); --primary: #ff5757;}.theme__root__3Nghz[theme='theme-blue'] { --color-bg: rgba(0, 229, 255, 0.05); --font-text-color-title: rgba(0, 229, 255, 0.85); --font-text-color-base: rgba(0, 229, 255, 0.65); --primary: #00e5ff;}.theme__root__3Nghz { display: flex; flex-direction: column; background-color: var(--color-bg); height: 100vh;}.theme__content__1gRQE { display: flex; align-content: center; justify-content: center; flex-direction: column;}.theme__content__1gRQE .theme__title__2W0ZV { text-align: center; font-size: 20px; color: var(--font-text-color-title);}.theme__content__1gRQE .theme__info__2c8iu { text-indent: 2em; font-size: 16px; color: var(--font-text-color-base);}.theme__btnWrap__2ZtlX { display: flex; justify-content: center; margin-top: 20px;}.theme__btnWrap__2ZtlX span { width: 120px; height: 32px; display: flex; align-items: center; justify-content: center; color: var(--primary); border: 2px solid var(--primary); background-color: #fff; border-radius: 10px; margin-right: 20px; cursor: pointer;}.theme__btnWrap__2ZtlX span:hover { font-weight: bold;}形式二 : less/ mixin1. 定义2套主题色彩变量, 用theme函数.theme(theme-red) { @color-bg: rgba(255, 87, 87, 0.05); @font-text-color-title: rgba(255, 87, 87, 0.85); @font-text-color-base: rgba(255, 87, 87, 0.65); @primary: #ff5757;}.theme(theme-blue) { @color-bg: rgba(0, 229, 255, 0.05); @font-text-color-title: rgba(0, 229, 255, 0.85); @font-text-color-base: rgba(0, 229, 255, 0.65); @primary: #00e5ff;}2.:global的形式全局范畴引入两套主题款式.theme-red 和 .theme-blue , 匹配全局的款式名:global(.theme-red) { .createTheme(theme-red);}:global(.theme-blue) { .createTheme(theme-blue);}3. 通过createTheme() 混入到每个作用范畴的less文件下.createTheme(@theme-name) { .theme(@theme-name); // 混入的主题色彩变量申明 .root { display: flex; flex-direction: column; background-color: @color-bg; height: 100vh; } .content { display: flex; align-content: center; justify-content: center; flex-direction: column; .title { text-align: center; font-size: 20px; color: @font-text-color-title; } .info { text-indent: 2em; font-size: 16px; color: @font-text-color-base; } } .btnWrap { display: flex; justify-content: center; margin-top: 20px; span { width: 120px; height: 32px; display: flex; align-items: center; justify-content: center; color: @primary; border: 2px solid @primary; background-color: #fff; border-radius: 10px; margin-right: 20px; cursor: pointer; &:hover { font-weight: bold; } } }}4. 在主页面中增加全局款式import React, { useEffect, useRef, useState } from 'react';import styles from './theme.less';interface ThemePageProps {}const themeMap = { 红色: 'theme-red', 蓝色: 'theme-blue',};const ThemePage: React.FC<ThemePageProps> = () => { const containerRef = useRef<HTMLDivElement>(null); const [theme, setTheme] = useState('theme-red'); useEffect(() => { document.documentElement.className = theme; }, [theme]); return ( <div className={styles.root} ref={containerRef}> <div className={styles.content}> <div className={styles.title}>我是题目</div> </div> <div className={styles.btnWrap}> {Object.entries(themeMap).map(([key, value]) => ( <span key={value} onClick={() => setTheme(value)}> {key} </span> ))} </div> </div> );};export default ThemePage;5. 编译后css文件红色主题 ...

December 12, 2021 · 4 min · jiezi

关于less:最省事的前端动态主题的实现方案

本文章是自己从CSDN迁徙的原创文章2021-12-06更新 提供的vite插件@zougt/vite-plugin-theme-preprocessor,已在v1.4.0反对在线动静主题的实现,比原文中提到的计划六的插件更加易用,具备如下特点: 应用老本很低跟ui框架无关,Element-ui、iview、Ant-design 等等等(只有基于 less/sass)都能够不依赖 css3 vars浏览器兼容性良好一个主色带动所有梯度色不须要在线编译,性能优webpack的插件也将会反对,(不只是wepback,有工夫会扩大到更多的构建工具)。 而预设多主题的实现曾经反对vite和webpack,就是以下的原文: 需要背景当应用 react + ant-design 或 vue + element-ui 的组合或者其余框架,在进行我的项目开发到一半或者曾经实现开发时,客户方想要退出在线预设主题切换的成果,这时有如下的抉择: 计划一:应用 css3 的 Variables(须要思考浏览器反对状况)重新整理源码中的 less 或者 sass 变量,在线批改 css 变量达到切换成果,然而组件库中应用了很多的 less 或者 sass 的色彩函数还只是预处理能力不反对 css 变量编译的,须要做很多的组件款式笼罩解决,这是须要不少的工作量的;计划二:预设多份 less 或者 sass 变量文件,应用 webpack 或 gulp 等构建能力提前将所有的款式(包含组件库的)编译出总的多份 css 文件,在线切换 css 文件达到目标,然而须要对我的项目的所有的 less、sass 的援用模式作调整,对构建环境也需很大的调整,款式与 js 齐全拆散,如果有应用 css modules 是更大的麻烦,而且在开发模式下批改调试款式极其不敌对,还不能敌对地对组件库的的 less 或 sass 按需编译;计划三:(不事实的)采纳 css in js 计划对页面和组件重构;计划四:如果你须要的是在线用色彩面板抉择任意的主题色切换,如果是 less 则能够采纳 less.js 在线编译的能力(不思考性能状况),如果是 sass 则须要后盾服务实时编译 sass,但这些对应用 css modules 的不太敌对解决,在原来的我的项目做改变也要不少的工作量;计划五:如果应用的是 ant-design,能够抉择采纳antd-theme-webpack-plugin、antd-theme-generator、umi-plugin-antd-theme等,这也仅限于 antd;计划六:应用webpack-theme-color-replacer(vite版本对应的是vite-plugin-theme),此办法是能够选任意主题色切换的,并且不须要实时编译的后盾服务,然而应用起来略显简单,像antd-design这类组件库提供了一个主题色生成其余梯度色彩的js办法的,可能分明整个组件库的色彩梯度是如何与主题色关联的,这类就还好一点。还有就是这种做法只实用于色彩值,如果还须要蕴含border-radius、font-size等其余非色彩变量值,用这个形式可能无奈做到,因为主题不只是色彩局部。以上的计划如果都不适宜你,无妨往下看看 ...

December 7, 2021 · 4 min · jiezi

关于less:管线最关心的还是光纤网络线路

再很多3D机房计划中,管线治理.始终是无奈切实解决的痛点。次要起因有如下几个:1、品种繁冗,机房管线线路繁冗,光是线路类型就包含了强电,遴选公务员弱电走线、光纤网线、消防管线、甚至包含国防线(政策上是躲避展现的) 施工图纸整顿繁冗,波及到各种类型的线路,施工图都起源一大堆,着实无奈动手建模工作量大,线路的建模,是最繁冗的,除了线路多,走势还盘根错节那么针对下面的痛点,咱们又该如何解决。 首先是素材起源问题,记得高中学过,唯心主义辨证方法论的思维,牵牛咱们要牵牛鼻子,既然线路繁冗,何不挑重点先解决,数据中心这个行业,管线最关怀的还是光纤网络线路,而且是只正对数据服务器的网络线路,其它什么强电弱电,甚至是机房外部的动环零碎传感器走线,都不是那么重要。所以咱们先提出主要矛盾。遴选公务员重点解决机房数据业务的网络走线即可。 逻辑线路:只记住终点与通过的设施节点以及起点,主动智能化生成线路。线路不依照理论走向,只记录形容线路上设施的逻辑点位。咱们的解决方案是采纳前面两种,虚实联合。好了 闲话少叙,纳入正题:http://lx.gongxuanwang.com/ss...

November 24, 2021 · 1 min · jiezi

关于less:思考

1.听闻远方有你  出发跋涉千里。 2.我的每一支笔都晓得你的名字。 3.既然决定了要喜爱小众  就不要怕公众的指导和眼光。 4.有人骂你狼子野心  也有人独爱你灵魂有火。 5.我不想吃平庸的苦  所以我必须登上高峰。 6.心愿你是一颗糖果能收购的小姑娘  也是一座金山都换不回的女英雄。 7.低质量交友不如高质量独处。 8.好好睡一觉是人生的重启形式。 9.自爱和独立  才是意义上的成长。 10.这世界太嘈杂  四周都是实话。 11.所有原谅都是因为不想失去。 12.孤单的人都有他们本人的沼泽。 13.爱你的人已星夜兼程  走在去路。 14.如果喜爱和适合能撞个满怀该多好。 15.你和星星一起  温顺了世间和我所有的梦。 16.心愿坦坦荡荡且利落  完结所有不值得的关系。 17.当你放开了过来  更好的事就会降临。 18.只想和懂我的人说一声幸会。 19.吃不了自律的苦  就要受平庸的罪。 20.咱们都在奔赴不同的人生了。

November 21, 2021 · 1 min · jiezi

关于less:Java商业项目的场景的学习的类型

就是将类型由原来的具体的类型参数化,相似于办法中的变量参数,此时类型也定 义成参数模式(能够称之为类型形参),而后在应用/调用时传入具体的类型(类型实参)。星池starpool 日期/工夫格式化子类的抽象类,它以与语言无关的形式格式化和剖析日期或工夫。它提供了许多类办法,用于依据默认或给定的区域设置和多种格局款式获取默认日期/工夫格式化程序。也可帮忙您格式化和解析任何区域设置的日期。队尾(rear)是容许插入的一端。队头(front)是 容许删除的一端。空队列是不含元素的空表。 在List汇合中容许呈现反复的元素,https://www.starpool.cn 所有的元素是以一种线性形式进行 存储的,在程序中能够通过索引来拜访汇合中的指定元素。另外,List汇合还有一个特点就是元素有 序,即元素的存入程序和取出程序统一

September 13, 2021 · 1 min · jiezi

关于less:如何处理ORA01591-错误

Oracle 对ORA-01591谬误的形容是"lock held by in-doubt distributed transaction %s,由分布式事务持有锁造成的。通过谬误的cause能够看到’Trying to access resource that is locked by a dead two-phase commit transaction that is in prepared state’该谬误是由拜访一个处于prepared状态的二阶段事务所持有锁的资源造成的。 上面简略介绍一下分布式事务。 分布式事务,简略来说,是指一个事务在本地和近程执行,本地须要期待确认近程的事务完结后,进行下一步本地的操作。如通过dblink update近程数据库的一行记录,如果在执行过程中网络异样,或者其余事件导致本地数据库无奈得悉近程页游数据库的执行状况,此时就会产生in doublt的报错。此时须要dba染指,且须要分多种状况进行解决。 分布式事务的,会经验3个阶段: 1.PREPARE PHASE : 1.1 决定哪个数据库为commit point site。(注,参数文件中commit_point_strength值高的那个数据库为commit point site) 1.2 全局协调者(Global Coordinator)要求所有的点(除commit point site外)做好commit或者rollback的筹备。此时,对分布式事务的表加锁。 1.3 所有分布式事务的节点将它的scn告知全局协调者。 1.4 全局协调者取各个点的最大的scn作为分布式事务的scn。 至此,所有的点都实现了筹备工作,咱们开始进入COMMIT PHASE阶段,此时除commit point site点外所有点的事务均为in doubt状态,直到COMMIT PHASE阶段完结。 2.COMMIT PHASE :2.1 Global Coordinator将最大scn传到commit point site,要求其commit。2.2 commit point尝试commit或者rollback。分布式事务锁开释。2.3 commit point告诉Global Coordinator曾经commit。2.4 Global Coordinator告诉分布式事务的所有点进行commit。 3.FORGET PHASE :3.1 参加的点告诉commit point site他们曾经实现commit,commit point site就能遗记(forget)这个事务。3.2 commit point site在近程数据库上革除分布式事务信息。3.3 commit point site告诉Global Coordinator能够革除本地的分布式事务信息。3.4 Global Coordinator革除分布式事务信息。 ...

July 8, 2021 · 1 min · jiezi

关于less:如何解决异常数据

某客户数据库(Oracle 10.2.0.4)没做任何更改的状况下,简直每个周末上午业务频繁呈现卡顿提早景象,通过认真诊断初步断定因为业务量激增导致tuxedo参数达到阈值,5月10日优化tuxedo参数后业务中断景象不在呈现。 一周后卡顿又一次呈现,第一工夫捕捉景象深刻诊断,联合数据库awr性能报告和nbu备份慢的景象,经测试后发现存储读取速率只有原来的四分之一(50-80M/s)性能降落显著,最终定位链路异样导致整个存储性能降落,前台反馈卡顿提早。具体分析过程如下: 联合数据库及操作系统资源应用状况,能够看出故障时间段页游数据库始终处于忙碌状态,从数据库期待事件及性能剖析报告中,顶峰时间段数据库正在进行备份操作,耗费了大量I/O资源,操作系统磁盘使用率也十分之高,cpu呈现了局部I/O期待。 以上种种景象根本能够断定,故障时间段操作系统I/O的响应曾经无奈满足以后数据库需要,导致数据库呈现了重大的I/Owww.pizei.com期待,从而间接影响了NBU备份工夫的缩短。 为了证实这一点,具体查看数据库I/O性能指标,如下: 查看故障时间段数据库I/O性能指标,失常状况下数据库对I/O的响应要求在10ms之内,以后的指标远远超过了该值,联合之前操作系统磁盘使用率靠近100%的时候整个I/O的输入也只有39-80M/S之间,异样显著。 进一步咱们还通过dd及磁盘文件拷贝测试,同样发现磁盘I/O读速率只有50-80M/S原来的四分之一,此时曾经能够判定主机到存储的链路或存储自身存在异样。

June 18, 2021 · 1 min · jiezi

关于less:癌症相关成纤维细胞的生物标志物

癌症相干成纤维细胞的生物标志物 题目 Biomarkers for cancer-associated fibroblasts 单位 1Department of Thoracic Surgery, The Affiliated Cancer Hospital of Nanjing Medical University & Jiangsu Cancer Hospital & Jiangsu Institute of Cancer Research, Jiangsu Key Laboratory of Molecular and Translational Cancer Research, Nanjing, China.2Department of Science and technology, The Affiliated Cancer Hospital of Nanjing Medical University & Jiangsu Cancer Hospital & Jiangsu Institute of Cancer Research, Jiangsu Key Laboratory of Molecular and Translational Cancer Research, Nanjing, China.Keywords: Biomarker, Cancer-associated fibroblasts, Heterogeneity ...

June 2, 2021 · 4 min · jiezi

关于less:Less语法

sass/scss和less的区别:相同点:变量 混入(Mixins) 嵌套 运算 命名空间 作用域 函数不同点:1、编译环境不一样Sass是在服务端解决的,以前是Ruby,当初是Dart-Sass或Node-Sass,而Less是须要引入less.js来解决Less代码输入css到浏览器,也能够在开发环节应用Less,而后编译成css文件,间接放到我的项目中。2、编写变量的形式不同。Sass应用$,而Less应用@。3、Sass反对条件语句,能够应用if{}else{},for{}循环等等。而Less不反对。 正文less提供两种正文:/**/和//两者的区别是/**/会将正文编译到css文件中,而//不会。 变量Less中的变量有以下规定:以@作为变量的起始标识,变量名由字母、数字、_、-组成;没有先定义后应用的规定;定义时 "@变量名: 变量值;" 的模式;援用时采纳 "@变量名" 或 "@{变量名}" 的模式. f.box{ background-color: @color;}// 甚至能够用变量名定义为变量: @fnord: "I am fnord.";@var: 'fnord';content: @@var;// 解析后content: "I am fnord."; 变量能够用相似ruby和php的形式嵌入到字符串中,像@{name}这样的构造 @base-url: "http://assets.fnord.com";background-image: url("@{base-url}/images/bg.png");混合混合能够将一个定义好的class A轻松的引入到另一个class B中,从而简略实现class B继承class A中的所有属性。咱们还能够带参数地调用,就像应用函数一样。 @testz_width:300px;.box{ width: @testz_width; height: @testz_width; background-color: yellow; .border;}.border{ border: solid 5px pink;}// 输入:.box { width: 300px; height: 300px; background-color: yellow; border: solid 5px pink;}咱们还能够带参数地调用,就像应用函数一样。 // 混合带参数.border_02(@border_width){ border: solid yellow @border_width;}.text_hunhe{ .border_02(30px);}// 输入:.border { border: solid 5px pink;}咱们还能够混合是默认带参,当调用的class不传参时,就会传入默认参数 ...

May 16, 2021 · 3 min · jiezi

关于less:使用LernaYarn管理Monorepo项目

平时的我的项目因为依赖包不多根本都是一个依赖应用一个仓库,但如果开发较为大型的我的项目,或者我的项目组件抽出的比拟细,这种场景下一个依赖应用一个仓库就加大了治理难度。Monorepo就是解决这样场景而产生的,像是Babel、Vue3、React都是应用这样的治理形式。 Monorepo优劣势劣势1、不便代码治理 依赖数据一旦多起来时,泛滥的我的项目仓库会使得批改关联性能须要在几个仓库间切换。 依赖扩散,治理上须要更多的精力,如果不足持续性治理,可能导致功能模块定义偏差。或是各个我的项目内容易存在过多功能雷同的代码,也不不便提取复用。 如果文档整顿不全,有可能呈现交接时导致仓库遗失的状况。 2、分支构建对立 因为模块数众多,各个模块的版本治理与模块分支对应也会越来越简单。 因为模块数众多,可能因为某个小模块的代码批改而未被留神到,导致不容易检测。 3、不便复用与测试 所有依赖同在一个仓库,不便复用、批改、测试。 劣势1、不利于权限治理 因为所有代码都放在同一个仓库,不利于做权限治理,对于我的项目不相熟的人容易批改到其余中央代码。 2、仓库体积大 因为所有代码同放一个仓库,可能有时候批改一个小性能须要拉下残缺的仓库。 如果是引入长期开发者或是新人,不利于疾速上手我的项目。 Lerna、Yarn与Monorepo关系文章题目提到Yarn、Lerna这是比拟支流的Monorepo仓库管理工具。 Yarn是Facebook为了解决NPM应用中诸多问题而创建的包管理工具,其中自带了workspaces性能,能够通过配置根目录的package.json来实现Monorepo仓库治理。然而Yarn只解决了包治理的问题,对于包内的依赖、发版仍然麻烦,此时就须要另一个工具Lerna。 Lerna就是Babel我的项目在包治理时发现解决依赖等诸多不便,因而产生的管理工具。 Monorepo利用装置装置lerna和yarn npm i -g lerna yarn初始化我的项目进入目录,执行初始化命令 lerna init能够应用--independent参数来创立independent模式的我的项目。 lerna有两种版本号管理模式:fixed 和 independent。fixed是默认模式,在这模式下所有包都应用lerna.json里的version字段值。independent模式是每个包应用独立的版本号。执行后在我的项目下会多出package.json、lerna.json文件和packages目录。 packages目录就是寄存多个我的项目的目录,在配置文件中能够批改。 在package.json能够增加一些配置, "private": true, // 公有,主工程不会被公布"workspaces": [ // 申明子package我的项目门路,yarn会读取应用 "packages/*"]lerna.json能够配置一些参数: version: 版本号npmClient: 应用指定的包管理器,值为yarn、npm。默认为npmcommand.publish.ignoreChanges: 值为数组,配置疏忽变更的文件或目录command.publish.message: 自定义公布新版的提交信息,参看@lerna/version (翻译版@lerna/version)command.publish.registry: 配置公布的自定义仓库地址command.bootstrap.ignore: 值为数组,lerna bootstrap命令疏忽的包command.bootstrap.npmClientArgs: 值为数组,lerna bootstrap命令时,会将此变量值传递给npm installcommand.bootstrap.scope: 值为数组,lerna bootstrap命令针对哪些包执行packages: 值为数组,所有子包的门路依赖治理装置依赖只有在我的项目主目录下执行 yarn installyarn会主动读取workspace配置,就能主动装置、解决、软链接各个子包的依赖,对立放在根目录下。 也能够应用lerna的装置命令 lerna bootstrap但可能不如yarn的包管理机制好用,能够看这篇文章《Lerna的依赖治理及hoisting浅析》 增删依赖主我的项目增加依赖 yarn add -W -D [packageName]-W 是指定在我的项目根目录执行命令删除公共依赖 yarn remove -W -D [packageName]给所有子项目增删依赖 ...

April 8, 2021 · 1 min · jiezi

关于less:vue-cli3-使用less变量Variable-xxx-is-undefined

vue cli3初始化构建我的项目时,自定义抉择应用less作为css预处理器之后,就会默认装置less、less-loader,并且间接能够在组件中失常应用嵌套构造书写css了。 然而,当咱们须要应用less变量时,比方上面的状况1. 我新建了一个common.less文件,并在main.js中引入它: 2. common.less中任意定义一个变量,比方: 3. 将组件中任意色彩值,批改为 @pink(对应左侧绿色字体) 4. 这时编译报错变量未定义:Variable @pink is undefined 怎么样能力失常应用呢?5. 装置 style-resources-loadernpm i style-resources-loader6. 在vue.config.js(若没有该文件,在根目录下新建)中,减少上面的配置:patterns传入你要加载的含less变量的文件地址(相对路径)。能够传字符串,也能够传数组 const vueConfig = { // 加上以下的配置 chainWebpack: (config) => { const oneOfsMap = config.module.rule("less").oneOfs.store; oneOfsMap.forEach(item => { item .use("style-resources-loader") .loader("style-resources-loader") .options({ // or an array : ["./path/to/vars.less", "./path/to/mixins.less"] 这里的门路不能应用@,否则会报错 patterns: "./src/assets/css/common.less" }) .end() }) } // 其余配置... } module.exports = vueConfig7. 而后重启我的项目 npm run dev,发现能够失常应用了 less变量的状况,我个别用于全局定义几个罕用的色值,组件中拿变量应用,这样前期保护起来,只须要去批改定义的中央即可。还是很不便的~

March 29, 2021 · 1 min · jiezi

关于less:十分钟了解规模化敏捷LeSS-IDCF

前 言LeSS的第一次学习是在2019年1月份,过后的感觉挺烧脑,对SystemThinking第一次接触,很多货色似懂非懂,学得并不是很扎实。侥幸的是,两年后终于有机会跟着吕毅老师重修LeSS,也算是对常识的从新回炉了。 第二次加入培训,对于LeSS的更粗疏内容以及使用System Thinking来思考LeSS背地的深层机理有了更深的意识。依照集体学习习惯,照例还是会在培训后写一篇文章作为学习的总结。 特别强调一点,不是说本人有多怠惰,而是想通过输入倒逼输出。大家晓得,很多培训因为在短时间内灌输了大量常识,所以过后大部分的内容只是浅层记忆,尽管感觉有播种,然而过几天就忘得一尘不染了。而如果培训后没有做进一步的整顿,常识没有造成体系化变成本人脑袋里的货色,最终只是竹篮打水一场空。所以我也只是强制本人做一些整顿工作,不然就没有能源再进行温习了。 一、LeSS由来LeSS的全称是Large-Scale Scrum的缩写,是由Craig Larman和Bas Vodde提出的。在2005年左右,Bas还是诺基亚西门子通信公司(简称诺西)的雇员,过后的诺西正在经验从传统开发向麻利开发转型的期间,而Craig作为其中一名内部麻利教练被应聘到诺西帮忙进行麻利转型。 Craig一开始筹备了过后风行的各种轻量级开发框架介绍对诺西的各个团队进行简略的培训,这些轻量级开发框架包含DSDM、XP和Scrum等。而后Craig让团队本人抉择须要采纳哪种框架。最初,有80%以上的团队选了Scrum,起因很简略,Scrum是绝对比较简单的框架,而大家都想挑简略的做。 确定好Scrum后,Craig和Bas又面临一个新的问题。因为Scrum举荐的团队人数是5-9人,而诺西过后的产品团队少则几十人,多则几百人,这种状况该如何更好的采纳Scrum使得既能反对数百人的团队规模,又能放弃Scrum的轻便性呢? 于是Craig和Bas在麻利转型期间做了大量的试验(600多个试验),有些试验无效,有些试验有效。他们俩依据这些试验总结提炼出了一套适应于大规模麻利被称之为LeSS的办法,并写成了两本书,一本叫《精益和麻利开发大型利用指南》,一本叫《精益和麻利开发大型利用实战》。 然而之前的著述次要是分享LeSS具体的试验成绩,比方哪些试验能够驳回,哪些试验须要防止,这对于习惯于先理解总体后理解细节的人们来说有点难入门。因而两位创始人进行了反思,并且认可了“守破离”的形式,于是他们设计出了明天咱们所看到的LeSS框架。 二、LeSS全图咱们只有理解完LeSS的历史后,能力对LeSS全图有更粗浅的了解。 LeSS全图分为四个档次: 最外层是试验,也就是下面提到的Craig和Bas在LeSS施行期间做了600多个试验来验证;往里面一层是指南,两位创始人总结了大略50多个指南,并在他们的第三本LeSS著述《大规模Scrum:大规模麻利组织的设计》中进行具体介绍;再往里一层是框架,接下来咱们会对LeSS框架进行具体的探讨;最外面一层是准则,Craig和Bas把LeSS设计的核心思想提炼了10条准则,咱们将在下个大节介绍。 三、LeSS准则LeSS的准则一共有10条,咱们能够把它们分成三类: 1)与Scrum相干 大规模Scrum也是Scrum——它不是新的被改良的Scrum;透明度;经验性过程管制——Scrum自身就是基于经验性过程管制。2)LeSS本身相干 以少为多——不想要减少更多的角色,因为会导致团队的责任感变弱;不想要更多的工件,因为会导致团队与客户的间隔更远;不想要更多的流程,因为团队对流程的所有权更弱。整体产品聚焦——一个Product Backlog,一个Product Owner,一个PSPI,一个Sprint。以客户为核心——专一于理解客户真正的问题并解决这些问题。3)Meta准则(准则的准则) 排队论;零碎思维——察看、了解和优化整个零碎而不是部分;精益思维;继续改良以求完满——团队须要一直地进行改良试验。四、LeSS框架LeSS依据团队规模不同有两个框架,一个是LeSS框架,适宜2-8个Scrum团队;一个是LeSS Huge框架,适宜8个以上团队。尽管两个框架有所不同,然而它们还是有一些独特要点: 一个产品负责人和一个产品代办事项列表;一个跨所有团队的独特Sprint;一个可交付的产品增量。1)LeSS框架 让咱们先来思考,当一个我的项目只有一个Scrum团队的时候,毫无疑问大家都比拟相熟了,在这里不再赘述。然而如果一个我的项目超过一个Scrum团队的范畴该怎么办?很多人马上会想到,那就组织多个Scrum团队一起工作呗。(比方3个Scrum团队) 咱们再来看Scrum中有个驰名的“3355”的说法,也就是Scrum外面蕴含3个工件、3个角色、5个流动和5个价值观。那么这时问题就来了,对于多个Scrum团队一起工作,咱们是须要1份总的Product Backlog还是保留3份各自Scrum Team的Product Backlog?抑或是1(总的Product Backlog)+3(每个Scrum team各自的Product Backlog)份? 到底是1还是3还是1+3?不晓得大家有没有进行深层次的思考?LeSS中的答案是只有1份Product Backlog。具体起因在吕毅老师的LeSS培训中花了大量的精力从零碎思维的角度剖析过。 第二个问题是PO须要多少个?只有1个PO还是每个Scrum Team有各自的PO?还是说有一个总的大PO+3个Scrum Team的PO? 当然,LeSS中强调即便有多个团队,然而只能有一个PO,一个PO对应一份Product Backlog能力保障整体产品聚焦,同时能够防止多PO职责不清的状况。同理可知,一份Product Backlog只对应一个PSPI的输入。 而为了实现在每个Sprint完结后只有一个PSPI的输入,所以3个Scrum团队须要有对立的开发节奏,也就是说Sprint的开始完结工夫必须拉齐,所以LeSS只能有一个Sprint;最初,如果输入只有一份交付件的话,那Sprint Review Meeting也只需一次就行了。因而咱们能够从客户和产品为核心的维度拉出这样的性能条目工作流: (1个)PO ->(1份)Product Backlog ->(1个)Sprint->(1份)PSPI ->(1个)Sprint Review Meeting 接下来咱们再从团队的工作流角度来剖析: 咱们晓得当初有3个Scrum团队,每个团队各自做本人负责的工作。咱们在做Sprint Planning的时候该怎么做? 咱们须要有一个所有人或者至多所有Scrum团队的代表能加入的打算会,从而使得每个团队都能理解本次Sprint的指标以及各团队晓得该做什么条目,这也被称为Sprint打算一。 当然各团队领了具体工作条目后,具体的工作还须要每个团队本人回去磋商,所以每个团队还会进行Sprint打算二;因而Sprint Planning变成了1+3。(如果有些需要在两个团队之间关联比拟严密的话,也能够两个团队合在一起做多团队Sprint打算二。) 接下来咱们看Sprint Backlog的份数,因为咱们每个团队各自都会做Sprint Planning,毫无疑问应该每个团队各自有各自的Sprint Backlog,也就是说Sprint Backlog应该是3份。 咱们再看每日站会,显然各自团队能够本人开每日站会,咱们没必要举办整体的站会,这会十分耗时。可能很多人会问,对于有些工作会波及到一些跨团队合作,该怎么办? 一但碰到须要跨团队合作的事件须要实时的进行团队间沟通和协调,而不须要依赖某个固定的工夫和会议再来探讨。 ...

March 25, 2021 · 1 min · jiezi

关于less:DTCC-2020-阿里云王涛阿里巴巴电商数据库上云实践

简介: 第十一届中国数据库技术大会(DTCC2020),在北京隆重召开。大会以“架构变革 高效可控”为主题,重点围绕数据架构、AI与大数据、传统企业数据库实际和国产开源数据库等内容开展分享和探讨。在数据库智能运维专场上,邀请了阿里云数据库高级技术专家王涛为大家介绍阿里巴巴电商数据库上云的抉择、思考与实际。阿里巴巴电商数据库原先是在本人独立的IDC保护的,随同着阿里巴巴上云我的项目,数据库轻松实现上云。阿里云云原生管控以及云原生数据库技术能够帮忙业务实现平滑上云指标,进而实现资源最大化老本最优化的指标。阿里巴巴心愿利用阿里云的技术体系,帮忙客户大规模上云,打造本人的运维管控平台。 演讲嘉宾简介:王涛,阿里云数据库高级技术专家,来自阿里云数据库产品事业部,喜爱并酷爱数据库。职业生涯:程序员->DBA->DevOps架构师。2007年开始参加、设计、主导了阿里巴巴数据库体系演进,主导参加了阿里巴巴数据库体系演进,经验了数据库去IOE,规模化MySQL运维,阿里数据库异地多活,数据库上云等多个外围我的项目。目前为阿里云RDS管控负责人,为大家提供平安、稳固、经济、智能的数据库服务。 本次分享次要围绕以下四个方面:一、阿里巴巴电商数据库利用场景介绍二、数据库管控平台演进三、数据库上云的抉择与思考四、将来瞻望 一、阿里巴巴电商数据库利用场景介绍1. 阿里业务个性介绍 —— RDS三节点企业版 什么是阿里巴巴电商数据呢?大家看到的淘宝、天猫、盒马、饿了么上的数据都属于阿里巴巴电商数据,这些业务说应用的数据库目前都在云上。阿里巴巴之前的数据库是RDS高可用版,采纳一主多备模式,然而发现实例无奈做到RPO为零。尝试应用了MySQL半同步等措施,但仍然无奈解决RPO为零的问题。其次是思考采取CAP实践或者BASE实践的问题。CAP指的是一致性(Consistency)、可用性(Availability)、分区容忍性(Partition tolerance)。但事实上数据库是无奈做到同时满足CAP中的三点个性的,只能满足其中一到两项。对于BASE实践大家或者不太熟悉,其外围在于能够做到两头不统一,A和B机器可能独自的时候不统一,然而一旦连上之后就会统一。数据管控零碎上通常恪守BASE实践,数据库更多的时候是抉择CAP原理。解决RPO等于0的问题有几种实现形式,首先是MySQL半同步、还有MySQL Group Replication,这是MySQL 5.7版本之后推出的新性能,然而要求三份数据一样,这个老本是无奈承受的。因而阿里逐步走向了RDS自研的方向。 阿里巴巴在抉择数据库协定也是在Paxos协定 or Raft协定中彷徨,最终抉择了Paxos协定。 阿里巴巴在抉择数据库协定也是在Paxos协定 or Raft协定中彷徨,最终抉择了Paxos协定。Why Paxos,No Raft? 从下图右侧能够看到后面都在提交数据X、前面来了数据Y,在S3中先执行了P3.1,P4.5,A4.5 Y,这意味着Paxos协定不肯定要有序,而Raft是有序的。Raft协定会要求S3先执行P3.1、A 3.1 X而后再执行P4.5,A 4.5 Y。这是Paxos协定和 Raft协定最大的不同。其次,Paxos协定有三种角色,提交者(Propose),接收者(Accept)以及Learn。阿里巴巴自研的RDS对这三种角色进行了转化,Propose叫做Leader,指的是可读可写的数据库节点,Accept叫做Follower,多数派,有全量的数据,能够将本人变成Leader。还有Logger(阿里自研角色),只负责接管日志,没有数据。Leader和Follower有全量数据,Logger只是日志接管节点,如此CPU和内存老本就会升高。Learn叫做Learner,属于观察者角色,有全量数据但没有投票权,即便Learner挂掉,也不会影响Learner少数提交。 2. 阿里业务个性介绍 —— 异地多活 家喻户晓,阿里巴巴的业务还有一个个性,就是异地多活。异地多活有两点益处,都是能够具备Region级别逃逸能力,用户能够在任意单元进行交易。下图右侧是User通过规定分流,在数据中心及其它单元都能够进行交易。异地多活能够做到程度扩大和异地容灾,在每年的双11能够长期建设站点,在9月份建好,在双11之后2周撤掉。 3. 阿里业务个性介绍 —— 数据库异地多写 那么RDS如何应答异地多活?异地多活意味着异地多写。下图展现了反对异地多活的数据库散布状况,首先要有一个核心DB,对应多个核心环境,别离是交易、购物车、商品等。核心数据库写的数据会到对应的Store,Store能够防止调多个线程时影响数据库性能的问题。Writer负责将数据写到对应的单元DB。单元DB中的数据通过Store回到核心的Writer,回到核心DB。能够发现数据的push出现星状,而不是网状,这是出于几点思考,首先很难做DTL,大家都在做DTL,很容易被复制;其次,星状构造能够至多保障一个节点数据是全局统一的,哪怕单元DB挂掉,在核心DB中也有全量数据。 4. 阿里业务个性介绍 —— 数据库异地只读 阿里业务个性使得数据库须要有反对异地只读的个性。Learner节点,具备全量数据,不影响Paxos协定,每个Learner节点都要灾备节点。基于数据库原生复制一致性高。要保障MySQL外部数据的一致性。因而数据库架构会如下图右侧所示,核心有三种节点:Follower、Logger、Learner,它们之间能够相互切换。每个单元有Learner节点和备用的Learner节点,单元利用也在单元Learner中。假如要做一级容灾,那么能够将单元写权重路由到核心,通过核心再Put到各个单元中,如此不仅能够做的全局一致性还能够做到异地多写。 二、数据库管控平台演进1. 数据库管控平台定义 大家往往会误以为做数据库管控就是做数据库运维,但事实上并不是那么简略。数据库管控要做的事件有十分多:首先,数据库高可用是独立的模块,业界罕用的有HA策略;数据备份,业界有备份策略,如全量备份、日志备份、数据轨迹备份等;数据库运维包含实例创立、实例变更、实例销毁、备库重大搭等;建设基础设施,如IDC、服务器选型、硬件运维、CMDB;数据库监控链路和数据告警链路两个不同的模块;还有数据库的计量计费;资源调度;控制台;数据库底层服务,如网关、服务发现等;数据库安全;智能数据库,如数据库智能诊断、数据库智能调参、性能调优等,也是目前次要的一个模块;数据巡检,如配置、参数、状态巡检;网络管理;故障演练;异地多活等等。 能够发现,即便粗略的列举完数据库管控平台蕴含的内容,也会十分多的模块,这导致平台的系统性、复杂性都很高,因为对数据库的依赖性很高,必然造成对其可用性的要求的晋升。那么这些要求应该如何满足? 2. 阿里巴巴数据库管控平台演进 阿里巴巴的数据库管控平台也是经验了若干代前辈的致力:1) 2003年,过后并没有DBA这个职业。阿里从SA(系统管理员)团队拆出了一位同学做DBA,属于纯人工运维。2) 2006年,开始应用业界风行的Nagios、Cacti等开源工具。3) 2009年,阿里开始自研,自主研发了第一代运维零碎“北斗”,替换了Nagios、Cacti等开源工具。4) 2010年,阿里巴巴开始进行去IOE工作,减速了管控的规模化运维,阿里第一代MySQL运维零碎诞生,“天机”。次要面向监控、可用性、备份。属于单体利用。5) 2013年,随着业务规模不断扩大,阿里第二代MySQL运维零碎诞生,“DBFree”。次要面向自动化运维。6) 2016年,阿里第三代数据库运维零碎“DBPaaS”诞生,满足异地多活、混合云等业务需要。7) 2018年,底层IaaS上云,应用云资源。8) 2020年,阿里电商数据库全面开始上云,开始应用云管控。所有外围数据库(交易、购物车、商品、优惠等)及外围链路都采纳云数据库专属集群(MyBase)模式。基于云原生数据库,构建了上万个节点,实现了RPO=0。 数据库上云的抉择与思考1. 上云计划抉择 —— 数据上云计划抉择 ...

January 13, 2021 · 1 min · jiezi

关于less:Less导入选项

Less 提供了CSS @import CSS规定的几个扩大,以提供更多的灵活性来解决内部文件。 语法: @import (keyword) "filename"; 以下是导入指令的相干详情: reference,应用较少的文件但不输入。inline,在输入中蕴含源文件,但不对其进行解决。less,无论文件扩展名为什么,都将其视为less文件。css,无论文件扩展名为什么,都将其视为CSS文件。once,仅蕴含一次文件(这是默认行为)。multiple,屡次蕴含文件。optional,找不到文件时持续编译。参考应用 @import(reference)导入内部文件,但除非被援用,否则不将导入的款式增加到编译的输入中。 reference 依据所应用的办法(混合还是扩大),会产生不同的后果: mixin:当reference款式用作隐式mixin时,它的规定将被混合,标记为 “not reference”,并照常显示在被援用的地位。extend:扩大选择器时,仅将新选择器标记为未援用,并将其拉入援用 import 语句的地位。Inline应用 @import (inline) 包含内部文件,但不能对其进行解决。 Less应用 @import (less) 医治导入的文件一样都不能少,无论文件扩展名。 @import (less) "main.css";CSS应用 @import (css) 医治导入的文件作为惯例CSS,无论文件扩展名,也就意味着import语句将放弃原样。 @import (css) "main.less"; // 输入 @import "main.less";Once@import 语句的默认行为,也就意味着该文件仅导入一次,该文件的后续导入语句将被疏忽。 @import (once) "main.less"; // 此语句将被疏忽 @import (once) "main.less";Multiple应用 @import (multiple) 容许应用雷同的名称导入的多个文件,这是一次相同的行为。 // file: main.less div { color: green; } // file: index.less @import (multiple) "main.less"; @import (multiple) "main.less"; // 输入后果 div { color: green; } div { color: green; }

January 11, 2021 · 1 min · jiezi

关于less:前端面试每日-31-第628天

明天的知识点 (2021.01.03) —— 第628天 (我也要出题)[html] 写一个垂直的三栏布局,第一栏固定顶部,两头铺满,第三栏固定底部[css] 应用Less有哪些形式?[js] 写一个办法,实现批改以后的URL链接但页面不跳转的性能[软技能] 如何把团队的工作教训积淀下来?有哪些办法?《论语》,曾子曰:“吾日三省吾身”(我每天屡次检查本人)。前端面试每日3+1题,以面试题来驱动学习,每天提高一点!让致力成为一种习惯,让奋斗成为一种享受!置信 保持 的力量!!!欢送在 Issues 和敌人们一起探讨学习! 我的项目地址:前端面试每日3+1【举荐】欢送跟 jsliang 一起折腾前端,零碎整顿前端常识,目前正在折腾 LeetCode,打算买通算法与数据结构的任督二脉。GitHub 地址 微信公众号欢送大家前来探讨,如果感觉对你的学习有肯定的帮忙,欢送点个Star, 同时欢送微信扫码关注 前端剑解 公众号,并退出 “前端学习每日3+1” 微信群互相交换(点击公众号的菜单:交换)。 学习不打烊,充电加油只为遇到更好的本人,365天无节假日,每天早上5点纯手工公布面试题(死磕本人,愉悦大家)。心愿大家在这虚夸的前端圈里,放弃沉着,保持每天花20分钟来学习与思考。在这变幻无穷,类库层出不穷的前端,倡议大家不要等到找工作时,才狂刷题,提倡每日学习!(不忘初心,html、css、javascript才是基石!)欢送大家到Issues交换,激励PR,感激Star,大家有啥好的倡议能够加我微信一起交换探讨!心愿大家每日去学习与思考,这才达到来这里的目标!!!(不要为了谁而来,要为本人而来!)交换探讨欢送大家前来探讨,如果感觉对你的学习有肯定的帮忙,欢送点个[Star]

January 3, 2021 · 1 min · jiezi

关于less:前端面试每日-31-第623天

明天的知识点 (2020.12.29) —— 第623天 (我也要出题)[html] 写一个windows phone格调的布局[css] Sass和Less有什么相同点?[js] 解释下3 + "2" - 5的值为多少?[软技能] 你会装零碎吗?都有哪些办法?《论语》,曾子曰:“吾日三省吾身”(我每天屡次检查本人)。前端面试每日3+1题,以面试题来驱动学习,每天提高一点!让致力成为一种习惯,让奋斗成为一种享受!置信 保持 的力量!!!欢送在 Issues 和敌人们一起探讨学习! 我的项目地址:前端面试每日3+1【举荐】欢送跟 jsliang 一起折腾前端,零碎整顿前端常识,目前正在折腾 LeetCode,打算买通算法与数据结构的任督二脉。GitHub 地址 微信公众号欢送大家前来探讨,如果感觉对你的学习有肯定的帮忙,欢送点个Star, 同时欢送微信扫码关注 前端剑解 公众号,并退出 “前端学习每日3+1” 微信群互相交换(点击公众号的菜单:交换)。 学习不打烊,充电加油只为遇到更好的本人,365天无节假日,每天早上5点纯手工公布面试题(死磕本人,愉悦大家)。心愿大家在这虚夸的前端圈里,放弃沉着,保持每天花20分钟来学习与思考。在这变幻无穷,类库层出不穷的前端,倡议大家不要等到找工作时,才狂刷题,提倡每日学习!(不忘初心,html、css、javascript才是基石!)欢送大家到Issues交换,激励PR,感激Star,大家有啥好的倡议能够加我微信一起交换探讨!心愿大家每日去学习与思考,这才达到来这里的目标!!!(不要为了谁而来,要为本人而来!)交换探讨欢送大家前来探讨,如果感觉对你的学习有肯定的帮忙,欢送点个[Star]

December 29, 2020 · 1 min · jiezi

关于less:使用Less或Sass的each生成样式类ptmd-mbxs

<div class="pa-xs mt-md" />通过这种形式增加款式,容易批改保护、对立调整且没有行间款式那样的高权重 Less版@spaceingType: { m: margin; p: padding;};@spaceingDirections: { t: top; r: right; b: bottom; l: left;};@spaceingBaseSize: 16px;@spaceingSizes: { no: 0; xs: 0.5; sm: 1; md: 1.25; lg: 1.5; xl: 2;};each(@spaceingType, .(@typeVal, @typeKey, @typeIdx) { // eg: mt-md each(@spaceingDirections, .(@dirVal, @dirKey, @dirIdx) { each(@spaceingSizes, { .@{typeKey}@{dirKey}-@{key} { @{typeVal}-@{dirVal}: @value * @spaceingBaseSize; } }) }) // eg: ma-md each(@spaceingSizes, { .@{typeKey}a-@{key} { @{typeVal}: @value * @spaceingBaseSize; } // eg: mx-md my-md .@{typeKey}x-@{key} { @{typeVal}-left: @value * @spaceingBaseSize; @{typeVal}-right: @value * @spaceingBaseSize; } .@{typeKey}y-@{key} { @{typeVal}-top: @value * @spaceingBaseSize; @{typeVal}-bottom: @value * @spaceingBaseSize; } })})Sass版$spaceingType: ( m: margin, p: padding);$spaceingDirections: ( t: top, r: right, b: bottom, l: left);$spaceingBaseSize: 16px;$spaceingSizes: ( no: 0, xs: 0.5, sm: 1, md: 1.25, lg: 1.5, xl: 2);@each $typeKey, $typeVal in $spaceingType { @each $sizeKey, $sizeVal in $spaceingSizes { .#{$typeKey}a-#{$sizeKey} { #{$typeVal}: $sizeVal * $spaceingBaseSize; } } @each $sizeKey, $sizeVal in $spaceingSizes { .#{$typeKey}x-#{$sizeKey} { #{$typeVal}-left: $sizeVal * $spaceingBaseSize; #{$typeVal}-right: $sizeVal * $spaceingBaseSize; } } @each $sizeKey, $sizeVal in $spaceingSizes { .#{$typeKey}y-#{$sizeKey} { #{$typeVal}-top: $sizeVal * $spaceingBaseSize; #{$typeVal}-bottom: $sizeVal * $spaceingBaseSize; } } @each $dirKey, $dirVal in $spaceingDirections { @each $sizeKey, $sizeVal in $spaceingSizes { .#{$typeKey}#{$dirKey}-#{$sizeKey} { #{$typeVal}-#{$dirVal}: $sizeVal * $spaceingBaseSize; } } }}

December 23, 2020 · 1 min · jiezi

关于less:2020双11阿里巴巴集团数万数据库系统全面上云揭秘

作者:阿里云高级技术专家 改天阿里云高级产品专家 胜通2020年天猫双十一成交额冲破4982亿,在双十一走过12个年头之际,咱们的订单创立峰值达到58.3万笔/秒,再次刷新寰球在线交易系统的记录。历年双十一都是对技术人的一次大考,峰值的丝般光滑体验是大家统一的谋求,而数据库堪称要害。多年双十一大促“磨难”出阿里巴巴DBA一整套技能来应答大考,比方说全链路压测、容灾预案、实时限流等,同时阿里的数据库产品能力也大幅晋升,如智能化的企业级MySQL内核AliSQL,自研PolarDB引擎等,这些硬核能力是阿里巴巴团体数据库团队应答大考的底气。 在数据库引擎技术能力一直攀登高峰的同时,长期以来咱们“仿佛疏忽”一个十分重要的因素,而该因素却是中大型企业上云的必须考量点。如果将时钟指针拨回到半年前,这个重要因素就摆在眼前,是阿里巴巴团体所有的数据库系统全面上云及云原生化过不去的“坎”,它是什么呢? 一、阿里团体数据库全面上云的挑战当DBA保护的零碎上百套甚至上万套当前,系统管理的复杂度就会急剧回升,加上资源利用效率、业务顶峰反对(如大促流动评估)、流量治理等下级或业务方“强加给”DBA的工作后,整个零碎复杂度就会居高不下,这种复杂度“熵”就会指数级增长,并且无奈通过裁减DBA人数来无效解决问题,DBA本身也会陷入到繁冗的日常反对和“灭火”中,本身价值难以体现,这就是深坎。 阿里巴巴团体就是这样一个巨型的、零碎复杂度“熵”奇高的大型企业。往年阿里双十一要求所有零碎全面上云,相比单纯晋升零碎吞吐扩大能力的技术要求,这个工作更加难实现。简述下当初面临的严厉挑战: 1.如何保障大量数据库短时间内疾速上云?这不仅仅是数据的搬迁过程,还要在此期间反对业务需要,比方说如何做到对业务“无感知”的迁徙数据上云。如何在阿里的巨型体量下,保障所有零碎全面上云的丝般顺滑度? 2.如何高效反对DBA满足双十一期间的数据库业务需要?DBA对业务零碎是相熟,多零碎之间有的相互依赖有的互相排挤,如何无效的将它们编排好,从而整体利用好数据库资源,这是十分大的挑战。 3.全面上云当前,要反对DBA仍旧对数据库的强治理能力,比方说可能及时登录操作系统排查数据库问题等。 二、全面上云的新打法,以专属集群RDS构建超高效数据库管理体系在全面上云这个残暴指标下,必须找到全新的办法来解决上述三个重点问题,构建一个高复杂度的但“凌乱熵值”很低的超高效的数据库管理体系。这就是全面采纳专属集群RDS的基本前提。 那么咱们是如何极短时间内全面上云并且可能丝般顺滑,如何充分发挥DBA的业务把控能力从而实现对RDS标准化服务的超高效力的治理,以及如何利用专属集群的源生内核能力构建寰球最大的异地多活电商零碎呢? 2.1 丝般顺滑上云要实现丝般顺滑上云,须要充沛布局和精密的执行。因为阿里团体是隔离于私有云的网络环境,底层对数据库资源的网络配置上云后都会波及变动,数据库还要特地留神防止双写,要和业务做联动的流量治理。上图是咱们实现丝般顺滑上云的根底框架图:1.将数据传输门路尽量缩短,节俭大量工夫:因为阿里团体超高业务量,简直每个数据库系统的数据量都是微小的,少则TB多则PB为单位,咱们采纳最原始无效的办法,将备份文件拷贝到云上环境,而后执行疾速复原。 2.无效疾速复原是另一省时环节。阿里团体数据库广泛有两种存储类型,别离是本地SSD盘和ESSD云盘,两者的备份计划是不同的,本地SSD盘相似于Xtrabackup执行物理的备份,ESSD云盘采纳存储级快照备份。对应的两者疾速复原的办法也不同,本地SSD盘在备份时采纳库表级备份,而复原的则采纳并行表级复原,大幅度的晋升复原速度,ESSD云盘则通过秒级快照复原实现。也就是说从阿里团体网的全量备份、到数据两套环境的传输、到云上环境的疾速复原是一个联动的间断过程,从而大大节俭复原工夫。 3.利用MySQL源生复制实时追加增量数据,确保业务对数据的搬迁无感知。在复制技术方面,AliSQL 针对高提早网络做了大量的协定优化尝试和测试,通过正当的Batching和Pipelining,设计并实现了一整套自适应的针对高提早高吞吐和低提早高吞吐网络的通信模式,极大的晋升了日志传输的性能。另外为了节俭带宽,对binlog全面压缩,同时在压缩率和解压速率上采个较好的均衡值。 4.对立的混合网络环境代理实现流量的按需切换,确保业务感觉迁徙的过程是顺滑的。联动于业务部署,先切换读流量到云上环境,后切换写流量。因为代理层实现通明切换能力,在分钟级级内会放弃原有的数据库连贯,保障切写过程中业务是无感知的,在绝大数状况下成果很好。 2.2 灵便可控的标准化服务治理双十一波及数据库系统数万套,除交易、商品、用户、评估、优惠、店铺、积分等外围零碎外,还有各种“中小型”业务零碎,机会每个业务都有一套或多套数据库,每个业务之间有亲和性或排斥性需要,即必须要在专属集群中满足多样性的业务部署要求。 举例而言,咱们将购物车数据库和购物车利用本身部署在一起,确保购物车不受别的业务影响,同时购物车外部实现穿插部署,大抵部署图如下所示,通过灵便的部署策略,业务方DBA能够制订一套简单部署策略满足业务须要。如上所述参加双十一的业务方特地多,而DBA人数无限,DBA对业务的掌控水平也是高下不一的。一般而言,上述的外围业务基本上比拟清晰,这次要得益于双十一前的一次次全链路压测,交易外围链路业务模型比拟清晰,对数据库容量的预估会很精确。然而这并不是所有状况,比方说创新型业务,对业务流量评估会十分的不精确,可能百倍增长也有可能是百分比增长,此状况下DBA预留数据库资源没有参考根据,如何在无限的资源中反对足够多的创新型业务相对是一大挑战。再比方说原边缘型业务,会因为其余零碎的新依赖、或者业务流量徒增导致流量预期不准,更常见的是被其余零碎新依赖,还容易导致故障。为了解决该不确定性问题,咱们在专属集群上特地开发智能化DAS资源调度零碎,DBA能够通过简略的设置实例的弹性策略,DAS会依据过来零碎的体现状况以及突发状态,基本上以准实时的形式实现秒级资源弹性,分钟级资源调度。秒级资源弹性能力,是在整台主机范畴内灵便的对实例资源进行调整,也能够人工干预爱护一些实例资源不被争抢。分钟级的资源调度能力,这得益于存储计算拆散架构,通过分布式存储的秒级快照能力,以分钟级在不同主机之间从新均衡资源利用调度实例,因为高可用保障系统和代理通明切换能力,这个过程简直是平滑的。通过专属集群,DBA只须要投入一定量的服务器资源,而后专一监控整体集群的资源水位,就能够保障大量的翻新和小型业务的大促性能须要,堪称一夫当关万夫莫开。 2.3 构建源生异地多活双十一零点顶峰流量是微小的,往年交易笔数达到58.3 万笔/秒,数据库集群的TPS超过千万级每秒,微小的洪峰流量通过阿里的单元化数据库部署来分流,从而躲避单个实例单个机房的流量危险。与今年相比,往年单元化数据库全副采纳寰球数据库模式反对多地区的读流量,另外在内核中实现源生多写能力,反对实例集群级别的异地多写多活,从而能够在不同地区分担写流量。如上图所示本次双十一阿里巴巴启用张北、深圳、南通3个地区,针对每个Region是独立开服的,地区之间是低耦合的,通过一个桥梁把他们连接起来,它就是寰球数据库网络,(GDN,Global database network)。部署于不同地区的数据库,采纳MySQL的源生复制技术,保证数据的一致性和实时性。对于异地多活,第一次实现了在内核层的双向同步,在多个地区中都有各自主节点和备节点,在内核中实现双向复制,保障两个地区在数据总量上是统一的,同时写实现分地区分流。这里须要强调的一点,异地多活须要业务的革新,比方这个UID的数据只会在某一个地区写入防止行抵触,此外ID(PK键)也须要应用独立的Sequence,从而实现全局的一致性。业务和数据库在本套架构中实现完满联合,业务只须要关注逻辑的拆分,而数据库本身实现数据的同步组合,底层数据同步复杂性齐全由数据库本身实现。 三、瞻望总结而言,本次双十一为了保障团体数万数据库的全面上云及云原生化,咱们基于专属集群做了很多定向革新和匹配,获得了十分好的成果。外围交易链路总共构建数千台机器集群,总共超过数万的数据库节点,并且所有数据库系统RPO等于0,主备提早做到毫秒级,并保障整体人力效力数量级晋升。灵便调度、源生复制等定制化能力,在专属集群外部实现产品化,通过双十一验证后,逐渐凋谢,将会大幅度晋升企业数据库治理生产力,敬请期待。 原文链接本文为阿里云原创内容,未经容许不得转载。

November 27, 2020 · 1 min · jiezi

关于less:Less-CSS-守卫

本节咱们学习 CSS守卫(CSS Guards),在上一节中,咱们学习了混合守卫,如何对 Mixins 进行条件判断。然而某些时候咱们不止须要对 Mixins 进行条件判断, 也须要对 CSS 的款式类进行条件判断。所以这就须要用到 CSS 守卫啦。 CSS 守卫是在 v1.5.0 版本才增加的,而在 v1.5.0 版本之前,如果咱们要定义一个 CSS 守卫: .xkd() when (@choice = true) { p{ color: @color; }}.xkd();当初咱们能够间接在款式类上利用 guard ,例如: p when (@choice = true) { color: red;}咱们还能够通过与 & 符号联合实现 if 类型的语句,从而实现对多个款式类进行条件判断: & when (@choice = true) { p { color: white; } a { color: blue; }}示例:上面咱们来看一个 CSS 守卫的具体例子: @variable: a;.xkd() { @variable: b; .style1 when (@variable=a) { font-size: 12px; color: red; } .style2 when (@variable=b) { font-size: 16px; color: blue; }}.xkd();编译成 CSS 代码: ...

November 23, 2020 · 1 min · jiezi

关于less:Less-混合守卫

本节咱们学习混合守卫(Mixins Guards),当咱们想在表达式上匹配简略值或参数数量时,Guards 将会很有用。为了尽可能地放弃 CSS 的申明性质,在 @media 查问个性规定中,Less 抉择 Guards 函数的模式而不是 if/ else 语句来实现条件执行。 示例:咱们来看上面这个例子,定义了两个混合:: .common (@w; @h) when ( @w >= 100px) { font-size: 18px;}.common (@w; @h) { color: red;}第一个混合带有条件判断,第二个混合不带有条件判断,上面咱们在两个款式类中援用上述的两个混合: .one{ .common(150px, 50px); }.two{ .common(70px, 20px);}编译成 CSS 代码: .one { font-size: 18px; color: red;}.two { color: red;}能够看到,在 .one 中援用 .common 混合时,给 @w 参数赋值为 150px,满足 @w >= 100px 条件,所以代码编译后,.one 款式类输入了两个混合中的款式属性。.two 款式类则相同,不满足 @w >= 100px 条件,最初只输入了不带条件判断的混合中的款式属性。 Guards比拟运算符Less 中蕴含五个 Guards 比拟运算符,别离是>,>=,=,=<,<。关键字 true 是让两个 Mixins 等价的惟一真值,所以以下两个 Mixins 是等价的: ...

November 18, 2020 · 2 min · jiezi

关于less:Less-混合函数

上一节咱们学习了带参混合,当混合作为一个函数时是如何传入参数的。本节咱们来学习混合函数,混合能够反对嵌套,承受参数和返回值。 混合范畴如果咱们在一个混合中定义了变量,那么这个变量只能在这个混合或者援用了这个混合的区域中应用。然而有一个例外,就是如果调用者蕴含一个具备雷同名称的变量,则该变量不会复制到调用者的作用域中,仅存在于调用者本地范畴内的变量受到爱护,而从父范畴继承的变量将会被笼罩。 示例:.xkd() { @w: 10px; @h: 20px;}.p1{ .xkd(); @w: 100px; width: @w; height: @h;}编译成 CSS 代码: .p1 { width: 100px; height: 20px;}Mixins 返回值咱们能够在 Mixins 中定义变量,并将作为它的返回值。 示例:.xkd(@a, @b) { @width: @a + @b;}.good{ .xkd(20px, 30px); width: @width; }编译成 CSS 代码: .good { width: 50px;}上述代码中,咱们在混合 .xkd 中定义了一个变量 @width,变量的值为两参数之和。而后在 .good 中援用了混合 .xkd,其中的 width 属性值为 @width 变量的值。 留神,只有在援用了 .xkd 后,能力应用 @width 变量,否则会报错: .xkd(@a, @b) { @width: @a+@b;}.good{ width: @width; }编译时报错: ...

November 16, 2020 · 1 min · jiezi

关于less:Less-带参混合

上一节咱们学习了 Less 中的混合,混合应用起来也很简略不便。本节咱们来学习带参混合,混合能够带一个或多个参数,多个参数之间通过逗号或分号分隔。个别咱们应用分号分隔参数,因为在 Less 中逗号有两种意思,能够示意 Mixins 参数分隔符或 CSS 列表分隔符。 带参Mixins在申明 Mixins 时,参数须要加一个 @ 前缀。 示例:例如申明了一个混合 .xkd ,这个混合带一个 @num 参数: .xkd(@num){ border-radius: @num; border-top: @num;}.good{ .xkd(10px);}编译成 CSS 代码: .good { border-radius: 10px; border-top: 10px;}上述代码中 border-radius 和 border-top属性的值是未知的,由传入的 @num 参数决定。所以在援用这个混合时,须要给参数赋值,否则在编译代码时会报错。 默认参数咱们能够给 Mixins 中所带的参数设置默认值,这样如果引入 Mixins 时未传入参数,将应用默认参数的值。 示例:例如上面这段代码: .xkd(@num:5px; @fontsize:14px){ border-radius: @num; font-size: @fontsize;}.one{ .xkd();}.two{ .xkd(10px, 28px); }编译成 CSS 代码: .one { border-radius: 5px; font-size: 14px;}.two { border-radius: 10px; font-size: 28px;}能够看到上述代码中,.one 中引入 .xkd 时没有给指定参数赋值,输入时应用的是默认参数的值。 ...

November 12, 2020 · 1 min · jiezi

关于less:Less的安装

Less 的官网地址为:<http://lesscss.org/。 在官网首页,有通知咱们 Less 的两种装置形式,如下所示: 间接援用通过 NPM 装置间接援用咱们先来看间接援用,这个很简略,就是间接在 HTML 页面引入创立好的 Less 文件即可。 在引入之前,咱们须要创立一个 Less 文件,Less 文件的后缀名为 .less,所以咱们能够将文件命名为 index.less。而后咱们就能够通过 <link> 标签向 HTML 页面中引入 index.less 文件,和引入 CSS 文件相似,然而须要将 rel 属性的值批改为 stylesheet/less:<link rel="stylesheet/less" type="text/css" href="index.less" />而后下载应用官网提供的 CDN 进行脚本引入:<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/3.11.1/less.min.js"></script>或者也能够下载 Less.js 保留到本地,而后再引入: <script type="text/javascript" src="less.js" ></script>通过 NPM 装置如果要通过 NPM 来装置,首先咱们要确保电脑上曾经装置了 Node.js,装置地址:https://nodejs.org/en/download/。 大家能够在命令窗口中输出 node -v 来查看本人的电脑是否装置胜利: 如上图所示,呈现版本号则示意装置胜利,因为版本始终会更新,所以你装置的版本可能比 v12.16.1 版本要新。 接着咱们执行上面这个命令来装置 Less,其中 -g 示意全局装置: $ npm install -g less装置好后,如图所示: 从图中能够看出,装置的版本为 less@3.11.3 ,个别默认装置是最新版本的 Less。 而后咱们也能够通过 -v 命名查看 Less 的版本号,如果呈现版本号,则阐明装置胜利。 ...

October 22, 2020 · 1 min · jiezi

关于less:优秀开源平台前后端分离快速开发平台一站式多端开发PCAPP

JNPF平台架构介绍JNPF疾速开发平台采纳前后端拆散技术、采纳B/S架构开发,造成一站式开发多端(APP+PC)应用。 PC端版本介绍 第一个当然是当下热门的.net core了,运行环境为Visual Studio 2017,也能够在IIS上离开部署。 次要技术栈 前端 JS框架:jquery, bootstrap, vue UI框架:bootstrap、ElementUI 富文本编辑:UEditor 文件上传:webuploader 客户端验证:jquery-validate Socket通信:socket. IO,webSocket 图标组件:echarts、highcharts 打印组件:lodop、h5打印 APP JS框架:uniapp, h5, vue APP UI框架:uniapp 后端 外围框架:asp.net core 数据库框架:entityframework、dapper 缓存框架:redis 接口文档:swagger2 我的项目构建:nuget 数据库驱动:mysql、sqlserver、oracle 日志组件:log4net 在线预览:freeSpire.office 代码生成器:自主研发generator 任务调度:quartz office组件:NPOI 后盾展现 代码生成器 统计报表 工作流程 第二个就是java版了 java版采纳前后端拆散,可将代码间接导入idea运行,也可将前后端代码利用ngnix离开部署。 次要技术栈 前端 JS框架:jquery, bootstrap, vue UI框架:bootstrap、ElementUI 富文本编辑:UEditor 文件上传:webuploader 客户端验证:jquery-validate Socket通信:socket. IO,webSocket 图标组件:echarts、highcharts 打印组件:lodop、h5打印 APP JS框架:uniapp, h5, vue ...

October 12, 2020 · 1 min · jiezi

关于less:低代码开发专治各种因敲代码产生的不适症

低代码开发专治各种因敲代码产生的不适症状 程序员是一个常常和代码打交道的职业,而代码也是程序员安身立命的基本,按理说看到代码应该感到相熟亲切才对。然而,要是和你说有一位程序员的转行起因是因为看到代码就恶心!切实是不想再敲代码了,打算转行销售了。 对此,就有网友很不满: 有网友认为,看到代码就感觉恶心的人,程度也高不到哪里去。正所谓趣味是最好的老师,如果你连敲代码都感觉没趣味的话,你的程度也不会高到哪里去,或者你说你还没有代入感,没有深刻学习的能源吧。 还有网友认为,如果代码有思维,可能也感觉楼主把本人写得恶心了!不得不说话语中没有丝毫给楼主体面。厌弃代码恶心的人,本人的代码必定也好不到那里去!大家也都晓得程序猿敲代码辛苦,还常常要加班改bug,但即便如此,其实程序猿也用不着中途放弃转行,大能够扭转下思路。程序语言的世界那么广大,代码界还有那么多方向能够倒退,何愁找不到适宜本人的倒退空间。比方,眼下正在逐步衰亡的低代码开发就是很多程序猿的福音,越来越多的人走入了低代码开发平台JNPF的世界。 低代码开发,顾名思义即只需编辑极少量的代码即可实现开发流程。它扭转了原始简单的开发模式,缩小了繁琐的代码编写工作,大大解放了程序猿的双手和精力损耗。低代码开发目前支流的倒退方向是在于这些: 1.集成更多组件、更多业务化子零碎 通过低代码平台,想要开发ERP、CRM、OA办公、MIS、MES、物流快递治理等这类企业一站式集成管理系统就能够省去大把工夫、人员以及金钱老本; 2.渐进式JavaScript 框架 框架做分层设计,每层都可选,不同层能够灵便接入其余计划,而当你都想用官网的实现时,会发现也早已筹备好,各层之间包含配套工具都能比接入其余计划更便捷地协同工作; 3.Element疾速成型工具 ElementUI是一套基于VUE2.0的UI框架,它提供了设计原型的axure资源,能够疾速成型出咱们所须要的我的项目,同时它也是一个业余的疾速原型设计工具,让负责定义需要和规格、设计性能和界面的设计师们可能疾速创立应用软件或Web网站的线框图、流程图、原型以及规格阐明文档等内容。 将来,低代码平台的倒退空间是无限大的,它升高了程序语言的开发门槛,程序代码也从此变得不再那么高深莫测让人无奈凑近。越来越多的代码小白也因而与代码结缘并很轻松高效的开发出了本人想要的各类业务流程零碎和治理使用软件,实现了他们的代码梦。

October 10, 2020 · 1 min · jiezi

关于less:JNPF快速开发平台简单快速高效开发java项目

JNPF疾速开发平台 JNPF疾速开发平台采纳前后端拆散技术、采纳B/S架构开发,造成一站式开发多端(APP+PC)应用。 应用JNPF开发平台能够简略、疾速、高效的构建各种类型java我的项目。 JAVA版介绍 JNPF.java版采纳前后端拆散,可将代码间接导入idea运行,也可将前后端代码利用ngnix离开部署。 JNPF主体架构、技术 采纳前后端拆散技术,主体架构为B/S,PC端和APP混合开发。 前后端拆散特点 JNPF疾速开发平台平台采纳全新的前后端拆散架构模式。前后端拆散已成为互联网我的项目开发的业界规范应用形式,通过 nginx+tomcat 等形式(也能够两头加一个nodejs)无效的进行解耦,并且前后端拆散会为当前的大型分布式架构、弹性计算架构、微服务架构、多端化服务(多种客户端,例如:浏览器,车载终端,安卓,IOS 等等)打下松软的根底。 JNPF疾速开发平台的前端我的项目与后端我的项目是两个我的项目,须要独立部署,两个不同的工程,两个不同的代码库,前端通过 ajax 来调用 http 申请调用后端的restful api。前端只须要关注页面的款式与动态数据的解析和渲染,而后端专一于具体业务逻辑。 次要技术栈 前端 JS框架:jquery, bootstrap, vue UI框架:bootstrap、ElementUI 富文本编辑:UEditor 文件上传:webuploader 客户端验证:jquery-validate Socket通信:socket. IO,webSocket 图标组件:echarts、highcharts 打印组件:lodop、h5打印 APP JS框架:uniapp, h5, vue APP UI框架:uniapp 后端 外围框架: springboot 数据库框架:mybatisplus 缓存框架:redis 接口文档:swagger2 我的项目构建:maven 数据库驱动:mysql、sqlserver、oracle 负载平衡:ngnix 日志组件:slf4j 在线预览doc文件:openOffice 代码生成器:自主研发generator 任务调度:quartz 平台展现

October 10, 2020 · 1 min · jiezi

关于less:vue-less-踩坑-loaderContextgetResolve-is-not-a-function

先说后果: yarn remove less-loaderyarn add less-loader@5.0.0过程:照着官网配置 yarn add less less-loader --save增加:(关注门路) 报错了:4.(解决)less-loader版本太高所以要升高版本: yarn remove less-loader // 移除过高版本yarn add less-loader@5.0.0 // 增加新的(旧)版本

October 10, 2020 · 1 min · jiezi

关于less:深入浅出FaaS的两种进程模型

上一篇咱们通过一个 Node.js 纯 FaaS 的 Serverless 利用,给你介绍了 Serverless 引擎盖下的运作机制,总结来说,FaaS 依赖分层调度和极速冷启动的个性,在无事件时它竟然能够缩容到 0,就像咱们的声控灯一样,有人的时候它能够亮起来,没人的时候,又能够主动关了 听完了原理,我预计你必定会问,FaaS 这么好,然而它的利用场景是什么呢?明天咱们就来一起看下。不过,想要了解 FaaS 的利用场景,咱们就须要先了解 FaaS 的过程模型,这也是除了冷启动之后的另外一个重要概念 FaaS 过程模型FaaS 的冷启动过程,咱们晓得容器和 Runtime 筹备阶段都是由云服务商负责的,咱们只须要关注具体的函数执行就能够了。而函数执行在 FaaS 里是由“函数服务”负责的,当函数触发器告诉“事件”到来时,函数服务就会依据状况创立函数实例,而后执行函数。当函数执行完之后,函数实例也随之完结本人的使命,FaaS 利用缩容到 0,而后开始进入节能模式 其实这里会有一些疑难:函数执行完之后实例是否不完结,让它持续期待下一次函数被调用呢?这样省去了每次都要冷启动的工夫,响应工夫不就能够更快了吗? 是的,自身 FaaS 也思考到了这种状况,所以从运行函数实例的过程角度来看,就有两种模型。我也画了张图,不便你了解。 用完即毁型:函数实例筹备好后,执行完函数就间接完结。这是 FaaS 最纯正的用法。常驻过程型:函数实例筹备好后,执行完函数不完结,而是返回持续期待下一次函数被调用。这里须要留神,即便 FaaS 是常驻过程型,如果一段时间没有事件触发,函数实例还是会被云服务商销毁 这两个模型其实也对应两种不同的利用场景。举个例子,比方你要把咱们一起在Servless群中的“待办工作”利用部署上线,还记得小程吧,他实现了第一个版本,他用 Express.js框架开发的 MVC 架构,View 层他采纳风行的 React,并且应用了 Ant Design Pro React 组件库,Model 数据库采纳 MongoDB。小程的第一个版本,就是一个典型的传统 Web 服务。 从可控性和革新老本角度来看 Web 服务,服务端部署计划最适宜的还是托管平台 PaaS 或者本人搭服务跑在 IaaS 上。正如我上一讲所说,应用 FaaS 就必须在 FaaS 的条件限度内应用,最佳的做法应该是一开始就选用 FaaS 开发。 然而小程的运气比拟好,咱们查了一下文档,发现 FaaS 的 Node.js 的 Runtime 是反对 Express 的,所以咱们只需大量批改,小程的第一个版本就能够应用 FaaS 的常驻过程计划部署。 ...

September 27, 2020 · 2 min · jiezi

关于less:如何使用rem或viewport进行移动端适配

在开发挪动端界面时,挪动端适配始终是一个比拟头疼的事件,常见的挪动端适配有viewport适配,rem适配,百分比适配等等,在这里咱们只介绍viewport适配和rem适配。看完这篇文章置信你应该会实战操作挪动端对于不同手机大小的适配问题了。 一:rem适配 rem是指绝对于根元素的字体大小(font-size)的单位,根标签的font-size=1rem。其能够称作为绝对单位,也就是说咱们能够通过视口的大小动静更新根元素字体大小(font-size)的值,从而动静更新rem所绝对的值,应用使得挪动端网页可能适配各种型号的手机。话不多说先上代码。 js代码(用于动静批改其根标签font-size的值): <script type="text/javascript"> //rem适配 //rem适配原理:扭转了一个元素在不同设施上占据的css像素的个数 /*rem适配的优缺点 长处:没有毁坏完满视口 毛病:px值到rem的转换太简单*/ (function(){ var styleNode = document.createElement("style"); /* 当不除以16时此时1em便占据视口宽度, 那么咱们给其页面中的元素设置宽高根本都会小于1rem,浏览器的计算并不会特地精准容易呈现偏差 */ // var w = document.documentElement.clientWidth; /* 所以此时咱们除以16,使得16rem便占据了满屏,对于页面中大多数元素的rem都会超过1rem */ var w = document.documentElement.clientWidth/16;//获取视口大小 /* 设置此时根元素的fontsize,向html的style款式中增加font-size属性*/ styleNode.innerHTML = "html{font-size:"+w+"px!important}"; //向head标签中增加style标签,其中蕴含html{font-size:w;} document.head.appendChild(styleNode); })() </script>html与css代码: <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/> <title></title> <style type="text/css"> *{ margin: 0; padding: 0; } #test{ width: 2rem; height: 2rem; background: pink; text-align: center; line-height: 2rem; } </style> </head> <body> <div id="test">test</div> </body> 咱们来看一下通过扭转手机的型号(视口的大小)对于页面的元素有什么变动。 从上述两张图咱们能够看出,当咱们扭转手机的型号后(扭转实现后记得要刷新哦),视口的大小也产生了扭转,对于test元素的宽高也产生了扭转,此时咱们就可能进行进行挪动端适配了。 ...

August 11, 2020 · 1 min · jiezi

关于less:less常用布局

flex.flex-container { display: flex; &.flex-align-center { align-items: center; }}.flex-item { flex: 1;}// .flex-shrink {// position: relative;// flex-shrink: 1;// -ms-flex-negative: 1;// -webkit-flex-shrink: 1;// -ms-flex: 0 1 auto;// flex: 0 1 auto;// }@col: 6;.mixin-loop (@i) when (@i > 0) { &.flex-@{i} { flex: 100% / @i !important; } .mixin-loop(@i - 1);}.mixin-loop(@col);height高度@row: 12;.mixin-loop (@i) when (@i > 0) { .row-@{i} { height: 100% / (12 / @i) !important; } .mixin-loop(@i - 1);}.mixin-loop(@row);margin and padding布局// 定义一个数组@sizeList:xs,sm,md,lg,xlg,xxlg;@list: t, r, b, l;/* 间距 n的倍数 */@base-spacing: 10px;.base-spacing-margin-t (@spacing: 1) { margin-top: @base-spacing * @spacing;}.base-spacing-margin-r (@spacing: 1) { margin-right: @base-spacing* @spacing;}.base-spacing-margin-b (@spacing: 1) { margin-bottom: @base-spacing* @spacing;}.base-spacing-margin-l (@spacing: 1) { margin-left: @base-spacing* @spacing;}.base-spacing-padding-t (@spacing: 1) { padding-top: @base-spacing* @spacing;}.base-spacing-padding-r (@spacing: 1) { padding-right: @base-spacing* @spacing;}.base-spacing-padding-b (@spacing: 1) { padding-bottom: @base-spacing* @spacing;}.base-spacing-padding-l (@spacing: 1) { padding-left: @base-spacing* @spacing;}// 条件.padding-mixin(@a, @i) when (@a = t) { .base-spacing-padding-t(@i);}.padding-mixin(@a, @i) when (@a = r) { .base-spacing-padding-r(@i);}.padding-mixin(@a, @i) when (@a = b) { .base-spacing-padding-b(@i);}.padding-mixin(@a, @i) when (@a = l) { .base-spacing-padding-l(@i);}.margin-mixin(@a, @i) when (@a = t) { .base-spacing-margin-t(@i);}.margin-mixin(@a, @i) when (@a = r) { .base-spacing-margin-r(@i);}.margin-mixin(@a, @i) when (@a = b) { .base-spacing-margin-b(@i);}.margin-mixin(@a, @i) when (@a = l) { .base-spacing-margin-l(@i);}// class.test (@className, @i ,@name) { .p-@{name}-@{className} { .padding-mixin(@name, @i / 2); } .m-@{name}-@{className} { .margin-mixin(@name, @i / 2); } //.p-@{name}-@{className} { // .base-spacing-padding-t(@i); //}}// 循环.loop(@i) when (@i < (length(@sizeList)+1)) { .s-loop(@j) when (@j < (length(@list)+1)) { //.sss(extract(@list, @i)); .test(extract(@sizeList, @i), @i, extract(@list, @j)); .s-loop(@j+1); } .s-loop(1); .loop(@i+1);}.loop(1);

August 4, 2020 · 2 min · jiezi

你的less父级选择器-玩出花了吗

不晓得各位同学有没有感觉当初css在前端圈子里越来越不受“待见”了。起因可能有下: 难以模块化,不可保护,没啥能够深入研究的面试根本也不会问啊局部公司还有 css 工程师,前端不须要关怀。。。然而作为从看张鑫旭大佬的文章才一步步开启我的前端之路的开发er,我可不能“忘了本”。犹记得才刚刚转行那会面试的时候会问我“你感觉本人css和js哪个更善于?”,我都会不犹豫的说“css”。 平时用 BEM 规定写款式的同学可能常常会遇到上面这样的(相似)场景,标签列表中会有失常状态和选中状态。故事的开始就是起于这样一段html代码: <!-- 第1种组织模式,集体比拟偏向这种 --><!-- tag外面的子节点变多的时候不须要给每一个子节点都增加 --active 的修饰符 --><div class="tag tag--active"> <img src="" class="tag__img" /> <span class="tag__text">222</span></div><!-- 第2种组织模式 --><!-- 可能更合乎 bem的 思维(缩小款式嵌套)--><div class="tag"> <img src="" class="tag__img--active" /> <span class="tag__text--active">222</span></div>针对第一种html的构造,如何通过父级选择器 & 更优雅的写出款式。当初咱们就从 & 的根底用法一步步说起。 为了不便咱们应用命令行测试,请全局装置less npm install less -g // 以后版本:3.11.3上面的例子都是基于常见的通过 BEM 写款式的业务场景。 置信看完这篇文章的同学再用 BEM 规定写款式的时候代码肯定会土气的一批。 根本用法& 运算符示意一个嵌套规定的父选择器下面是 less 官网对于 & 的定义(请肯定要粗浅领会),上面咱们通过例子来逐渐感触。 .header { &__text { color: #000; &--active { color: #fff; } } &:before { content: ''; display: block; } &.test3 { font-size: 12px; }}通过 lessc 编译后: ...

July 9, 2020 · 2 min · jiezi

分享一个页面平滑滚动小技巧

背景今天写需求的时候发现一个一个小的优化点:用户选择了一些数据之后, 选择的条目需要高亮, 有时候列表很长, 为了提升用户体验,需要加个滚动, 自动滚动到目标位置。 下午简单的查了一下, 问题顺利解决, 就把这个小技巧分享一下给大家。 正文有几种不同的方式来解决这个小问题。 1.scrollTop第一想到的还是scrollTop, 获取元素的位置, 然后直接设置: // 设置滚动的距离element.scrollTop = value;不过这样子有点生硬, 可以加个缓动: var scrollSmoothTo = function (position) { if (!window.requestAnimationFrame) { window.requestAnimationFrame = function(callback, element) { return setTimeout(callback, 17); }; } // 当前滚动高度 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; // 滚动step方法 var step = function () { // 距离目标滚动距离 var distance = position - scrollTop; // 目标滚动位置 scrollTop = scrollTop + distance / 5; if (Math.abs(distance) < 1) { window.scrollTo(0, position); } else { window.scrollTo(0, scrollTop); requestAnimationFrame(step); } }; step();};// 平滑滚动到顶部,可以直接:scrollSmoothTo(0)jQuery 中重的animate 方法也可以实现类似的效果: ...

October 22, 2019 · 1 min · jiezi

Less参数混合

Mixins 具有多个参数参数可以使用逗号或分号分隔。 (建议使用分号,因为逗号具有双重含义:可以将其解释为mixin参数分隔符或者是css列表分隔符);使用逗号作为mixin分隔符使不可能创建逗号分隔的列表作为参数。参数mixin使用一个或多个参数,通过参数和它的属性来扩展Less的功能,以达到在混合到另一个块时自定义mixin输出的效果。如果编译器在mixin调用中或者是声明中看到至少一个分号,那么假设这个歌参数用分号分隔的话,并且所有逗号都属于css列表,我们可以有以下几种情况: 两个参数,每一个包含逗号分隔的列表:.name(1, 2, 3; something, else)三个参数,并且每个包含一个数字:.name(1, 2, 3)使用虚拟分号创建混入调用一个参数包含逗号分隔的CSS列表:.name(1, 2, 3;)逗号分隔的默认值:.name(@param1: red, blue;)命名参数mixin引用时可以通过名称而不是位置来提供参数值,可以通过名称来引用任何参数任何参数都可以通过它的名称来引用,而不是特定的顺序 。 .mixin(@color: green; @font-size: 18px; @padding: 15px; @margin: 10px;) { color: @color; font-size: @font-size; padding: @padding; margin: @margin; } .name1 { .mixin( @color: blue; @margin: 20px;); } .name2 { .mixin(red; @padding: 30px; @font-size:40px;); } // 输出,改变后的值改变,没有重新赋值的值默认原值 .name1 { color: blue; font-size: 18px; padding: 15px; margin: 20px; } .name2 { color: red; padding: 30px; font-size:40px; margin: 10px; }@arguments 变量@arguments 在JavaScript中代表所有的参数,在mixin内部同样有特殊含义,它包含调用mixin时传递的所有参数;如果我们不想处理单个参数,它将会非常适用。 ...

October 17, 2019 · 1 min · jiezi

Less混合

混合类似于编程语言中的函数。 Mixins 是一组CSS属性,允许我们将一个类的属性嵌套于另一个类,被嵌入的类可以看作是变量,并且包含类名作为其属性,也就是说我们可以用一个类定义样式然后把它当作变量,在另一个类中,只要引用变量的名字,就能够使用它的所有属性。 在Less中,可以使用类或者是id选择器以与CSS样式相同的方式声明mixin,它可以存储多个值,并且可以在必要的时候在代码中重复使用。 注意:当我们调用mixin时,括号是可选的。 不输出mixin如果要创建一个mixin,但是又不想要输出mixin的话,我们可以在它的后面加上一个括号。 .myMixin1 { color: green; } .myMixin2() { background: red; } .allMixin { .myMixin1; .myMixin2; } // 输出 .myMixin1 { color: green; } .allMixin { color: green; background: red; }Mixins 中的选择器Mixins不仅可以包含属性,还可以包含选择器。 .myxkd-mixin() { &:hover { color: red; font-size: 30px; border: 1px solid green; } } button { .myxkd-mixin(); } // 输出 button:hover { color: red; font-size: 30px; border: 1px solid green; }命名空间如果要在更复杂的选择器中混合属性,则可以堆叠多个ID或类。 ...

October 16, 2019 · 1 min · jiezi

Less-延伸

extend 是一个 Less 伪类,它通过使用:extend 选择器在一个选择器中扩展其他选择器样式。 扩展语法扩展可以是附加到选择器,也可以是集中放置在规则,看上去像是带有选择器参数的可选伪类,然后紧跟关键字 all 。 // 第一个块和第二个块做同样的事 .x:extend(.y) {} .x{ &:extend(.y);} // 扩展 .y 元素选择器的所有实例 .x:extend(.y all){} // 仅扩展选择器输出为 .y 的实例 .x:extend(.y){}扩展附加到选择器附加到选择器的扩展在我们看来像是一个普通的伪类,带有选择器作为参数,一个选择器可以包含多个extend子句,但是所有扩展都必须在选择器的末尾。 在选择器之后扩展:pre:hover:extend(div pre)。选择器和扩展之间允许有空格:pre:hover :extend(div pre)。允许多个扩展:pre:hover:extend(div pre):extend(.bucket tr)。不允许的:pre:hover:extend(div pre).nth-child(odd),扩展必须是最后一个。如果规则集中包含多个选择器,那么它们中的任何一个都可以是具有extend关键字的,在一个规则集中扩展的多个选择器。 .xkd_first, .xkd_second:extend(.vue), .xkd_three:extend(.python){ // 内容代码 }扩展内侧规则语法使用:&:extend(selector),将扩展放置到主体中是将它放入这个规则集的每个选择器的快捷方式。 // 在体内延伸 pre:hover,.xkd_extend{ &:extend(div pre); } // 与在每个选择器之后添加扩展名完全相同 pre:hover:extend(div pre){ .xkd_extend:extend(div pre){} }扩展嵌套选择器扩展能够匹配的嵌套的选择器,减少以下内容。 // 带目标选择器的嵌套规则集 .xkd{ tr{ background:green; font-size:30px; } } .xkd_extend:extend(.xkd tr){} // 输出 .xkd tr,.xkd_extend{ background:green; font-size:30px; } // 从本质上讲,扩展将查看已编译的CSS,而不是原始的CSS精确匹配扩展默认情况下,extend查找选择器之间的精确匹配。 ...

October 15, 2019 · 2 min · jiezi

Less-变量

概念使用 @ 符号定义变量,变量分配使用 : 完成。 声明格式:@变量名:变量值。 通常看到很多重复的相同的值,我们可以通过使用变量来避免。 Less中的变量和其他编程语言一样,可以实现值的复用,同样的它也有作用域,简单的来说就是变量的作用域就是局部变量和全局变量的概念;变量作用域采用的是就近原则,也就是说我们需要先查找自己本身是否有这个变量,如果有就使用自身变量,没有的话就查找上一级父元素,以此类推。 可变插值选择器名插值(可以引用任何变量)属性名插值(可以引用任何变量)URL插值(用来保存URL,并在url()中使用它)import 插值(import语句中,用来保存路径的变量)媒体查询插值导入语句 版本:1.4.0 句法: @import "@{themes}/tidal-wave.less"; 注意:在v2.0.0之前,我们仅考虑在根范围或者当前范围内声明的变量,并且在查找变量时仅考虑当前文件和调用文件。 // 变量 @themes: "../../src/themes"; // 用法 @import "@{themes}/tidal-wave.less";属性版本:1.6.0 @property: color; .widget { @{property}: #0ee; background-@{property}: #999; } // 编译为 .widget{ color: #0ee; background: #999; }变量名可以使用变量名称定义变量。 @fnord: "I am fnord."; @var: "fnord"; content: @@var; // 编译为 content: "I am fnord.";延迟加载变量是延迟加载的,无需在使用前声明。 .lazy-eval-scope { width: @var; @a: 9%; } @var: @a; @a: 100%; // 编译为 .lazy-eval-scope { width: 9%; }默认变量有时候我们会请求默认变量:一种仅在尚未设置变量的情况下才可以设置的功能,不需要这个功能是因为我们可以通过在后面放置定义来轻松覆盖变量。 ...

October 14, 2019 · 1 min · jiezi

空手套白狼我的互联网草根创业亲身经历

和大多数人一样,我出生寒门学子,没钱没势,所有的一切都是从零开始,只能空手套白狼,本文章主要是为了分享下我个人的创业经历以及一个产品从无到有的过程,后面也会聊到我做H5工具的相关技术方案,希望能帮助读者在未来的工作或者是创业路上有所帮助。2010年第一次创业务实的人都不甘于平庸,我亦如此,也许越是有挑战的东西,我越是感兴趣,创业的想法就像一颗毒瘤一直在我脑中去不掉,大学第一天上学,我把所有的生活费在阿里巴巴上进了一堆跳舞毯,开始了人生的第一次创业,我记得那是2010年上大一的事情了,虽然没有赚回本钱,但是我意外的认识了生产跳舞毯的老板。在学校里卖不完跳舞毯,于是我开了个淘宝店铺在网上卖,虽然网上也没卖完,却阴差阳错的成为了跳舞毯公司的网店兼职设计师(精通美图秀秀),再后面就自学了PS,成为了一个UI设计师,我大学学的是java,因为学习了PS,也就顺理成章的成了前端工程师。也为接下来的创业奠定了技术的基础。 2012年第一个工作室大学2年期间,我的前端技术逐渐成熟了,可以做一些官网站了,于是我打算在乐山本地找一家网络公司做兼职,很快我成功的拿到了他们的网站订单,创意的设计风格加上物美价廉,很快成为了这家公司稳定的合作方,于是我在学校里面创立了自己的工作室(馒头工作室)。我的头像也是M这个LOGO也一直沿用至今。 2014年人生第一家公司14年,我们都被大学老师赶出去找工作,刚刚出来的我找了一家公司,但是很快就按耐不住想要创业的想法,于是聚集了几个同学,我们一起创办了一家公司,受到了“云来场景应用”的启发,当时我们就在想,要是能批量生产H5就好了,我们提出了“即见即所得”的概念,很快在14年发布了第一款产品"酷APP",我这里还保留了几张珍贵的截图: 但是当时缺乏商业经验以及面临公司生存的问题,没有拿到融资的我们很快就坚持不下去了,然后项目以失败告终!团队也各奔东西。 小知识:什么是H5?微信扫描以下二维码即可查看H5 H5DS v1.x 版本虽然第一款自主研发的产品失败了,但是我依然觉得这个产品是个好东西,于是贼心不死的我在15年团队解散后发布了另外一个编辑器产品(H5DS)也就是现在的1.x版本。界面是参考PhotoShop来做的,是不是感觉很像PS? H5DS v2.x 版本有了1.x版本,那就有2.x是吧?期间我去了一家创业公司,在那家公司我用下班的业余时间,在H5DS的基础上又重构了一个版本,2.x的编辑器。界面清爽了很多,而且功能也更多了。 H5DS v3.x 版本16年的时候,大多数创业公司都输给了资本,我所在的创业公司也无法避免,随着上家创业公司的倒闭,我没有马上找工作,回到家里,我继续捣鼓我的编辑器,于是很快发布了3.x版本。界面从白变黑,整个代码也重写了。可以说3.x版本完全是重构的。 H5DS v4.x 版本到现在3年了,因为兼职的原因,所以进度很慢,后来在一次技术分享会上面,我认识了我的技术合伙人,基于3.x版本,我们一起发布了4.0版本,3.0版本是jquery的版本,那么4.x就是react的版本。 H5DS v5.x 版本4.x版本的生命周期是很短的,在多次讨论后,我们在4.x之上,我们很快就发布了5.x版本。5.x版本在界面上没有做任何改动,但是代码完全重构了,5.x也就是现在的版本。从此选择了拥抱react生态,海量react组件库在H5DS中都可以使用。 产品版本总结任何产品都非一来就完美的,如果是那样,我也不用重构那么多版本了,慢慢改进打磨迭代升级,产品就会越来越完善,越来越强大。可以看到产品的进步,也可以看到我们想法的转变,任何一次升级都是为了更好的迎合市场的需求,如果希望自己的产品能走的更远,那就不要停下来!创业也是一样,并非一开始就什么都会,什么都有,也是慢慢积累起来的经验和知识,然后学以致用。感觉有点像玩游戏打怪升级,一开始在新手村混,然后到普通玩家区,再到高玩(高端玩家)区,一开始就到高玩区,肯定死翘翘了! H5DS产品概述H5DS(HTML5 design software)h5ds.com 是一款真正意义上的HTML5页面制作工具,非常难得是这个项目我做了5年,版本也换了好几个,依旧初心不改!未来还有很多个五年,我也希望自己的工具会越做越好,下面就来聊聊这个花了我无数心血做的产品。 准确的产品定位类似的竞品也比较多。比如易企秀,maka,兔展,人人秀,wps秀堂,凡科H5等。我们的产品究竟有何不同? 普通用户而言:H5是手机上用于营销的滑动页面。 专业技术人员:H5是HTML5的简称,是一门技术方案,滑动页面只是H5的一小块应用领域。 很明显,其他竞品的定位是做营销滑动页面,而我们的定位是HTML5的编辑器。可以做滑动页面,网站,3D虚拟现实,数据报表,PC网站,小程序,在线PS,在线动画制作等应用。 从一个技术到产品再到销售任何成熟稳定的产品都不是一朝一夕就能完成的,从1.x到5.x,我从一个技术慢慢也有了产品的思维,这个项目让我学到了太多的东西,我觉得是任何公司都给不了一个技术的东西,做了这个项目,让我有了和可客户坐在咖啡厅唇枪舌战的经历,同时我也有了产品经理的经验,我规划的功能也曾遭受用户的质疑,甚至有用户专门发了一个word文档给我,里面罗列了40多个编辑器改进意见,做一个产品是一件非常有意义的事情,我也兼职了UI的工作,玩起了PS,如何设计交互让用户感觉更友好,让我掉了不少头发!这个项目让我体验了设计师,技术,产品,销售,至少哪天不写代码了,还可以去跑下业务! 创业九十九死一生一路走来,我感觉自己创业以来什么都缺,缺人才,缺资金,缺资源,的确,创业是非常艰难的,如果说九死一生是其他行业的创业,那IT行业真的是99死一生。14年在风口的创业公司有多少能活到现在?14年我们创业的时候也是冲着融资去的,但是现在不是了,我觉得首先要活下去,然后再想如何发展壮大,如何赚钱。我所知道的很多IT公司都需要靠融资才可以活下去,一旦资金链断裂了,公司立马倒闭,H5DS在发布4.x版本的时候就已经能做到自负盈亏了,所以目前我们不需要融资,不用考虑生存的问题,虽然节奏慢了点,但是不至于倒闭做不下去了,先解决温饱,才可以创造价值。我希望我们的产品能走的很远,只要活着,就有希望!虽然看上去比较悲观,但是创业真的非常残酷!我非常庆幸自己没有放弃,一直坚持做自己的产品,算下来,今年是5年了,正好是v5版本。产品也比较接近我的预期。 未来会走的更远非常庆幸,我们在第一个5年活下来了,未来我们会站在巨人的肩膀上,走的更远!至于未来五年的规划,虽然我已经做好了,但是市场永远是变化不可测的,我们也会不断的更新产品,推出新鲜的功能,只希望能在这条道路上走的更远! 技术干货分享聊了太多和技术不挂边的东西,差点忘记自己是一个技术了,接下来会聊一些技术相关的东西,也算是分享一些干货给给位技术同僚!就编辑器技术部分,这里给大家做个分享。 技术选型技术选型我们采用react + mobx + koa2 + mysql 整体都是JS技术栈,至于为什么要这样选型,因为我们人少,技术保持统一,方便维护!另外一方面原因是因为我们是一个创业团队,技术资源非常宝贵,必须尽可能的节约开发成本,也是为什么我们会选择纯JS的技术栈,这样我们每个人都可以做前端也可以做后端。 mobx 最最核心的概念只有2个。 @observable 和 @observer ,它们分别对应的是被观察者和观察者。这是大家常见的观察者模式,这里使用了ES7 中的 装饰器。参数发生变化时自动触发render更新视图,这个和vue是一样的原理。之所以没有使用vue是因为我们也需要react的state配合起来做性能优化以及灵活的数据处理。我们可以结合防抖函数去做性能优化,控制或者选择性的去更新视图。下面举个例子: import React, { Component } from 'react';import { inject, observer } from 'mobx-react';import debounce from 'lodash/debounce';@inject('h5ds')@observerclass Demo extends Component { constructor(props) { super(props); this.state = { count: props.h5ds.count // 默认是1 } } // 防抖函数控制性能 updateOtherRender = debounce(() => { const { count } = this.state; // 如果大于10才会去更新其他地方的视图 if(count > 10) { this.props.h5ds.count = this.state.count } }, 500) changeValue = e => { this.setState({count: e.target.value}, this.updateOtherRender) } render() { return <input type="number" value={this.state.count} onChange={this.changeValue}/> }}我们在很多地方都有用到上面这种写法,react提倡的最小模块化,我们也希望模块之间的影响会最小,如果一个参数在多个模块中被使用,在快速输入的时候务必会变的很慢。 ...

September 10, 2019 · 2 min · jiezi

野子电商数据分析

野子电竞数据官网改版https://www.xxe.io/ 全新登场1.通用型的数据分析入门思维,比如AARRR(海盗模型)获取用户–>提高活跃度–>提高留存率–>获取营收–>自传播 2.实现数据分析的流程深入业务–>构建指标体现–>事件设计–>数据采集–>业务目标–>数据分析–>验证迭代重点:1)构建指标体现;2)数据分析+验证迭代 3.关注的指标1)总体运营指标:1.1.活跃用户数、新增用户数1.2.总订单量、访问到下单转化率1.3.成交金额(GMV)、销售金额、客单价1.4.销售毛利、毛利率 2)流量指标:2.1.新增用户数、页面访问数2.2.用户获取成本2.3.跳出率、页面访问时长、人均页面访问数2.4.注册会员数、活跃会员数、活跃会员率、会员平均购买次数、会员留存率 3)销售指标:3.1.加入购物车次数、加入购物车买家数、加入购物车商品数、购物车支付转化率3.2.下单笔数、下单金额、下单买家数、浏览下单转化率3.3.支付金额、支付买家数、支付商品数、浏览-支付买家转化率、下单-支付买家转化率3.4.交易成功/失败订单数、交易成功/失败金额、交易成功/失败买家数、交易成功/失败商品数、退款订单数量、退款金额、退款率 4)客户价值指标:4.1.累积购买客户数、客单价4.2.新客户数量、新客户获取成本、新客户客单价4.3.消费频率、最近一次购买时间、消费金额、重复购买率 5)市场营销活动指标:5.1.新增访问人数、新增注册人数、总访问次数5.2.订单数量、下单转化率5.3.ROI(投资回报率) 4.如何分析1)渠道分析顺序:曝光–>点击–>下载–>注册–>付费核心数据是有效注册数,其次是付费用户数,最后是arpu值 2)用户运营:2.1.根据活跃度:新增活跃用户、活跃老用户、沉默用户、流失用户…2.2.根据商品偏好:美妆类、母婴类、零食类、电子产品类、书籍类…2.3.根据消费能力:普通会员、黄金会员、白金会员、钻石会员…2.4.根据消费频率:每周一次以上、每月1-2次、三个月2次…

September 9, 2019 · 1 min · jiezi

使用lessloader与antd按需加载babelpluginimport的坑

为了在react中使用antd以及它的主题更改,需要在项目中 yarn eject 暴露出webpack文件进行改造本答案是在日期当时最新的create-react-app上的webpack版本 less-loader的配置安装less less-loader两个包yarn add less less-loader//配置less的变量const lessRegex = /\.less$/;const lessModuleRegex = /\.module\.less$/; //less配置(模仿css的配置改写) { test: lessRegex, exclude: lessModuleRegex, use: getStyleLoaders({ importLoaders: 2, sourceMap: isEnvProduction && shouldUseSourceMap, }, 'less-loader'), }, { test: lessModuleRegex, use: getStyleLoaders({ importLoaders: 2, sourceMap: isEnvProduction && shouldUseSourceMap, modules: true, getLocalIdent: getCSSModuleLocalIdent, },'less-loader'), },设置后可以新建less文件用简单样式去检测是否生效,要记得重启项目。Babel-plugin-import(antd的按需加载设置)安装插件yarn add babel-plugin-import修改package.json(或新建文件.babellrc进行编辑,但两者只能存一种)"babel": { "presets": [ "react-app" ], "plugins": [ [ "import",{"libraryName":"antd","style":"css"} ] ] }根据webpack配置更改antd主题颜色在webpack.config.js中找到preProcessor //原配置 if (preProcessor) { loaders.push({ loader: require.resolve(preProcessor), options: { sourceMap: isEnvProduction && shouldUseSourceMap, }, }); }注释后更改为 /** * 定义全局样式配置 */ if (preProcessor) { let loader = require.resolve(preProcessor) if(preProcessor === 'less-loader') { loader = { loader, options: { modifyVars: { //自定义主题 'primary-color': '#1890ff', }, javascriptEnabled: true, } } } loaders.push(loader); } return loaders; };只需修改primary-color的颜色,再重启项目即可更改主题颜色

July 15, 2019 · 1 min · jiezi

Less语言特性

第二节(Less)githubVariables(变量)在你的样式表中相同的值重复几十次 甚至上百次 并不少见,变量通过为你提供一种在一个地方管理这些值的方法让你的代码变得更容易维护。 @nice-blue: #5B83AD;@light-blue: @nice-blue + #111;#header { color: @light-blue;}//作为属性名@mySelector: banner;.@{mySelector} { font-weight: bold; line-height: 40px; margin: 0 auto;}// 作为URL@images: "../img";body { color: #444; background: url("@{images}/white-sand.png");}// 作为import引入@themes: "../../src/themes";@import "@{themes}/tidal-wave.less";// 作为属性@property: color;.widget { @{property}: #0ee; background-@{property}: #999;}// 作为变量@fnord: "I am fnord.";@var: "fnord";content: @@var;由于变量只能定义一次,实际上也相当于常量。 变量是延迟加载的,在使用前不一定要预先声明。 同名变量后面的会覆盖前面的。 Extend(拓展)nav ul { &:extend(.inline); background: blue;}.inline { color: red;}输出: nav ul { background: blue;}.inline,nav ul { color: red;}extend可以附加给一个选择器,也可以放入一个规则集中。它看起来像是一个带选择器参数伪类,也可以使用关键字all选择相邻的选择器。 .a:extend(.b) {}// 上面的代码块与下面这个做一样的事情.a { &:extend(.b);}.c:extend(.d all) { // 扩展".d"的所有实例,比如".x.d"或者".d.x"}.c:extend(.d) { // 扩展选择器编译为".d"的唯一实例}.e:extend(.f) {}.e:extend(.g) {}// 上面的代码与下面的做一样的事情.e:extend(.f, .g) {}如果你想有一个animal子类型,并且要重写背景颜色。那么你有两个选择: ...

July 14, 2019 · 3 min · jiezi

前端利器之less入门

Less 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量、Mixin、函数等特性,使 CSS 更易维护和扩展。一遍一遍写一大段一大段一样的代码,有木有很乏味,如果要换一个contain为cover呢?编译之后引用css文件 我推荐使用Koala.exe 下载地址 多语言支持 支持Less、Sass、CoffeeScript 和 Compass Framework。实时编译 监听文件,当文件改变时自动执行编译,这一切都在后台运行,无需人工操作。项目配置 支持为项目创建一个全局配置,为文件设置统一编译选项。跨平台 Windows、Linux、Mac都能完美运行。 less 是什么? Less 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量、Mixin、函数等特性,使 CSS 更易维护和扩展。less,是方便我们快速编写CSS的工具,它增强了CSS代码的扩展性和复用性。Less 可以运行在 Node 或浏览器端。 less能为我们做什么? 下边让我们来看一段我们经常写的代码 /我们经常写浏览器的兼容,假设我们写icon/nav a.home.active i { background: url('images/nav-home-on.png') no-repeat center; background-size: contain; -webkit-background-size: contain; -moz-background-size: contain; -o-background-size: contain;}nav a.home i { background: url('images/nav-home-off.png') no-repeat center; background-size: contain; -webkit-background-size: contain; -moz-background-size: contain; -o-background-size: contain;}nav a.topics.active i { background: url('images/nav-circle-on.png') no-repeat center; background-size: contain; -webkit-background-size: contain; -moz-background-size: contain; -o-background-size: contain;}nav a.topics i { background: url('images/nav-circle-off.png') no-repeat center; background-size: contain; -webkit-background-size: contain; -moz-background-size: contain; -o-background-size: contain;}一遍一遍写一大段一大段一样的代码,有木有很乏味,如果要换一个contain为cover呢?改疯了有木有让我们看看less会怎么做 ...

July 12, 2019 · 2 min · jiezi

less用法让css更加简便

什么是lessLess 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量、Mixin、函数等特性,使 CSS 更易维护和扩展。Less 可以运行在 Node 或浏览器端。如何引入less使用less有以下三种方式直接引入 Less.js使用CDN在线引入在命令行 使用npm安装npm install less -g3.为什么使用less(less优势) 1.变量 2.混合嵌套 3.方法 4.父子元素 5.import4.如何使用less 1.创建html页面,在页面内引入mian.css 2.创建less页面,并编写less代码 3.运行指令lessc main.less > main.css,生成对应的css文件 在命令控制行中通过运行指令lessc main.less > main.css,生成对应的css文件 可以通过指令lessc main.less来预先查看编译后的css代码样式生辰八字起名字 5.变量 通过@变量名的方式来进行变量的定义(@等同于var),之后通过调用变量名来进行赋值,这样可以极大的重复代码,对于性能优化也有很好的提升6.混合嵌套 在编写部分css代码时,可能会出现相同属性多次使用的情况 在上面的两个样式中都使用了border这个属性,并且内容完全相同;在传统 CSS 写法中只能这样一遍又一遍的去书写重复的内容,在 Less 中通过将公共属性抽取出来作为一个公共类的方式规避这一点。 总结 混合也是减少代码书写量的一个方法; 混合的类名在定义的时候加上小括弧 (),那么在转译成 css 文件时就不会出现; 混合的类名在被调用的时候加上小括弧 ()和不加上小括弧 ()是一样的效果,看个人习惯,如:第三行和第八行转译成 css 是一样的。 7.Function 在less中,我们可以通过编写一个css类的方法,将值通过参数的形式进行传参,然后只调用方法和实参,就可以完成css的设置 语法 .方法名(形参){定义css属性} .background(@color){background: @color;}

July 12, 2019 · 1 min · jiezi

vuecli安装使用less

vue-cli构建的项目默认是不支持less的,需要自己添加依赖1.安装less和less-loader ,在项目目录下运行如下命令npm install less less-loader --save-dev 2.安装成功后,打开build/webpack.base.conf.js ,在 module.exports = 的对象的module.rules 后面添加一段:module.exports = { // 此处省略无数行,已有的的其他的内容module: { rules: [ // 此处省略无数行,已有的的其他的规则 { test: /\.less$/, loader: "style-loader!css-loader!less-loader", } ] }} 3.最后,在代码中的style标签中加上lang="less"属性即可 <style lang="less" scoped> .index-wrap { display: flex; align-items: center; justify-content: center; span { font-size: 0.373rem; } }</style>

July 12, 2019 · 1 min · jiezi

微前端改造初探

在写这篇文章的一个多月前,本坑还不知道微前端是什么,大概从字面上的含义是比较小的前端项目。 本坑开始实践它,是由于工作要求。改造一个运行多年,前端用jsp写的服务平台项目(以下简称该平台)。改造它是改造它的前端架构。改造它的原因是比较多人反馈,其页面加载和渲染显得吃力,页面切换后首屏等待时间长的问题,交互体验舒适度不可避免的下降了,特别是在老式电脑面前。 该平台业务比较多,所以组长希望前端框架组能把平台中的前端部分分离出来,最好用当下满大街的Vue、能够按照各个一级菜单分成若干前端子项目,用户访问依然是整体的项目,同时这一改造实施过程不需要重做一个、而是整个500多个页面从局部开始、是逐步、兼容的,新旧同时运行,直至整体被替换。(ps:不重做?这......科学吗?) 看看,慢在哪里其实大概知道慢在哪里,但是不知道究竟慢在具体哪个部分。和其他一以贯之的类似管理平台布局并无不同。左边导航栏,上面顶栏,右侧内容栏,整体页面是一个index.jsp。上面提到的内容栏是一个iframe,里面通过切换src来切换页面。更多的业务造就更多页面,更多页面带来更多的加载。加上长时间没有做好资源加载的管理,导致渲染一次页面需要加载大量js,css或者多次加载同一个文件的情况。该平台大量的配置页面生成,是通过easyui的来做的。通过数据来创造整个页面dom节点,也拖累了内容完整呈现的时间。 我们使用谷歌浏览器performance可以最终追查到这个系统在哪些方面,哪个方法存在着哪些延迟。结论是: 1、混乱的项目资源管理导致大量的资源请求。 2、easyui和项目中不少的dom操作带来大量的重排和重绘。 3、埋点,插件使用不当以及其他。 微前端它是什么呢? 微前端的概念来自于之前流行的微服务。它的来源很大程度是来自于这篇文章 。微服务系统使得后台服务架构能够比较好地规避越来越臃肿的体积带来的性能下降。根据业务合理拆分成一个个的服务,尽量避免一个子服务影响整个项目运行的优势,有效的进行隔离。 那么,前端也有同样的需求吗?答案是肯定的。 今天,日益更新的前端技术,已经能够把一个个页面各个小元素打包成组件库,功能包,在多个项目中引入使用。此外,我们不用再使用难受的iframe来聚合不同的项目,而是导出一个个web component,只需要import 到页面就可以使用。把一个个子项目打包成一个个web component,聚合在入口项目之内。这也许就是微前端现在比较时髦的样子。如果一个大项目有以下特点,微前端可以在这些项目中运用:1、大项目有统一的入口,子项目页面需要无刷新下切换,可是各个子项目在业务上和开发团队上是不同的。 2、项目过大,打包、运行、部署效率出现显著下降的问题。这时希望能根据业务拆分打包,部署。 方案与实施回到本文开头,一开始面对这样的需求还是有些想辞职的冲动,因为觉得需求有点不是符合实际,实际上要实施改版也是需要过程的。 不过静下来想想,搜搜,翻了翻当前项目的前端结构,隐隐约约似乎浮现一些需求可行性的线索。 因为项目的最终目的是把整个jsp页面改成vue来写。而这一要求是逐步替换的过程,所以在改造过程中,同时要保证项目兼容jsp的页面。我们继续沿用了原来就有的iframe,借此把jsp融入整个微前端框架,而已经改造的micro则不需要iframe.我们的开发团队,分框架组和各个业务组。其中每个业务组有3到8个人,他们大多数是后端背景,主要做的也是后端开发。框架组有前端和后端。为了应付庞大的业务开发需求。大部分后端人员都需要使用jsp,js等前端技术进行开发。框架组为了减少他们的前端开发门槛,前端框架组会封装好easyui组件,提供业务组使用。所以,正如前文提到,后端人员是通过数据,结合框架组提供的组件来完成页面的开发的。从某种角度来说,数据配置的页面对接下来的改造工作有一定的帮助,因为大部分页面可以同时改写。 我们对整个项目进行了大致的分类。 1、portal 项目:该项目是整个微前端项目的入口。里面含有loader,用以加载各个项目模块。它也嵌入到子项目中,使得单独运行子项目和portal项目一样的界面要求。2、permission 项目:该项目包含菜单组件,登录页面,顶栏组件,权限控制等。在任何环境下,它都必须首先加载,为子项目模块挂载提供锚点。3、common项目:该项目包含公共业务组件。比如封装好的页面,可以直接给不太能够掌握vue项目的后端人员更加友好的去使用。4、业务项目:就是指业务组各个模块开发的前端项目。什么样的业务分为一个项目,这点由产品和技术人员一起来决定。相对于portal项目,业务项目相当于它的子项目。 前端框架组必须提供一套统一的业务项目的前端模板,可以在确认新建的子项目后迅速的加入到整个项目中,进行开发和部署,而这一过程不能影响其他项目的部署和运行。 除了上述方案浮出水面,还会在改造过程中遇到一个个细节问题。 不过在大方向,框架组成上,前端结构上做好了,细节问题也会随耐心和时间被解决。 分别阐述本坑根据以上的分类,大致进行说明其实现。这其中结合了不少前辈之经验,在文章结尾处鸣谢。 Portal:portal 项目是整个项目部署的入口,它的核心来自于single-spa 在整个项目结构中它将集成到每一个子项目。集成的方式很粗暴简单,就是外联加载。portal负责根据不同的环境来对应的组件和app,同时也安装各个app,卸载各个app等,它负责app在single-spa的生命周期。比如集成模式下根据环境和路由加载对应的app,而在子项目运行时只加载公共组件和不同业务的app。 那么protal是如何加载的呢? protal维护了一个json里面包含了各个子项目的index.html的信息,通过匹配index.html里面的src 、link,加载各项资源。 module.exports = { common: { webName:'common', globalVarName: 'mfe:common', componentsTarget: '/common/release/components/web.html', resourcePatterns: ['/components.[0-9a-z]{8}.js/g'], loadType:'before' }, permission: { webName:'permission', globalVarName: 'mfe:permission', // URL 匹配模式 matchUrlHash: '', // 微前端地址 componentsTarget: '/permission/release/components/web.html', webTarget:'/permission/release/web/web.html', // 资源匹配模式 resourcePatterns: ['/common.[0-9a-z]{8}.css/g','/store.[0-9a-z]{8}.js/g', '/publicPath.[0-9a-z]{8}.js/g','/singleSpaEntry.[0-9a-z]{8}.js/g','/components.[0-9a-z]{8}.js/g'], //是否要在项目启动前加载,before为提前加载,after为hash变化后加载 loadType:'before' }, app4vue:{ webName:'repair-order', globalVarName: 'mfe:app4vue', matchUrlHash: '/layout/repair-order', webTarget: '/app4/release/web/web.html', resourcePatterns: ['/common.[0-9a-z]{8}.css/g','/store.[0-9a-z]{8}.js/g', '/singleSpaEntry.[0-9a-z]{8}.js/g'], loadType:'after' }} async gatherResource () { const self = this // const spaEntry = 'portal' const web = self._webName //如果是微前端聚合模式 if (window._IS_SIGLE_PORTAL) { if (web !== 'mfe-permission') { await self.loadComponents(micros.common) await self.loadApp(micros.permission) } } else { if (web === 'mfe-permission') { await self.loadComponents(micros.common) } else { if (web !== 'mfe-common') { await self.loadComponents(micros.common) } await self.loadApp(micros.permission) } } // return new Promise(resolve => resolve('loader:all Finish!')) }permisson:permission负责登录页,layout中的菜单栏,顶栏。所有的子项目app都必须挂载到permission项目中的显示区块里。也就是说permssion会提供锚点给子项目挂载。 ...

July 10, 2019 · 2 min · jiezi

css-预处理器-sassscsslessstylus

css 预处理工具,可以将其编译为 css基本介绍sass/scssSASS 2007年诞生,最早也是最成熟的CSS预处理器,拥有ruby社区的支持和compass这一最强大的css框架Sass的缩排语法,对于写惯css前端的web开发者来说很不直观,sass 不兼容 css 代码Sass3 就变成了Scss(sassy css) 与原来的语法兼容,只是用{}取代了原来的缩进sass 的运行 依赖于 ruby 环境(compass 将 sass 编译为 css)现在可用 node-sass 来编译 sass/scss 文件 node-sass 是一套在 node.js 用 LibSass 編 sass/scss 的工具原始的sass 是用 ruby 编写的,所以需要 ruby 环境,libSass 是原始sass引擎的一个 c/c++ 接口,使用它编译sass不依赖于ruby,可以使用其他语言使用libSassnode-sassruby-sass与libsass的区别安装node-sass时,会去GitHub 下载一个 .node的文件而这个文件托管在墙外的服务器上,所以失败了 node-sass安装失败解决方案以 .sass 或 .scss 为文件后缀名称(现在一般都是用 scss)lessless 2009年出现,受sass的影响较大,但又使用CSS的语法,让大部分开发者和设计师更容易上手,在ruby社区之外支持者远超过SASS,其缺点是比起SASS来,可编程功能不够,不过优点是简单和兼容CSS,反过来也影响了sass演变到了scss的时代,著名的Twitter Bootstrap就是采用LESS做底层语言的。less 可以使用 less.js 在浏览器运行时中解析 less 代码也可以在 node环境中 安装 less,提前编译 less 文件 `npm install -g less &lessc styles.less styles.css` (可以加参数控制编译后的css排版及压缩)以 .less 为文件后缀名称stylusStylus,2010年产生,来自Node.js社区,主要用来给Node项目进行CSS预处理支持,由 TJ 大神开发安装及编译 npm install stylus -g & stylus src/ (可以加参数控制编译后的css排版及压缩)以 .styl 为文件后缀使用现状现在一般都是配合webpack使用这几种预处理语言,需要先安装 编译器、对应 loader,然后再 module.rules 配置其具体规则基本语法less 基本语法属于 css 风格,而 sass,stylus 利用缩进,空格,换行来减少需要输入的 字符目前 scss, stylus 也可以支持 css 风格,用大括号 来书写 ...

July 9, 2019 · 2 min · jiezi

龙芯国产域名服务器发布-完全国产不远了

现在一说到服务器处理器,那必然是领先的intel和AMD处理器,基本上处理器还是intel的天下,重新分级的处理器分为铂金、金、银、铜四个等级,对应之前的E3、E7、E5的分类,等级不同价格不同,基本的金牌处理器都是一万美金起步,这个价格会让很多企业望城却步.这些年AMD一直被intel在服务器市场打压,基本没有什么还手之力,但是2019年开始AMD最新的Zen 3架构发布,分别是7nm工艺的Rome罗马、7nm+工艺的Milan米兰,之后会在2020年后则会有新一代HEDT平台,主流处理器代号Vermeer(维梅尔),APU平台代号Renoir雷诺瓦,这些新平台的新核心架构.这就看来大的服务器厂商都在服务器处理器上下功夫,因为他们知道真正赚钱的还是服务器处理器,一个IDC商采购项目的投资,基本上是当地民用市场几年的收益,所以都想强占这个桥头堡.我们中国的龙芯本世纪初开始的”狗剩”到现在的构架服务器处理器,经过了漫长的发展之路.目前新一代龙芯最强的型号为3A3000和3B3000,是四核64位处理器,主频1.35-1.5GHz,一二级缓存64K每个核独享,共享8MB三级缓存,TDP功耗只有30瓦,能够支持DDR3内存,并且支持服务器需要的ECC功能。虽然和国际上intel和AMD无法比较,但是所有构架都是我们自主研发,所有部件我们都能够独立制造.大家都知道,互联网的根域名服务器一直是发达国家掌握,2019年7月,国家工程研究中心联手龙芯发布了基于龙芯处理器的域名服务器,  结束了域名解析被国外“卡脖子”的历史,根域名服务器简单地说,没有他我们就完全上不去网,即使中国网络没事,没有根域名服务器也上不去,现在即使外国全面断网,我们国内还是能使用互联网.现在龙芯处理器能够达到四核64位,由于使用了精简指令集(RISC),所以龙芯的RISC+MIPS非常适合服务器上使用,这要是企业和个人完全使用龙芯服务器,我国每年最大的进口商品将消失,美国对我们信息战也基本结束.这一点还要观众老爷们深思,中华强则技术强.这里推荐国产的服务器管理工具平台,由于很多服务器都是linux系统,代码下操作肯定不便,所以针对linux服务器的特点,国人自己研发了云端化的服务器管理工具,可以实现只要浏览器就可以批量化管理自己的服务器,不管你的服务器在任何厂商和任何IP.这个平台就是旗鱼云梯,不光是linux管理平台,也是一键化建站,批量管理运维的工具,对于服务器的安全防护直接是底层支持,方便管控服务器里的网站实现SEO优化设置.

July 5, 2019 · 1 min · jiezi

vue之echarts的vif渲染

1.通过以下命令安装echarts npm install echarts --save2.在main.js文件里全局引入echarts import echarts from 'echarts'Vue.prototype.$echarts = echarts3.单页面引用echarts import echarts from 'echarts'// html代码<div v-if="noData">123</div><div v-else class="details-ECharts" style="width:100%;overflow-x: scroll;"> <div id="myECharts" style="width:100%;height:220px;background-color:#ffffff;"></div></div><script>// js代码import echarts from 'echarts'export default { name: 'aaa', data () { return { xData: [], tionData: [], noData: false } }, methods: { statistics () { var myChart myChart = echarts.init(document.getElementById('myECharts')) myChart.setOption({ title: { text: '对比图', x: 'center', y: 'bottom', textStyle: { color: '#666666', fontWeight: 'normal', fontSize: 13 } }, xAxis: [ { type: 'category', data: this.xData, axisLine: { show: false }, axisTick: { show: false } } ], yAxis: [ { type: 'value', axisLine: { show: false }, show: false } ], series: [ { name: '222', type: 'bar', barWidth: '10px', data: this.tionData, smooth: true, itemStyle: { normal: { barBorderRadius: [5, 5, 0, 0], label: { show: true, position: 'top', rotate: '30', color: '#999999', formatter: '¥{c}' }, color: (params) => { return this.tionData.length-1 === params.dataIndex ? '#E8B003' : '#E1E1E1'; } } } } ] }) }, // 请求后台接口 aaa(data) { if(data){ this.noData = false this.$nextTick(()=> { this.statistics() }) } else { this.noData = true this.statistics() } } }, mounted () { this.statistics() }}</script>4.总结 ...

June 18, 2019 · 1 min · jiezi

常见的CSS预处理器之Less初体验

CSS预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为CSS增加了一些编程的特性,将CSS作为目标生成文件,然后开发者就只要使用这种语言进行编码工作。 简单来说,CSS预处理器用一种专门的编程语言,进行Web页面样式设计,然后再编译成正常的CSS文件,以供项目使用。 CSS预处理器的技术现在已经很成熟了,而且也出现了各种不同的 CSS 预处理器语言,但是呢不可能一一列出,面面俱到,这篇文章呢,主要是介绍一下比较常见的CSS预处理器语言之一之 Less初体验。 LessAlexis Sellier与2009年设计LESS的第一个版本是用Ruby编写的,在后来的版本中,它被JavaScript替代了。Less是一门CSS预处理语言,扩充了 css语言,增加了诸如变量、混合(mixin)、函数等功能,让 css 更易于维护,方便制作主题。 关于Less的基本使用,我们需要从嵌套、混合、变量、函数以及引入这几个方面来一一认识。 1 Less的安装使用和编译:引用Less,全局安装 npm install less -g新建一个index.html文件和main.less,在index.html 中引入main.css,然后输入下面语句自动编译成main.css lessc main.less main.css2 Less 的基本语法嵌套在 css 中父子元素的写法通常如下: .container { padding: 0;}.container .header { background-color: red;}通过Less 写法如下,父子嵌套关系一目了然。也就是下面的代码编译就成了上面的css语法。 .container { padding: 0; .header { background-color: red; }}伪类伪类的写法,在 css 中写法如下: #header :after { content: " "; display: block; font-size: 0; height: 0; clear: both; visibility: hidden;}在less 引入可以用一个符号 & 代替主类 #header;&就代表了上一层的类名。 ...

June 17, 2019 · 2 min · jiezi

js内功修炼之九阳神功原型链

写在前面如果说JavaScript是一本武学典籍,那么原型链就是九阳神功。在金庸的武侠小说里面,对九阳神功是这样描述的:"练成「九阳神功」后,会易筋洗髓;生出氤氲紫气;内力自生速度奇快,无穷无尽,普通拳脚也能使出绝大攻击力;防御力无可匹敌,自动护体,反弹外力攻击,成就金刚不坏之躯;习者速度将受到极大加成;更是疗伤圣典,百病不生,诸毒不侵。至阳热气全力施展可将人焚为焦炭,专门克破所有寒性和阴毒内力。"可见其功法强大。那么,如何修炼好js中的九阳神功呢?真正的功法大成的技术是从底层上去理解,那种工程师和码农的区别就在于对底层的理解,当你写完一行代码,或者你遇见一个bug,解决的速度取决于你对底层的理解。什么是底层?我目前个人的理解是“在你写每一行代码的时候,它将如何在相应的虚拟机或者V8引擎中是如何运行的,更厉害的程序员甚至知道每条数据的操作是在堆里面还是在栈里面,都做到了然于胸,这是JavaScript的内功最高境界(反正我现在是做不到,我不知道你们能不能,哈哈哈)”。 一、Js原型链的简单理解**理解原型链之前首先要了解js的基本类型和引用类型:1、基本类型 基本类型有Undefined、Null、Boolean、Number 和String。这些类型在内存中分别占有固定大小的空间,他们的值保存在栈空间, 我们通过按值来访问的。 基本类型:简单的数据段,存放在栈内存中,占据固定大小的空间。2、引用类型引用类型,值大小不固定,栈内存中存放地址指向堆内存中的对象。是按引用访问的。存放在堆内存中的对象,变量实际保存的是一个指针,这个指针指向另一个位置。每个空间大小不一样,要根据情况开进行特定的分配。当我们需要访问引用类型(如对象,数组,函数等)的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。** js的原型链说简单也简单,说难也难。 首先说明:函数(Function)才有prototype属性,对象(除了Object)拥有_proto_.原型链的顶层就是Object.prototype,而这个对象的是没有原型对象的。可以在Chrome输入: Object.__proto__输出的是: ƒ () { [native code] }可以看到这个没有.prototype属性。 二、prototype和_proto_的区别我们知道原型是一个对象,其他对象可以通过它实现属性继承。 var a = {};console.log(a.prototype); //undefinedconsole.log(a.__proto__); //Object {}var b = function(){}console.log(b.prototype); //b {}console.log(b.__proto__); //function() {} /*1、字面量方式*/var a = {};console.log(a.__proto__); //Object {}console.log(a.__proto__ === a.constructor.prototype); //true/*2、构造器方式*/var A = function(){};var a = new A();console.log(a.__proto__); //A {}console.log(a.__proto__ === a.constructor.prototype); //true/*3、Object.create()方式*/var a1 = {a:1}var a2 = Object.create(a1);console.log(a2.__proto__); //Object {a: 1}console.log(a.__proto__ === a.constructor.prototype); //false(此处即为图1中的例外情况) ...

June 14, 2019 · 2 min · jiezi

iconfont在react中完整使用教程

hello,各位小伙伴们,很久没写文章了。突然要自己搭建项目了,项目中对于阿里巴巴iconfont的使用,大家都清楚吗? 第一步:将图标加入购物车 第二步:将图标下载到本地,将如下文件放置在react项目中assets目录下 第三步:导入iconfont.css到项目目录,鄙人踩坑点在此。查阅部分文件,找到相关资料,发现是在纯html页面中导入是完全OK的。<link rel="stylesheet" type="text/css" href="iconfont.css">但是请注意,咱们将静态资源放置在src目录下,public中的index.html不可采用。于是,正确做法如下:在src文件下的index.js或者app.js等文件中写入如下语句即可。import './assets/fonts/iconfont.css'; 第四步:介绍使用方法 unicode: <i className="iconfont">&#xe72e;</i>font-class:<i class="iconfont icon-gouwuche"></i>symbol:待我研究去吧。。。备注:如果发现页面没有更新,可以重启一下服务。以上就是关于iconfont的介绍了,大家可以踊跃查阅资料,在此希望能够给到小伙伴们一些帮助呀!

June 10, 2019 · 1 min · jiezi

vuecli配置全局sassless变量

一、全局配置less 1.下载插件**vue add style-resources-loader**vue add pluginName 是vue-cli3提供的。vue add 是用yarn安装插件的, yarn源的问题有可能导致失败。如果上面安装失败的话,就分别安装 style-resources-loader 和 vue-cli-plugin-style-resources-loader(前提是已经安装过 less less-loader) // 没有出错的话,可以无视这里 npm i style-resources-loader vue-cli-plugin-style-resources-loader -D 或 yarn add style-resources-loader vue-cli-plugin-style-resources-loader -D** 第二步配置vue.config.js const path = require("path"); module.exports = { ... pluginOptions: { "style-resources-loader": { preProcessor: "less", patterns: [ //这个是加上自己的路径, //注意:试过不能使用别名路径 path.resolve(__dirname, "./src/assets/variable.less") ] } } ... }或者使用官网的自动导入在chainWebpack中引入https://cli.vuejs.org/zh/guid... 二、全局配置sass(直接配置vue.config.js) 注意:官网独爱sass,这种loader的形式只有sass才合适用,其他的(less、stylus)都会报错。 module.exports = { ... css: { loaderOptions: { sass: { // @是src的别名 data: ` @import "@/assets/variable.scss"; ` } } } ... }

June 5, 2019 · 1 min · jiezi

2019年百度云计算市场突变状况

时间到了2019年六月份,对于云计算市场的变动,企业和站长都敏锐感觉到云服务器市场的变动,我们的企业推广其中最主要的就是百度,可是六月份百度搜索总裁向海龙辞职,下面高管也陆续离职了4个,百度搜索公司带来的盈利占到整个百度的七成以上.去年同时期,百度盈收几十亿元,今年已经负几十亿了,前两年还说BAT,然后现在百度市值不及阿里和腾讯的十分之一了. 百度2019年一过就各种推广自己的云服务器,结果买的人很少,推广还是看之前的三板斧,打电话、竞价、硬推,这些办法已经过时了,当阿里云每年的盈利都在涨幅,腾讯云依托自己新媒体扛把子身份,一步步扩张小程序时,百度还在玩抄袭、垄断、嫁接等忽悠人.百度的辉煌要过去了,云服务器计算领域要迎来新的变革,随着5G时代来临,总带宽变大,相对的我们的云服务器也将享受红利,更大的带宽,随着AMD和intel在服务器处理器市场大战,将来的硬件采购也将会大幅度便宜,这是要爆发的前期呀.对于你同时购买多个厂商的云服务器,那么管理这些云服务器就需要好的方式,采用SAAS化云平台就是最完美的解决方式,旗鱼云梯这个互联网产品.推出后受到了企业和个人站长的欢迎,能够实现多个云服务商主机管理在一个平台下,同时批量实现管理,一键web环境搭建,LAMP和LNMP的免费服务器,一键建立网站,免费的SSL的https服务,各厂商CMS系统支持,安全稳定的WAF防火墙.只有一流的团队,才能够实现这样的革命进步,旗鱼云梯是2019年服务器集群管理的新篇章,是企业和个人站长的最好集群化平台.

June 5, 2019 · 1 min · jiezi

2019年3月所遇知识点整理

*注:本文章是在工作过程中所接触的知识点的整理,涉及的东西比价杂乱,如有错误之处,欢迎纠错与指导一, 前端项目性能优化二, Vuex数据页面刷新丢失问题三, Vue-Router模式、钩子四, mini-css-extract-plugin五, 删除元素所有子节点六, Vue调试器vue-devtools安装七, Vue项目webpack打包部署到Tomcat八, css布局总结(CSS实现,头部高度固定,主体高度铺满剩余高度;主体左侧固定宽度,右侧铺满剩余宽度,八种创建等高列布局)九, webpack开发和生产两个环境的配置详解十, htmlWebpackPlugin的minify各配置项用法说明十一, 前端存储十二, Object判断是否为对象和对象的.length十三, http请求十四,css mix-blend-mode 混合模式十五,JS引擎的执行机制

June 4, 2019 · 1 min · jiezi

2019年6月所遇知识点整理

*注:本文章是在工作过程中所接触的知识点的整理,涉及的东西比价杂乱,如有错误之处,欢迎纠错与指导一, 前端与网关二, 字符串的处理

June 4, 2019 · 1 min · jiezi

gulp40-搭建less编译环境

gulp4.0 搭建less编译环境

June 3, 2019 · 1 min · jiezi

记录移动端开发1像素边框问题-stylus代码转成less

需求:需要解决1像素问题: 物理像素是设备像素的2倍,在手机上预览,1px边框会变成2px参考cube-ui的mixin.styl 中1像素解决方案,如下: border-1px($color = #ccc, $radius = 2PX, $style = solid) position: relative &::after content: "" pointer-events: none display: block position: absolute left: 0 top: 0 transform-origin: 0 0 border: 1PX $style $color border-radius: $radius box-sizing border-box width 100% height 100% @media (min-resolution: 2dppx) width: 200% height: 200% border-radius: $radius * 2 transform: scale(.5) @media (min-resolution: 3dppx) width: 300% height: 300% border-radius: $radius * 3 transform: scale(.333)问题:我们的项目中所有样式文件都是用less写的,而且就用一个mixin.styl 中的这个方法而已 ...

May 24, 2019 · 1 min · jiezi

流程图循环怎么画流程图有现成的模版吗

流程图(Flow Chart)是一种常见的工作图表。在企业中,流程图主要用于说明某一个过程,该过程可以是生产线上的工艺流程,也可用于表达完成任务所需的步骤。另外,流程图也常用于表示算法的思路,可以有效解决汇编语言和早期的BASIC语言环境中的逻辑问题。 运用流程图的时候,需要使用一些标准符号代表某些类型的动作。如用菱形框表示判定,用方框表示流程。具体的表示方法整理如下: 流程图的分类 流程图的种类多达10种,归纳整理如下: 但是根据使用的场景不同,大致可划分为7个类别,分别是商业流程图、跨职能流程图、数据流程图、事件管理流程图、IDEF图、工作流程图、SDL图。 商业流程图:又叫做业务流程图,是一种描述系统内部各人员与各单位的业务关系、管理信息以及作业顺序。它是一种物理模型,借助于此,分析人员可以找出业务流程中的不合理流向,方便优化。 跨职能流程图:可显示进程中各个步骤之间的相互关系,也能显示执行它们的职能单位。跨职能流程图按照分布的方向不同,可以分为水平跨职能流程图和垂直跨职能流程图。当跨职能流程图用于UML的时候,又被叫作泳道图。 数据流程图:一种描述系统数据流程的工具,可以将抽象的数据独立出来,通过特定的图形符号来展示信息的来龙去脉和实际流程。这是一种能描绘信息系统逻辑模型的重要工具。 事件管理流程图:这是IT服务管理中重要的流程,当一个事件被输入的时候,服务台的操作人员会依据事件的影响范围和紧急程度,对其进行初步的归类评估。 IDEF图:IDEF,即集成计算机辅助制造,一种用于描述企业内部运作的一套建模方法。IDEF图是用于表达这种建模方法的图示。 工作流程图:通过适当的符号来记录工作事项,能够反映一个组织系统中各项工作之间的逻辑关系。工作流程图可以帮助管理者了解实际工作活动,并去除工作中多余的工作环节,进而提升工作效率。 SDL图:使用说明和规范的语言(SDL)为通信、电信系统以及网络创建图表。 流程图的画法 了解流程图的类别后,那又该如何绘制我们所需的流程图呢?下面我们以亿图图示软件为例,介绍如何快速创建专业的流程图。 第1步:打开软件,“新建”-“流程图”,然后根据自己的需求,选择绘图模板。比如选择基础流程图,双击鼠标即可打开绘图面板。值得一提的是,亿图图示里除了模板,还有对应的例子,如果是新手绘图,可以借鉴流程图例子帮助自己加深认识。 第2步:从左侧符号库里选择所需的图形符号,并拖动至画布中。并依次添加,直至完毕。 第3步:使用连接线符号,对各个图形符号进行连接。亿图图示软件的连线十分便捷,鼠标点击需要连线的两端,即可生成直角连线。如果连线的位置不满意,也可以通过鼠标拖动线条的方式进行修改。 第4步:最后再添加文字和注释,一份完整的流程图即可大功告成。另外,亿图软件还有丰富的背景图案以及标题栏样式可以选择,这将大大提升流程图的颜值。 特别注意: 亿图图示软件拥有一键更换样式的功能,无需自己搭配,方便省事。 绘制完成的作品,可以导出图片、Html、Word、PPT、Excel等多种格式;也可以将作品保存在亿图云,不担心丢失的问题。 软件还有打印功能,即见即所得的打印方式,让流程图的存在不再只是虚拟化。 支持跨平台操作系统,不论是window、Mac还是Linux,都可以安装使用亿图软件。 多类型的图形图表设计软件,不仅可以绘制流程图,还能绘制思维导图、组织架构图、户型图、信息图等260种图示。

May 15, 2019 · 1 min · jiezi

栅格GRID-未来可期-更便捷的布局方式

栅格布局组成: wrapper(父元素)和 items(子元素)。 父 属性设置: display: grid;或display: inline-grid; /*网格模式*/grid-template-columns: 40px auto 50px; /*子元素列的宽度*/grid-template-rows: 25% 100px auto; /*子元素行的高度 设置则定高 不设则自适应*//*他们俩可设置是px 百分比 也可以自动伸缩auto*/grid-gap: 5px; /*网格区域的间距 可设置单一间距 也可以上下一个间距左右一个间距 。 不支持上右下左四个值写法*/子 属性设置:不设置一下值是 默认均分。 更多变化 需要用到⤵️ grid-row-start: 2; /*行 的开始*/grid-row-end: 3; /*行 的结束*//*上面两句可简写成 grid-row: 2 / 3;*/grid-column-start: 1; /*列 的开始*/grid-column-end: 4; /*列 的结束*//*同理上面两句可简写成 grid-column: 1 / 4;*/------------更简洁写法-----------------------grid-row-start: 2; /*行 的开始*/grid-row-end: 3; /*行 的结束*/grid-column-start: 1; /*列 的开始*/grid-column-end: 4; /*列 的结束*//*上面四句可简写成*/grid-area:2/1/3/4; /*顺序grid-row-start,grid-column-start,grid-row-end,grid-column-end。*/ 理解row和columns的排序 基本就理解grid的用法例如:grid-row-start: 2; 指的是从上到下第二条线开始grid-column-start: 1; 指的是从左到右第一条线开始 ...

May 8, 2019 · 2 min · jiezi

SCSS-日常用法

SCSS 日常用法本文是以自己的理解起的结构,要看详细的帮助文档,参阅这里:https://sass-lang.com/documen...你需要了解的less 和 sass 是两种 css 预编译语言,其目的是为了更快、更结构的编写 css 文件,是一种强大的 css 编译语言,都能使用 变量、运算符、判断、方法等等。 scss 与 sass 的区别(这里先不讲 less ): 先有的 sass 后有的 scssscss 需要大括号{}和分号;sass 什么都不用直接裸奔感觉 sass 不如 scss 严谨,裸奔太狂野了,所以我们选用 scss, 看个小例子写一个 .btn 类并支持 :hover :active 样式 css .btn {/* btn 初始样式 */}.btn:hover{/* :hover 样式 */}.btn:active{/* :active 样式 */}scss .btn{// btn 初始样式 &:hover{ // hover 样式 } &:active{ // active 样式 }}在scss, sass, less 中 & 都代指父类上面这个例子中的 & 代指 .btn可以看出 scss 的结构要比 css 清晰,并且写的也要更少。下面的 scss 在使用中就会生成上面的 css。而这还只是皮毛,保证你用过 scss 之后就不会再用 css 写样式了。 ...

May 1, 2019 · 3 min · jiezi

续命之移动适配

最近看了好多移动适配的资料,整理了一下以作后续开发少出bug(哈哈~)移动端布局,为了适配各种大屏手机,目前最好用的方案莫过于使用相对单位rem。基于rem的原理,我们要做的就是: 针对不同手机屏幕尺寸和dpr动态的改变根节点html的font-size大小(基准值)。这里我们提取了一个公式(rem表示基准值)rem = document.documentElement.clientWidth * dpr / 10 如何转换成rem单位呢?公式如下:rem = px / 基准值; rem方案一首先,先说一个常识,浏览器的默认字体高都是16px。使用%单位方便使用css中的body中先全局声明font-size=62.5%,这里的%的算法和rem一样。因为100%=16px,1px=6.25%,所以10px=62.5%,这是的1rem=10px,所以12px=1.2rem。px与rem的转换通过10就可以得来,很方便了吧!使用方法注意,rem是只相对于根元素htm的font-size,即只需要设置根元素的font-size,其它元素使用rem单位设置成相应的百分比即可;例子: 一般情况下,是这样子使用的 移动端做适配的时候,可以使用这样的方法 方案二 js中rem是怎么用的首先得让文字和标签的大小随着屏幕的尺寸做变化 等比缩放,然后在把计算出的值赋给html 这样当前窗口的字体就能获取到了,然后我们再设置窗口大小改变的情况,其实也就是加一个窗口改变的监听事件onresize。发生了onresize,就重新计算该窗口下根目录字体的大小。 方案三 从dpr维度的适配上文也提到了dpr那么什么是dpr呢 通俗点讲就是花了200px的长宽来渲染CSS里面定义的100px的长宽而样式pixels和设备pixels的比值,就是dpr,即Device Pixel Ratio<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><style> .box1{ height: 5rem; width: 5rem; background-color:red; }</style></head><body> <div class="box1"></div></body><script> var dpr = window.devicePixelRatio;//当前显示设备的物理像素分辨率与CSS像素分辨率的比值 var meta = document.createElement('meta'); // dpr meta.setAttribute('content', 'initial-scale=' + 1 / dpr + ', maximum-scale=' + 1 / dpr + ', minimum-scale=' + 1 / dpr + ', user-scalable=no'); document.getElementsByTagName('head')[0].appendChild(meta); ...

April 28, 2019 · 2 min · jiezi

React配置less与antd定制主题

一、配置less在配置less之前,我使用create-react-app,得到React版本为^16.8.6。 安装依赖并解构目录:(可以在命令前加sudo确保不会出现权限问题)yarn add babel-plugin-import 或 npm install babel-plugin-importyarn less-loader 或 npm install less-loaderyarn eject 或 npm run eject解构后,我得到的webpack版本为4.28.3,config文件夹长这样: 于是,打开webpack.config.js修改配置:在第42行附近修改代码为: // style files regexesconst cssRegex = /\.css$/;const cssModuleRegex = /\.module\.css$/;const sassRegex = /\.(scss|sass)$/;const sassModuleRegex = /\.module\.(scss|sass)$/;const lessRegex = /\.less$/; //新增const lessModuleRegex = /\.module\.less$/; //新增在第327行附近修改代码为: oneOf: [ { ...//其他配置 }, ...//其他配置 //配置less-loader(新增) { test: lessRegex, exclude: lessModuleRegex, use: getStyleLoaders({ importLoaders: 2 }, 'less-loader'), }, { test: lessModuleRegex, use: getStyleLoaders( { importLoaders: 2, modules: true, getLocalIdent: getCSSModuleLocalIdent, }, 'less-loader' ), }, //EndOf配置less-loader(新增) ...//其他配置]二、配置antd定制主题修改package.json: ...

April 25, 2019 · 1 min · jiezi

react配置less,并使用less module(webpack.config.js配置)

网上看了很多配置,最后才发现create-react-app2.0后就不用eject就可以使用css module特性,那么less仿照css的配置即可1.css module的使用将CSS文件名为[filename].module.cssimport styles from './index.module.css';2.配置less暴露webpack配置文件cnpm run eject 安装lessless-loader依赖 npm install less less-loader --save-dev修改webpack.config.js文件配置,一共修改三处第一处:增加定义变量```const cssRegex = /\.css$/;const cssModuleRegex = /\.module\.css$/;const sassRegex = /\.(scss|sass)$/;const sassModuleRegex = /\.module\.(scss|sass)$/;const lessRegex = /\.less$/;const lessModuleRegex = /\.module\.less$/;```第二处:仿照css配置less```{ test: cssRegex, exclude: cssModuleRegex, use: getStyleLoaders({ importLoaders: 1, sourceMap: isEnvProduction && shouldUseSourceMap, }), // Don't consider CSS imports dead code even if the // containing package claims to have no side effects. // Remove this when webpack adds a warning or an error for this. // See https://github.com/webpack/webpack/issues/6571 sideEffects: true, }, // Adds support for CSS Modules (https://github.com/css-modules/css-modules) // using the extension .module.css { test: cssModuleRegex, use: getStyleLoaders({ importLoaders: 1, sourceMap: isEnvProduction && shouldUseSourceMap, modules: true, getLocalIdent: getCSSModuleLocalIdent, }), }, // Opt-in support for SASS (using .scss or .sass extensions). // By default we support SASS Modules with the // extensions .module.scss or .module.sass { test: lessRegex, exclude: lessModuleRegex, use: getStyleLoaders({ importLoaders: 1, sourceMap: isEnvProduction && shouldUseSourceMap, }), // Don't consider CSS imports dead code even if the // containing package claims to have no side effects. // Remove this when webpack adds a warning or an error for this. // See https://github.com/webpack/webpack/issues/6571 sideEffects: true, }, // Adds support for CSS Modules (https://github.com/css-modules/css-modules) // using the extension .module.css { test: lessModuleRegex, use: getStyleLoaders({ importLoaders: 1, sourceMap: isEnvProduction && shouldUseSourceMap, modules: true, getLocalIdent: getCSSModuleLocalIdent, }), },```第三处:修改getCSSModuleLocalIdent函数内部,增加less![图片描述][2]3测试是否安装成功建立以module.less为结尾的less文件 ...

April 22, 2019 · 2 min · jiezi

less常用技巧

本文主要是记录自己日常工作中用到过的一些less小技巧1. 组件库主题定制一般组件库的样式编写都会为使用者设计一些主题样式更换方案,我这里根据自己对主流组件库antd和iview的研究,总结出这两类:iview引入主题样式,复写@import ‘~iview/src/styles/index.less’;// Here are the variables to cover, such as:@primary-color: #1B88EE;antd通过less-loader的modifyVars注入主题变量rules: [{ test: /.less$/, use: [{ loader: ‘style-loader’, }, { loader: ‘css-loader’, // translates CSS into CommonJS }, { loader: ’less-loader’, // compiles Less to CSS options: { modifyVars: { ‘primary-color’: ‘#1B88EE’, }, javascriptEnabled: true, },}], //注意 less-loader 的处理范围不要过滤掉 node_modules 下的 antd 包。所以在给公司定制组件库的时候我们可以使用这两种方法来给使用者定制主题,当然了,我们设计的时候最好和主流框架的变量名保持一致,使得使用者更好上手。@primary-color: #1B88EE; // 全局主色@link-color: #1B88EE; // 链接色@success-color: #4FC7AF; // 成功色@warning-color: #F8AC59; // 警告色@error-color: #F95355; // 错误色@font-size-base: 14px; // 主字号@text-color: rgba(0, 0, 0, .65); // 主文本色@text-color-secondary : rgba(0, 0, 0, .45); // 次文本色@disabled-color : rgba(0, 0, 0, .25); // 失效色@border-radius-base: 4px; // 组件/浮层圆角@border-color-base: #d9d9d9; // 边框色@box-shadow-base: 0 2px 8px rgba(0, 0, 0, .15); // 浮层阴影2. 给项目设置常用样式common.less不知道大家在实际开发中有没有遇到过为了一个padding或margin或fontsize而常常需要多写一层class的情况。.loop(20);.loop(@n, @i: 0) when (@i =< @n) { @size: @i*2; .pt-@{size} { padding-top: unit(@size, px) !important; } .pr-@{size} { padding-right: unit(@size, px) !important; } .pb-@{size} { padding-bottom: unit(@size, px) !important; } .pl-@{size} { padding-left: unit(@size, px) !important; } .mt-@{size} { margin-top: unit(@size, px) !important; } .mr-@{size} { margin-right: unit(@size, px) !important; } .mb-@{size} { margin-bottom: unit(@size, px) !important; } .ml-@{size} { margin-left: unit(@size, px) !important; } .fs-@{size} { font-size: unit(@size, px) !important; } .loop(@n, (@i + 1));} // e.g. pt-2 pt-16 pt-40 fs-16 fs-24等等把以上这段加到通用less里后,如果有一些特殊的边距或字体就可以直接写class=“mb-20"这样了,可以省去一些功夫多写个不必要的class,当然常用的width或height之类的都可以通过when循环解决,需要注意的less没有if-else判断,所有的判断也都是通过when关键字来解决。 ...

April 20, 2019 · 1 min · jiezi

create-react-app使用less最详细说明 2019-04-13

描述创建步骤和官网一直,大家可以查看官网,下面简单列举下.创建项目npx create-react-app my-appcd my-app/eject出配置文件npm run eject或者yarn eject安装lessless和less-loader都要安装。less是支持less语法的,less-loader是webpack使用来编译less的。npm install less less-loader –save配置webpack.config.js修改config/webpack.config.js新增less配置变量const cssRegex = /.css$/;const cssModuleRegex = /.module.css$/;const sassRegex = /.(scss|sass)$/;const sassModuleRegex = /.module.(scss|sass)$/;const lessRegex = /.less$/; // 新增less配置const lessModuleRegex = /.module.less$/; // 新增less配置,这个其实不配置也行增加module下面rule规则,可以copy cssRegex或者sassRegex的配置。{ test: sassModuleRegex, use: getStyleLoaders({ importLoaders: 2, sourceMap: isEnvProduction && shouldUseSourceMap, modules: true, getLocalIdent: getCSSModuleLocalIdent }, “sass-loader” )}, { test: lessRegex, exclude: lessModuleRegex, use: getStyleLoaders({ importLoaders: 1,// 值是1 modules: true, // 增加这个可以通过模块方式来访问css sourceMap: isEnvProduction && shouldUseSourceMap }, “less-loader” ), sideEffects: true}, // 这个测试删了也不影响{ test: lessModuleRegex, use: getStyleLoaders({ importLoaders: 1, sourceMap: isEnvProduction && shouldUseSourceMap, modules: true, getLocalIdent: getCSSModuleLocalIdent }, “less-loader” )},// “file” loader makes sure those assets get served by WebpackDevServer.需要注意一下几个地方:1.lessRegex中importLoaders的值为1当然这个是2也能使用,但是它的值是根据lessRegex变量后面正则中匹配的loader数来决定的,比如const cssRegex = /.css$/只是处理css一种类型的文件,那应该就是1;const sassRegex = /.(scss|sass)$/;对应的是scss和sass两种类型,那就应该是2.2.lessRegex的use中增加modules配置modules可以不设置,不设置的话,less只能通过字符串名的方式使用,比如定义了一个.title,引用时import ‘./index.less’,使用时:<div className=“title”></div>如果需要通过模块的方式调用,则需要把modules设置成true,就可以通过styles.title方式使用了。import styles from ‘./index.less’,使用<div className={styles.title}></div>第二种配置方式可以不增加新的变量,把css的配置包含lessconst cssRegex = /.(css|less)$/; //增加lessconst cssModuleRegex = /.module.(css|less)$/;{ test: cssRegex, exclude: cssModuleRegex, use: getStyleLoaders({ importLoaders: 2,// 改成2 modules: true,//使用模块方式访问样式 sourceMap: isEnvProduction && shouldUseSourceMap }, “less-loader” //增加loader ), // Don’t consider CSS imports dead code even if the // containing package claims to have no side effects. // Remove this when webpack adds a warning or an error for this. // See https://github.com/webpack/webpack/issues/6571 sideEffects: true}解决了你的问题,请点赞和收藏给点鼓励,有问题请留言。 ...

April 13, 2019 · 1 min · jiezi

less学习小记

什么是Less?css的Less好比是js的Jquery,可以让人们更方遍快捷的使用css,使css代码更简洁,可以减少重复的代码,减少开发人员的工作量。 Less CSS是一种动态样式语言,属于CSS预处理语言的一种,它使用类似CSS的语法,为CSS赋予了动态语言的特性,如变量、继承、运算、函数等,更方便CSS的编写和维护Less和Sass的区别Less和Sass的主要不同就是他们的实现方式:Less是基于JavaScript,所以,是在客户端处理的。Sass是基于Ruby的,然后是在服务器端处理的。 其实也有一个服务器端的LESS版本。在服务器上安装LESS的最简单的办法就是使用Node Package Manager (NPM,一看就知道是基于Node.js的)SASS和LESS在变量作用域上也有明显差别。LESS具有全局变量,而SASS暂时不具有全局变量的概念。SASS比LESS更完善的点还在于SASS能通过@function的方式编辑函数;通过@for循环或者@each循环对数据进行循环;通过@if else对数据进行判断Less的学习注释 less中有两种注释://和//。使用//的注释是会被编译进css文件的,而使用//的注释不会被编译进css文件。 由于我们应该一般编写和维护less文件,所以我们一般采用第二种注释,无需将注释编译进css文件。变量 less中使用@声明一个变量,和一般程序语言不同的是,@符号与变量之间不能有空格 变量的使用: //less文件 @myWidth : 200px; @myHeight : 500px; #main { width: @myWidth; height: @myHeight; background-color: yellowgreen; }混合将less写法与常规的css写法进行混合书写 //less文件 @charset “utf-8”; @myWidth : 200px; @myHeight : 200px; #main { width: @myWidth; height: @myHeight; background-color: yellowgreen; .border } .border { border:3px solid pink }可以带参数,设置默认值://less .border(@mywidth: 4px){ border: @mywidth solid green;}.mybox { .border(5px);}//css.mybox { border: 5px solid green;}4.匹配模式 // 根据不同的参 数可以匹配不同的样式: .pos(r) { position:relative; } .pos(a) { position:absolute; } .pos(f) { position:fixed; } .pipei { width:200px; height:200px; background-color:green; .pos(f); //.pos(r) .pos(a) 传入不同的参数,实现不同的定位方式 }5.运算less中可以实现运算,任何数字、颜色或者变量都可以参与运算(+ - * /),运算应该被包裹在括号中//less.border(@mywidth:4px){ border: @mywidth + 5px solid green; //这里的单位可以省略,但是两者必须有一个带单位}.mybox { .border();}//css.mybox { border: 4px solid green;}6.嵌套嵌套是less中非常有用、高效的语法//less#list { width: 600px; margin: 30px auto; list-style: none; padding: 0; li { height: 30px; line-height: 30px; background-color: pink; margin-bottom: 5px; a { float: left; // 伪类选择器 &:hover { font-size:20px; } } span { float: right; } }}7.arguments参数 有时候我们不想单个操作参数,可以使用@argemunts操作参数。//less.border_arg(@w:30px,@c:red,@xx:solid){ border:@arguments;}.test_arguments{ .border_arg();}//css.test_arguments { border: 30px red solid;}8.避免编译有时候我们需要输出一些不正确的css语法或者使用一些less不认识的专有语法,要输出这样的值我们需要使用~““将语法包裹起来,语法放在双引号或者单引号中间。从而实现不让less编译该段代码: ...

April 9, 2019 · 1 min · jiezi

Cutterman - 最好用的切图工具

软件描述Cutterman是一款运行在photoshop中的插件,能够自动将你需要的图层进行输出, 以替代传统的手工 “导出web所用格式"以及使用切片工具进行挨个切图的繁琐流程。 它支持各种各样的图片尺寸、格式、形态输出,方便你在pc、ios、Android等端上使用。它不需要你记住一堆的语法、规则,纯点击操作,方便、快捷,易于上手。下载地址Cutterman更详细的介绍和下载使用方法安装后重启PS窗口->扩展功能->Cutterman (勾选)点击需要导出的图层和选择路径,直接导出对应格式(.PNG24 .JPEG .GIF )切片PS-点击要导出使用切片的场景。例如web,选择导出的格式

April 9, 2019 · 1 min · jiezi

Javascript如何与Sass,Less,Css之间共享变量?

原博文地址,此博文首次发于csdn,原创前段时间遇到网站换肤的需求,本想挺简单的,直接用 Sass 或者 Less 设置变量就好了,结果导致的问题就是 js 中设置的样式得单独设置,好麻烦。本文章代码gitHub地址 https://github.com/l-x-f/variables-css-less-sass-js 这个时候如果能让样式文件和 js 文件实现变量共享,那这个问题就解决了。查了好多资料,最终的解决方案如下:1.原理介绍:通过 webpack 和 css module,我们可以在 js 中使用样式 Sass,Less,Css 文件中定义的变量。2.环境: node: v8.10.0 vue-cli:3.5.3 3.package.json ( scss和less及其loader等先安装,vue-cli:3.5.3 下webpack已配置){ “name”: “Javascript 如何 Sass,Less,Css 之间共享变量”, “version”: “0.1.0”, “private”: true, “scripts”: { “serve”: “vue-cli-service serve”, “build”: “vue-cli-service build”, “lint”: “vue-cli-service lint” }, “dependencies”: { “core-js”: “^2.6.5”, “vue”: “^2.6.6”, “vue-router”: “^3.0.1”, “vuex”: “^3.0.1” }, “devDependencies”: { “@vue/cli-plugin-babel”: “^3.5.0”, “@vue/cli-plugin-eslint”: “^3.5.0”, “@vue/cli-service”: “^3.5.0”, “babel-eslint”: “^10.0.1”, “eslint”: “^5.8.0”, “eslint-plugin-vue”: “^5.0.0”, “less”: “^3.9.0”, “less-loader”: “^4.1.0”, “node-sass”: “^4.9.0”, “sass-loader”: “^7.1.0”, “vue-template-compiler”: “^2.5.21” }}4.文件目录5.variables文件夹下代码(核心代码)css.css文件/* @value 定义变量,然后使用。@value bgcColor: red; 会导出@ 后面的变量,在:export {} 可以取到该变量,也可以导出他们在功能上等同于 ES6 的关键字export,即导出一个 js 对象。/@value bgcColor: red;@value fontSize: 10px;/ 这里可以直接使用.demo { background-color: bgcColor; font-size: fontSize;} // CSS Module 导出 :export { cssExportBgcColor: bgcColor;} /less.less文件@mainColor: #398bd0;@fontSize: 100px;// CSS Module 有一个:export关键字,它在功能上等同于 ES6 的关键字export,即导出一个 js 对象。:export { name: “less”; mainColor: @mainColor; fontSize: @fontSize;}scss.scss文件$primaryColor: #f4d020;$fontSize: 11px;// CSS Module 有一个:export关键字,它在功能上等同于 ES6 的关键字export,即导出一个 js 对象。:export { name: “scss”; primaryColor: $primaryColor; fontSize: $fontSize;}index.js文件import variablesScss from “./scss.scss”;import variablesLess from “./less.less”;import variablesCss from “./css.css”;// 导出变量export default { variablesScss, variablesLess, variablesCss};6.styles文件夹下代码(样式文件中使用变量)css-use.css文件@value variables: “../variables/css.css”; / 导入变量*/@value bgcColor, fontSize from variables;/* 取出变量*/.box { name: “css”; /* 此属性错误,仅用于区分,可忽略*/ background-color: bgcColor; font-size: fontSize;}less-use.less文件@import “../variables/less.less”;.box { name: “less”;/* 此属性错误,仅用于区分,可忽略*/ background-color: @mainColor; font-size: @fontSize; }scss-use.scss文件@import “../variables/scss.scss”;.box { name: “scss”; /* 此属性错误,仅用于区分,可忽略*/ background-color: $primaryColor; font-size: $fontSize; }7.main.js代码import Vue from “vue”;import App from “./App.vue”;Vue.config.productionTip = false;import variables from “./variables”;console.log(variables, “main-variables”);new Vue({ render: h => h(App)}).$mount("#app");8.App.vue文件代码<template> <div id=“app” class=“box”></div></template><script>// variables in jsimport variables from “./variables”;export default { name: “home”, components: {}, data() { return { variables: { …variables } }; }, created() { console.log(this.variables, “App-this.variables”); }};</script><!–css –><style lang=“css”>#app { height: 500px;}@import “./styles/css-use.css”;</style><!–scss –><style lang=“scss”>@import “./styles/scss-use.scss”;</style><!– less–><style lang=“less”>@import “./styles/less-use.less”;</style>9.最后的效果如图我们在js文件(或vue 文件)中取到样式变量,最后引用第三个资料中的一句话结束本文章环境之间共享变量是编程的圣杯参考资料http://www.ruanyifeng.com/blo…https://github.com/css-module...https://www.bluematador.com/b...https://github.com/css-module...https://github.com/css-module… ...

April 8, 2019 · 2 min · jiezi

程序 + 音乐: 我的自由钢琴开发历程

原文链接Hate 996? Come Here & Relax最近用Vue + Tone.js做了一款钢琴类web应用,名字定为自由钢琴(AutoPiano),人生如音乐,欢快且自由。此文权当作该项目的总结和分享项目简介自由钢琴(AutoPiano)是利用HTML5技术开发的在线钢琴应用,致力于为钢琴爱好者、音乐爱好者以及其他所有的创造者提供一个优雅、简洁的平台,在学习工作之余可以享受钢琴、音乐的美好。就类似于多年前Flash开发的钢琴游戏,自由钢琴只是换了H5的技术,同时支持了钢琴曲的自动播放功能。AutoPiano支持键盘按键和鼠标点击播放,同时琴键上会有按键和音名提示。另外,AutoPiano还有教学的功能,一种方式是快速入门,通过简易的谱子按键进行演奏,另一种是演奏示例,通过钢琴曲的自动播放来达到演示的目的。目前这两个功能都在持续完善中,如下图所示:体验地址: http://crystalworld.gitee.io/…项目地址: https://github.com/WarpPrism/…开发这样的应用需要乐理知识吗?当然。基本的乐理知识还是要知道的,比如 CDEFGAB 音名、五线谱、调式、节奏等等还是要懂一点的。篇幅所限,这里就不展开讨论了,推荐两个网站:https://www.bilibili.com/vide…https://www.cnblogs.com/devym…其他的就是编程知识了,以及如何将乐理知识转化为程序逻辑。AutoPiano目前采用的技术架构是vue框架 + tone.js。钢琴界面效果是怎么写的?可以用CSS或贴图。笔者这里直接用css实现了,考虑到钢琴有黑键和白键,且黑键和白键有序地排列成 7:5的模式,所以实现起来并不复杂。<div class=“piano-key-wrap”> <div class=“piano-key wkey” v-for=“note in Notes” :key=“note.keyCode” :data-keyCode = “note.keyCode” v-if=“note.type==‘white’” @click=“clickPianoKey($event, note.keyCode)"></div> <div class=“bkey-wrap bkey-wrap1”> <div class=“piano-key bkey” v-for=“note in Notes” :key=“note.keyCode” :data-keyCode = “note.keyCode” v-if=“note.type==‘black’ && note.id >= 36 && note.id <= 40” @click=“clickPianoKey($event, note.keyCode)"></div> </div></div>.piano-wrap { width: 90%; margin: 20px auto; .piano-key-wrap { width: 100%; background: @dark; overflow: hidden; position: relative; .wkey { display: inline-block; width: 2.775%; height: 100%; margin: 0 auto; background: linear-gradient(white 10%, rgb(251, 251, 251) 92%, rgb(220, 220, 220) 93%, white 97%); border: solid 1px @dark; border-radius: 0 0 5px 5px; position: relative; &:active { background: linear-gradient(#eee 10%, #ddd 60%, #bbb 93%, #ccc 97%); } } .wkey-active { background: linear-gradient(#eee 10%, #ddd 60%, #bbb 93%, #ccc 97%); } .bkey-wrap { width: 20%; height: 0; position: absolute; top: 0; } .bkey-wrap1 {left: 0;} .bkey-wrap2 {left: 19.5%;} .bkey-wrap3 {left: 39%;} .bkey-wrap4 {left: 58.3%;} .bkey-wrap5 {left: 77.7%;} .bkey { display: inline-block; width: 10%; height: 70%; background: linear-gradient(#000 10%, rgb(86, 86, 86) 85%, #000 90%); border-radius: 0 0 3px 3px; position: absolute; top: 0; overflow: hidden; &:active { background: linear-gradient(rgb(86, 86, 86) 10%, #000 90%, #222 100%); } } .bkey-active { background: linear-gradient(rgb(86, 86, 86) 10%, #000 90%, #222 100%); } .bkey:nth-child(1) {left: 9%;} .bkey:nth-child(2) {left: 23%;} .bkey:nth-child(3) {left: 50%;} .bkey:nth-child(4) {left: 65%;} .bkey:nth-child(5) {left: 79%;} }}codepen上也有很多这样的例子供参考,不一定采用上述实现:https://codepen.io/search/pen…相信只要合理地控制css变量和数值,大家能做出更好的 Piano 界面。如何实现单个音符的播放?实现音频播放,最简单的就是利用HTML5 中的 audio 标签,通过触发audio的play和pause方法,实现对音频的控制,笔者一开始就是这么实现的。// <div class=“audios-wrap” id=“audios-wrap”>// <audio src=”” id=“preloadAudio” ref=“preloadAudio”></audio>// </div>// 预先为每个音符都建立一个audio元素initAudioDom() { var vm = this for (let i = 0; i< vm.Notes.length; i++) { var note = vm.Notes[i] $(’.audios-wrap’).append(&lt;audio src='${note.url}' hidden='true' data-id='audio${i}' class='audioEle'&gt;); }},// 触发某个audio元素的播放playNote(url) { var vm = this if (!url || typeof url != ‘string’) return; var audios = $(’.audioEle’); for (let i = 0; i< audios.length; i++) { let audio = audios[i]; if (audio.src.indexOf(url) > -1) { var cloneAudioNode = audio.cloneNode() cloneAudioNode.play() cloneAudioNode.remove() break; } }}上述是我的第一种实现方式,即不同音符触发不同audio的播放。之后也许是出于好奇,尝试了 Tone.js,通过Tone.js + 内置采样器实现对音频播放更有效的控制,当然,其提供的很多复杂功能都还没用上。。。// 初始化合成器this.synth = SmapleLibrary.load({ instruments: “piano”}).toMaster()// 合成器触发音频释放playNote(notename = ‘C4’, duration = ‘2n’) { if (!this.synth) return this.synth.triggerAttackRelease(notename, duration);}嗯,现在的代码就符合音乐美学和代码美学了,美滋滋。当然笔者也期望Tone.js能快点完善中文文档,不然上手还是很吃力的,感兴趣的小伙伴可以先去其官网研究一番。关于钢琴曲的自动播放这一部分应该是开发整个应用最难的地方了,因为音乐或者说乐谱本身是相当复杂的,根据百度百科的描述,五线谱起源于希腊,历经上千年不断完善才成为现在的乐谱标准。而简谱的出现则要晚的多,但依然五脏俱全,可以说,简谱也不简单。笔者的实现思路是,以一种乐谱格式为载体,将乐谱转换为一种程序可识别的格式,然后导入到程序中进行播放,这种可识别格式如下所示,也是目前所采用的: { name: ‘小星星’, step: ‘C’, speed: ‘100’, playState: ‘’, mainTrack: [‘1(1)’,’ 1(1)’,’ 5(1)’,’ 5(1)’,’ 6(1)’,’ 6(1)’,’ 5(2)’,’ 4(1)’,’ 4(1)’,’ 3(1)’,’ 3(1)’,’ 2(1)’,’ 2(1)’,’ 1(2)’,’ 5(1)’,’ 5(1)’,’ 4(1)’,’ 4(1)’,’ 3(1)’,’ 3(1)’,’ 2(2)’,’ 5(1)’,’ 5(1)’,’ 4(1)’,’ 4(1)’,’ 3(1)’,’ 3(1)’,’ 2(2)’,’ 1(1)’,’ 1(1)’,’ 5(1)’,’ 5(1)’,’ 6(1)’,’ 6(1)’,’ 5(2)’,’ 4(1)’,’ 4(1)’,’ 3(1)’,’ 3(1)’,’ 2(1)’,’ 2(1)’,’ 1(2)’, ‘1<(1)’, ‘1<(1)’, ‘5<(1)’, ‘5<(1)’, ‘6<(1)’, ‘6<(1)’, ‘5<(2)’, ‘4<(1)’, ‘4<(1)’, ‘3<(1)’, ‘3<(1)’, ‘2<(1)’, ‘2<(1)’, ‘1<(2)’, ‘5<(1)’, ‘5<(1)’, ‘4<(1)’, ‘4<(1)’, ‘3<(1)’, ‘3<(1)’, ‘2<(2)’, ‘5<(1)’, ‘5<(1)’, ‘4<(1)’, ‘4<(1)’, ‘3<(1)’, ‘3<(1)’, ‘2<(2)’, ‘1<(1)’, ‘1<(1)’, ‘5<(1)’, ‘5<(1)’, ‘6<(1)’, ‘6<(1)’, ‘5<(2)’, ‘4<(1)’, ‘4<(1)’, ‘3<(1)’, ‘3<(1)’, ‘2<(1)’, ‘2<(1)’, ‘1<(2)’], backingTrack: [‘1>(0.5)’, ‘5>(0.5)’, ‘3>(0.5)’, ‘5>(0.5)’, ‘1>(0.5)’, ‘5>(0.5)’, ‘3>(0.5)’, ‘5>(0.5)’, ‘1>(0.5)’, ‘6>(0.5)’, ‘4>(0.5)’, ‘6>(0.5)’, ‘1>(0.5)’, ‘5>(0.5)’, ‘3>(0.5)’, ‘5>(0.5)’, ‘1>(0.5)’, ‘6>(0.5)’, ‘4>(0.5)’, ‘6>(0.5)’, ‘1>(0.5)’, ‘5>(0.5)’, ‘3>(0.5)’, ‘5>(0.5)’, ‘7>>(0.5)’, ‘5>(0.5)’, ‘2>(0.5)’, ‘5>(0.5)’, ‘1>(0.5)’, ‘5>(0.5)’, ‘3>(0.5)’, ‘5>(0.5)’, ‘1>(0.5)’, ‘3>(0.5)’, ‘5>(0.5)’,’ 1(0.5)’, ‘1>(0.5)’, ‘4>(0.5)’, ‘6>(0.5)’,’ 1(0.5)’, ‘1>(0.5)’, ‘3>(0.5)’, ‘5>(0.5)’,’ 1(0.5)’, ‘5>>(0.5)’, ‘7>>(0.5)’, ‘2>(0.5)’, ‘5>(0.5)’, ‘1>(0.5)’, ‘3>(0.5)’, ‘5>(0.5)’,’ 1(0.5)’, ‘1>(0.5)’, ‘4>(0.5)’, ‘6>(0.5)’,’ 1(0.5)’, ‘1>(0.5)’, ‘3>(0.5)’, ‘5>(0.5)’,’ 1(0.5)’, ‘5>>(0.5)’, ‘7>>(0.5)’, ‘2>(0.5)’, ‘5>(0.5)’, ‘1>(0.5)’, ‘5>(0.5)’, ‘3>(0.5)’, ‘5>(0.5)’, ‘1>(0.5)’, ‘5>(0.5)’, ‘3>(0.5)’, ‘5>(0.5)’, ‘1>(0.5)’, ‘6>(0.5)’, ‘4>(0.5)’, ‘6>(0.5)’, ‘1>(0.5)’, ‘5>(0.5)’, ‘3>(0.5)’, ‘5>(0.5)’, ‘1>(0.5)’, ‘6>(0.5)’, ‘4>(0.5)’, ‘6>(0.5)’, ‘1>(0.5)’, ‘5>(0.5)’, ‘3>(0.5)’, ‘5>(0.5)’, ‘7>>(0.5)’, ‘5>(0.5)’, ‘2>(0.5)’, ‘5>(0.5)’, ‘1>(0.5)’, ‘5>(0.5)’, ‘3>(0.5)’, ‘5>(0.5)’, ‘1(0.75)’, ‘5(0.25)’, ‘3(0.5)’, ‘5(0.5)’, ‘1(0.75)’, ‘5(0.25)’, ‘3(0.5)’, ‘5(0.5)’, ‘1(0.75)’, ‘6(0.25)’, ‘4(0.5)’, ‘6(0.5)’, ‘1(0.75)’, ‘5(0.25)’, ‘3(0.5)’, ‘5(0.5)’, ‘1(0.75)’, ‘6(0.25)’, ‘4(0.5)’, ‘6(0.5)’, ‘1(0.75)’, ‘5(0.25)’, ‘3(0.5)’, ‘5(0.5)’, ‘7>(0.75)’, ‘5(0.25)’, ‘2(0.5)’, ‘5(0.5)’, ‘1(0.75)’, ‘5(0.25)’, ‘3(0.5)’, ‘5(0.5)’, ‘1(0.75)’, ‘3(0.25)’, ‘5(0.5)’, ‘1<(0.5)’, ‘1(0.75)’, ‘4(0.25)’, ‘6(0.5)’, ‘1<(0.5)’, ‘1(0.75)’, ‘3(0.25)’, ‘5(0.5)’, ‘1<(0.5)’, ‘5>(0.75)’, ‘7>(0.25)’, ‘2(0.5)’, ‘5(0.5)’, ‘1(0.75)’, ‘3(0.25)’, ‘5(0.5)’, ‘1<(0.5)’, ‘1(0.75)’, ‘4(0.25)’, ‘6(0.5)’, ‘1<(0.5)’, ‘1(0.75)’, ‘3(0.25)’, ‘5(0.5)’, ‘1<(0.5)’, ‘5>(0.75)’, ‘7>(0.25)’, ‘2(0.5)’, ‘5(0.5)’, ‘1(0.75)’, ‘5(0.25)’, ‘3(0.5)’, ‘5(0.5)’, ‘1(0.75)’, ‘5(0.25)’, ‘3(0.5)’, ‘5(0.5)’, ‘1(0.75)’, ‘6(0.25)’, ‘4(0.5)’, ‘6(0.5)’, ‘1(0.75)’, ‘5(0.25)’, ‘3(0.5)’, ‘5(0.5)’, ‘1(0.75)’, ‘6(0.25)’, ‘4(0.5)’, ‘6(0.5)’, ‘1(0.75)’, ‘5(0.25)’, ‘3(0.5)’, ‘5(0.5)’, ‘7>(0.75)’, ‘5(0.25)’, ‘2(0.5)’, ‘5(0.5)’, ‘1>(2)’] }额,是不是很复杂,很臃肿。。。它以简谱为载体,通过特殊符号来标记音高和时长,从而产生mainTrack和backingTrack两个音轨,然后同步播放即可。这种实现虽然简单,但有很多致命缺点:不兼容通用的计算机乐谱格式,如musicxml不能完全表示音乐的所有维度,比如很多钢琴谱不止有两个音轨过于抽象和复杂,不实用,很难制作这种识别格式音乐专业人士: what are you 弄啥嘞?所以笔者转向另一种实现思路,解析musicxml,但奈何这个过程耗时耗力,目前只完成了一半,部分细节还没有完全解析正确,如果读者有好的想法,可以在评论区留言探讨。欢迎贡献协作贡献代码,直接PR贡献首页展示的随机歌词: https://github.com/WarpPrism/…贡献快速入门的弹奏方法: https://github.com/WarpPrism/…没想到短时间内能有这么多star(`・・´),吓得晚上下班回去又继续码代码。。。不过此项目仍不完善,还在不断更新中,特别是入门弹奏谱子比较少,目前只有:小星星新年好因为爱情隐形的翅膀蒲公英的约定纸短情长同桌的你晴天千与千寻主题曲明天你好青花瓷…都是笔者一个一个手打出来的T_T,能力有限,会的就这么多,所以是时候见证社区的力量了。FORK时,请遵循GPL开源协议。最后最后再贴一下体验地址: http://crystalworld.gitee.io/…欢迎体验,分享。解析musicxml的过程仍在进行中,如果某一天成功了,那么示例演奏里面就会加入海量的歌曲,以供学习,如果失败了,额,那就是因为生活阻挡了我奋进的脚步。。。原创不易,转载分享时请注明出处~ ...

April 8, 2019 · 3 min · jiezi

react 支持less

1、安装lessnpm install less less-loader 2、暴露webpack配置文件npm run eject3、配置config/webpack.config.js文件。新声明less添加loader的配置

April 2, 2019 · 1 min · jiezi

vue中如何实现的自定义按钮

在实际开发项目中,有时我们会用到自定义按钮;因为一个项目中,众多的页面,为了统一风格,我们会重复用到很多相同或相似的按钮,这时候,自定义按钮组件就派上了大用场,我们把定义好的按钮组件导出,在全局引用,就可以在其他组件随意使用啦,这样可以大幅度的提高我们的工作效率。好了,话不多说,上代码:img-button.vue//这是我们自定义按钮组件<template> <div class=“img-button”> <!– 图片按钮 –> <div v-if=“type === ‘查看’” :title=“tag === ’’ ? type : tag” class=“img-btn check-img”></div> <div v-if=“type === ‘添加’” :title=“tag === ’’ ? type : tag” class=“img-btn add-img”></div> <div v-if=“type === ‘修改’” :title=“tag === ’’ ? type : tag” class=“img-btn edit-img”></div> <div v-if=“type === ‘删除’” :title=“tag === ’’ ? type : tag” class=“img-btn delete-img”></div> <div v-if=“type === ‘刷新’” :title=“tag === ’’ ? type : tag” class=“img-btn refresh-img”></div> <div v-if=“type === ‘关闭’” :title=“tag === ’’ ? type : tag” class=“img-btn close-img”></div> <div v-if=“type === ‘齿轮’” :title=“tag === ’’ ? type : tag” class=“img-btn gear-img”></div> <div v-if=“type === ‘平面图’” :title=“tag === ’’ ? type : tag” class=“img-btn plan-img”></div> <div v-if=“type === ‘地图’” :title=“tag === ’’ ? type : tag” class=“img-btn map-img”></div> <div v-if=“type === ‘一般模板’” :title=“tag === ’’ ? type : tag” class=“img-btn normal-img”></div> <div v-if=“type === ‘特殊模板’” :title=“tag === ’’ ? type : tag” class=“img-btn special-img”></div> <div v-if=“type === ‘折线图’” :title=“tag === ’’ ? type : tag” class=“img-btn line-img”></div> <!– 文字按钮 自定义大小–> <div v-if=“type === ‘按钮’” :title=“tag === ’’ ? name : tag” class=“img-btn ibtn”>{{name}}</div> <div v-if=“type === ‘小按钮’” :title=“tag === ’’ ? name : tag” class=“ibtn-samll”>{{name}}</div> <div v-if=“type === ‘普通按钮’” :title=“tag === ’’ ? name : tag” class=“normal-btn”>{{name}}</div> </div></template><script>export default { name: ‘ImgButton’, props: { type: { type: String, default: ’’ }, name: { type: String, default: ’’ }, tag: { type: String, default: ’’ } }}</script><style lang=“less” scoped> .img-button { vertical-align: middle; display: inline-block; cursor: pointer; margin-right: 10px; .img-btn { .img-no-repeat; width:25px; height:25px; } .img-btn:hover { transform: scale(1.1); } .refresh-img { background-image: url(’../../assets/images/button/refresh.png’); } .add-img { background-image: url(’../../assets/images/button/add.png’); } .delete-img { background-image: url(’../../assets/images/button/delete.png’); } .check-img { background-image: url(’../../assets/images/button/check.png’); } .close-img { background-image: url(’../../assets/images/button/close.png’); } .edit-img { background-image: url(’../../assets/images/button/edit.png’); } .gear-img { background-image: url(’../../assets/images/button/gear.png’) } .plan-img { background-image: url(’../../assets/images/button/plan.png’) } .map-img { background-image: url(’../../assets/images/button/map.png’) } .normal-img { background-image: url(’../../assets/images/button/normal.png’) } .special-img { background-image: url(’../../assets/images/button/special.png’) } .line-img { background-image: url(’../../assets/images/button/line_chart.png’) } .ibtn { width: auto; min-width: 100px; padding: 0 20px; font-size: 17px; height: 30px; line-height: 30px; text-align: center; border-radius:15px; background-color: #2f5d98; vertical-align: middle; color:#00cccc; } .ibtn-samll { .ibtn; height: 25px; padding: 0 2px; font-size: 10px; line-height: 25px; border-radius: 0px; background-color: transparent; border: 1px solid #00cccc; } .ibtn-samll:hover { color: white; border: 1px solid white; } .normal-btn { .ibtn; } .normal-btn:hover { color: white; background-color: #ff9247; } }</style>在router.js中配置好路由在main.js中引入//注册自定义按钮 import imgButton from ‘./components/img-button’Vue.use(imgButton)然后就可以在其他组件使用了<imgButton type=‘刷新’ @click.native=‘refreshBtn’></imgButton>//值得注意的是 自定义按钮组件添加点击事件的时候一定要加.native 因为.native 修饰符就是用来注册元素的原生事件而不是组件自定义事件的好了 今天的分享就到这了。 ...

March 28, 2019 · 2 min · jiezi

NuxtJS 各种配置

NuxtSSR解决问题配置babel问题. Nuxt.js 不支持ES6的语法 加入babel 在package.json里面启动的命令加入 , start 的命令也需要加入 cross-env NODE_ENV=development nodemon server/index.js –watch server –exec babel-node 这还不够,因为我们没有去配置babel,所以我们需要在.babelrc去做一下presets的配置,在此之前我们需要安装一下babel插件 没有全局安装过babel-cli的同学请输入 npm i babel-cli -g 保险起见你可能还需要安装babel-core 然后我们开始安装babel-preset,输入 npm i babel-preset-es2015 –save-dev 最后一步,我们需要在项目的根目录创建.babelrc文件,并在里面写上如下配置: { “presets”: [“es2015”] } 出现问题就删除node-modules 重新下载依赖 配置一下less npm install less less-loader

March 16, 2019 · 1 min · jiezi

Vue + TypeScript 重构 vue-admin-element 小结

简单看了下 typescript 官网的语法,就想借助一个项目实战下。这里选用了 vue-admin-element附上源码地址:vue-element-admin-ts,欢迎 star 或 fork遇到的问题及解决方案Q: error TS7017: Index signature of object type implicitly has an ‘any’ typeA: https://stackoverflow.com/que…或者在 tsconfig.json文件的 compilerOptions选项中添加"noImplicitAny": falseQ: error TS2339: Property ‘webkitURL’ does not exist on type ‘Window’A:https://stackoverflow.com/que…interface Window { webkitURL?: any; } declare var window: Window;Q: Property ‘context’ does not exist on type ‘NodeRequire’.A:https://github.com/rails/webp…npm i -D @types/webpack-envQ: ’this’ implicitly has type ‘any’ because it does not have a type annotationA: https://stackoverflow.com/que...Q: 导入 .vue 时,为什么会报错,即使所写的路径并没有问题?A: 在 TypeScript 中,它仅识别 js/ts/jsx/tsx 文件,为了让它识别 .vue 文件,我们需要显式告诉 TypeScript,vue 文件存在,并且指定导出 VueConstructor:declare module ‘*.vue’ { import Vue from ‘vue’ export default Vue}Q: TS2345: Argument of type ‘string’ is not assignable to parameter of type ’never’.A: 空的数组添加数据的时候,会有这个提示,解决方案:https://github.com/Microsoft/…Q: Property ‘basePath’ has no initializer and is not definitely assigned in the constructor. 59 | @Prop({required: true, default: {}}) public item: Route; 60 | @Prop({default: false}) public isNest: boolean; > 61 | @Prop({default: ‘’}) public basePath: string;A: https://github.com/kaorun343/...Q: Object is possibly ‘undefined’.A: https://stackoverflow.com/que...Q:Property ‘$refs’ does not exist on type ‘Element | Element[] | Vue | Vue[]’. Property ‘$refs’ does not exist on type ‘Element’.A: https://github.com/vuejs/vue-...https://juejin.im/post/5bd698...https://www.leevii.com/2018/1… ...

March 7, 2019 · 1 min · jiezi

CSS预编译是什么?

背景:大厂的任职要求里还有一条是:熟悉使用Sass.Less等CSS预编译工具。学习一样东西的第一步就是首先知道它是什么CSS预编译工具有人开发了一些扩展CSS功能的写法,比如less,sass,其目的是让css能支持一些编程语言才有的功能,比如:表达式,函数,变量,循环,判断.有这些功能就能方便重复定义,写css时省事.举以下例子.var colorRed {color:red}//用var定义一个字体颜色变量样式//定义一个新闻列表样式.news-list{ font-size:12px; line-height:1.76; color:@colorRed; //这里文字颜色引用自变量 var colorRed}上面这段扩展css语言的写法里面有变量,然而浏览器的css解析引擎是不认识css里面的var这些东西的,这就是一个无效的css,所以这些扩展css的语言有预处理器,作用是把上面这段浏览器不认识的代码,还原为浏览器认识的CSS标准发给浏览器解析.如下:.news-list{ font-size:12px; line-height:1.76; color:red;}以上见解参考以下链接,可点击查看.

February 28, 2019 · 1 min · jiezi

基于 less,sass,stylus三种预处理rem

一. less形式 //定义一个变量和一个mixin(全局) @fontSizeBase: 75;//基于视觉稿横屏尺寸/100得出的基准font-size .px2rem(@name, @px){ @{name}: @px / @fontSizeBase * 1rem; } //使用示例: .fontsize { .px2rem(fontsize, 750); } //less翻译结果: .fontsize { font-size: 10rem; }二. sass形式 //定义一个变量和一个mixin $fontSizeBase: 75;//基于视觉稿横屏尺寸/100得出的基准font-size @mixin px2rem($name, $px){ #{$name}: $px / $fontSizeBase * 1rem; } //使用示例: .fontsize { @include px2rem(height, 750); } //scss翻译结果: .fontsize { font-size: 10rem; }三. stylus形式 //定义一个变量和一个mixin $fontSizeBase: 75;//基于视觉稿横屏尺寸/100得出的基准font-size px2rem(name, px){ {name}: px / $baseFontSize * 1rem; } //使用示例: .fontsize { px2rem(‘font-size’, 750); } //stylus翻译结果: .fontsize { font-size: 10rem; } ...

February 26, 2019 · 1 min · jiezi

Less 日常用法

Less 日常用法你需要了解的less 和 sass 是两种 css 预编译语言,其目的是为了更快、更结构的编写 css 文件,是一种强大的 css 编译语言,能使用 变量、运算符、判断、方法等等。本文我只写一些自己常用的方法,要看全部的帮助文档,参阅这里:http://lesscss.cn/features/看个小例子写一个 .btn 类并支持 :hover :active 样式CSS.btn {/* btn 初始样式 /}.btn:hover{/ :hover 样式 /}.btn:active{/ :active 样式 */}Less.btn{// btn 初始样式 &:hover{ // hover 样式 } &:active{ // active 样式 }}可以看出 less 的结构要比 css 清晰,并且写的也要更少。下面的 less 在使用中就会生成上面的 css。而这还只是皮毛,保证你用过 less 之后就不会再用 css 写样式了。变量less 是支持变量的,因为有了变量,让 less 在改变全局样式的时候更加方便了。一般使用中,颜色是最常用的。其次是单位长度。@变量名: 变量值// 如:// Colors@red: #CD594B;@yellow: #F8CE5E;@green: #4B9E65;@yellow: #5A8DEE;// Unites@btn-padding: 4px;@btn-lineheight: 26px;实际使用中:less.btn-success { background-color: @green; line-height: @btn-lineheight; color: #fff;}生成 css.btn-success { background-color: #4B9E65; line-height: 26px; color: #fff;}混合可以直接在其它类中插入其它类的内容。less.bg-yellow { background-color: @yellow;}.btn-warn { line-height: @btn-lineheight; .bg-yellow;}会生成 css.bg-yellow { background-color: #F8CE5E;}.btn-warn { line-height: 26px; background-color: #F8CE5E;}运算符less 支持 + - * / ( ) 运算,看例子@width-20: 20px;@count: 3;@per-10: 10%;.card{ width: width20 * @count; min-width: @per-10 * 7;}// 注意,运算的时候,要在运算符两边留空格,因为可能会有横线连接的变量,造成混淆。// 单位 less 可以自动识别,不用担心单位。输出.card{ width: 60px; min-width: 70%;}less 的内置函数参阅 : http://lesscss.cn/functions/#…完整的函数有:杂项函数、字符串函数、 列表函数、 数学函数、类型函数、颜色定义函数、颜色通道函数、颜色操作函数、颜色混合函数这里只说一此关于颜色的常用方法,因为其它的我现在也没怎么用到。lighten(颜色, 百分比)// 调高颜色的亮度darden(颜色, 百分比)// 调低颜色的亮度saturate(颜色, 百分比)// 调高饱和度desaturate(颜色, 百分比)// 调低饱和度@green: #4B9E65;.green{ background-color: @green;}.green-lighten{ background-color: lighten(@green,20%);}.green-darken{ background-color: darken(@green,20%);}.green-saturate{ background-color: saturate(@green,20%);}.green-desaturate{ background-color: desaturate(@green,20%);}输出.green { background-color: #4B9E65;}.green-lighten { background-color: #88c79c;}.green-darken { background-color: #2a5939;}.green-saturate { background-color: #34b55c;}.green-desaturate { background-color: #62876e;}函数方法的使用有时候,比如,你需要写一个按钮类 .btn-success, .btn-danger, .btn-default, .btn-warning,如果单个定义的话,会很麻烦,现在用了方法,就可以直接填参数完成了。less@green: #4B9E65;@blue: #5A8DEE;@yellow: #F8CE5E;@red: #CD594B;.btn-template(@bgcolor,@fcolor:white){// 定义了两个参数,第二个参数有默认值// 也就是说这个方法可以值一个或两个参数// 另外 带 () 参数的方法不会把自身渲染到 css 中,只有调用才会渲染 color: @fcolor; border-color: darken(@bgcolor, 3%); background-color: @bgcolor; &:hover { color: @fcolor; background-color: darken(@bgcolor, 5%); } &:active { color: @fcolor; background-color: darken(@bgcolor, 10%); }}.btn-blue{ .btn-template(@green)}.btn-blue{ .btn-template(@blue)}.btn-blue{ .btn-template(@yellow)}.btn-blue{ .btn-template(@red)}上面的 less 输出为下面的内容,有没有很厉害.btn-blue { color: white; border-color: #46945e; background-color: #4B9E65;}.btn-blue:hover { color: white; background-color: #438d5a;}.btn-blue:active { color: white; background-color: #3b7b4f;}.btn-blue { color: white; border-color: #4c83ed; background-color: #5A8DEE;}.btn-blue:hover { color: white; background-color: #437dec;}.btn-blue:active { color: white; background-color: #2c6de9;}.btn-blue { color: white; border-color: #f7ca4f; background-color: #F8CE5E;}.btn-blue:hover { color: white; background-color: #f7c746;}.btn-blue:active { color: white; background-color: #f6bf2d;}.btn-blue { color: white; border-color: #ca4e3f; background-color: #CD594B;}.btn-blue:hover { color: white; background-color: #c74737;}.btn-blue:active { color: white; background-color: #b34032;}文件拆分,文件引用像 js 和其它高级开发语言一样, less 也可以引用外部的 less 文件引用格式:@import “variables.less"这样就把外部的 variables.less 引入到当前文件中了variables.less// colors@green: #4B9E65;@blue: #5A8DEE;@yellow: #F8CE5E;@red: #CD594B;// units@common-height: 30px;@input-height: 26px;@input-padding: 4px;主体less文件@import “variables.less”// 主文件里面就可以引用 variables.less 中的变量了。 ...

February 22, 2019 · 2 min · jiezi

React入门:从零搭建一个React项目

一、初始化项目新建文件夹,文件名firstreact 文件夹名称不要用react,node这类关键字,后面使用插件时会发生错误。init项目环境,项目信息可默认或自行修改mkdir firstreactcd firstreactnpm init二、安装webpack新建gitignore文件,用于忽略安装的包文件,文件内容: node_modules安装webpack, 注意:我此处安装的webpack版本是4.28.4,webpack4和webpack2, webpack3的一些配置不同,具体参考webpack文档webpack中文文档npm i –save-dev webpack三、配置webpack环境新建文件夹,文件名:srcsrc目录下新建文件hello.js,文件内容:module.exports = function () { var element = document.createElement(‘h1’); element.innerHTML = ‘Hello React’; return element;};src目录下新建文件index.js,文件内容:var hello = require(’./hello.js’);document.body.appendChild(hello());新建文件webpack.config.js,一个最基础的webpack配置如下:const webpack = require(‘webpack’);const path = require(‘path’);var config = { entry: [ ‘./src/index.js’ ], // 打包入口文件 output: { path: path.resolve(__dirname, ‘dist’), filename: ‘bundle.js’ } // 打包输出文件};module.exports = config;执行webpack。执行完成后,根目录下会新增一个dist文件夹,文件夹下是打包出来的js文件bundle.jswebpack安装html-webpack-plugin,该插件将为你生成一个 HTML5 文件, 其中包括使用 script 标签的 body 中的所有 webpack 包。npm i –save-dev html-webpack-plugin html-webpack-plugin配置,webpack.config.js内容如下const webpack = require(‘webpack’);const path = require(‘path’);const HtmlwebpackPlugin = require(‘html-webpack-plugin’);var config = { entry: [ ‘./src/index.js’ ], // 打包入口文件 output: { path: path.resolve(__dirname, ‘dist’), filename: ‘bundle.js’ },// 打包输出文件 plugins: [ new HtmlwebpackPlugin({ title: ‘Hello React’, }) ]};module.exports = config;再次执行webpack,此时dist目录下生成了一个新文件index.htmlwebpack安装webpack-dev-server和webpack-cli,提供一个简单的 web 服务器,并且能够实时重新加载。npm install –save-dev webpack-dev-server webpack-cli修改webpack.configconst webpack = require(‘webpack’);const path = require(‘path’);const HtmlwebpackPlugin = require(‘html-webpack-plugin’);var config = { entry: [ ‘webpack/hot/dev-server’, ‘webpack-dev-server/client?http://localhost:3000’, ‘./src/index.js’ ], // 入口文件 output: { path: path.resolve(__dirname, ‘dist’), filename: ‘bundle.js’ }, // 打包输出文件 plugins: [ new HtmlwebpackPlugin({ title: ‘Hello React’ }), ]};module.exports = config;配置webpack启动的快方式,此处webpack4在启动服务是要求设置mode,告知 webpack 使用相应模式的内置优化。未设置会报一个警告。mode选项支持“development”“production”“none”,具体信息请阅文档 修改package.json文件:············ “scripts”: { “start”: “webpack-dev-server –mode=development –port 3000 –hot”, “build”: “webpack –mode=production” }···········启动服务,服务启动后打开浏览器访问http://localhost:3000/npm run dev三、优化开发环境css编译和js编译。现在开发时一般css都会使用扩展css语法,如less或sass,这时就需要在项目中安装css编译插件。此处以less为例。es6和es7语法也需要babel编译。const webpack = require(‘webpack’);const path = require(‘path’);const HtmlwebpackPlugin = require(‘html-webpack-plugin’);var config = { entry: [ ‘webpack/hot/dev-server’, ‘webpack-dev-server/client?http://localhost:3000’, ‘./src/index.js’ ], // 入口文件 output: { path: path.resolve(__dirname, ‘dist’), filename: ‘bundle.js’ }, // 打包输出文件 module: { rules: [ { test: /.less$/, use: [ { loader: ‘style-loader’ }, { loader: ‘css-loader’ }, { loader: ’less-loader’ } ] }, { test: /.js$/, exclude: /node_modules/, use: [ { loader: ‘babel-loader’ } ] } ] }, plugins: [ new HtmlwebpackPlugin({ title: ‘Hello React’ }), ]安装:npm i –save-dev less css-loader style-loader less-loadernpm i –save-dev babel-loader @babel/core @babel/preset-env @babel/preset-react 修改webpack.config.jsconst webpack = require(‘webpack’);const path = require(‘path’);const HtmlwebpackPlugin = require(‘html-webpack-plugin’);var config = { entry: [ ‘webpack/hot/dev-server’, ‘webpack-dev-server/client?http://localhost:3000’, ‘./src/index.js’ ], // 入口文件 output: { path: path.resolve(__dirname, ‘dist’), filename: ‘bundle.js’ }, // 打包输出文件 module: { rules: [ { test: /.less$/, use: [ { loader: ‘style-loader’ }, { loader: ‘css-loader’ }, { loader: ’less-loader’ } ] }, { test: /.js$/, exclude: /node_modules/, use: [ { loader: ‘babel-loader’ } ] } ] }, plugins: [ new HtmlwebpackPlugin({ title: ‘Hello React’ }), ]};module.exports = config;根目录下新建.babelrc文件,配置文件内容如下{ “presets”: [ “@babel/preset-env”, “@babel/preset-react” ]}在src目录下新建文件index.less,文件内容如下body{ h1{ color: green; }}修改src目录下的index.js文件:import hello from ‘./hello.js’;import ‘./index.less’;document.body.appendChild(hello());再次启动服务npm run start目前为止完成了一个最基础的项目结构,后面需要使用其他框架的话再此基础上修改。在这过程中因各个插件工具的版本不同可能会发生不同错误,遇到错误时,请查询相关文档。四、在项目中使用React安装react。npm i –save-dev react react-dom修改src目录下index.js,文件内容如下:import React from ‘react’;import ReactDOM from ‘react-dom’;import ‘./index.less’;class APP extends React.Component { render() { return (<h1>Hello React</h1>) }}ReactDOM.render(<APP/>, document.getElementById(‘content’));在src目录下新建index.html,在html增加挂载节点content。 文件内容如下:<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title><%= htmlWebpackPlugin.options.title %></title></head><body> <div id=“content”></div></body></html>对应修改webpack.config.js文件,为htmlWebpackPlugin修改template············ plugins: [ new HtmlwebpackPlugin({ title: ‘Hello React’, template: ‘./src/index.html’ }), ] ············目录结构为:│ .babelrc│ .gitignore│ package.json│ webpack.config.js│ └─src hello.js index.html index.js index.less ...

February 20, 2019 · 2 min · jiezi

JavaScript五十问——对比来说CSS的Grid与FlexBox(上篇)

前言春节假期有幸拜读了张鑫旭大大的关于Flex与Grid的两篇文章(见参考文献),很有收获;自己在开发的过程中,很多时候都会采用Flex布局,而Float与inline-box这种方式已经很少使用了;这次在春假期间学习了Grid,深感Grid的好用与便利。趁着这次机会总结一下Grid与Flex的使用。浏览器支持Flex 浏览器支持情况Grid浏览器支持情况可以看出来,相对于Grid来说,Flex无论实在PC端还是移动端都得到了很好的支持,而Grid,在移动端的支持还是差强人意。FlexBox在flex布局中,有两个概念需要谨记:容器与元素。在一个html标签中声明样式:display:flexordisplay:inline-flex即声明了一个flex的容器,在这个容器里面的元素即为flex元素。而flex所有的样式属性分为两类:容器属性与元素属性,他们均作用于flex元素,只不过flex容器中声明的属性统领flex所有元素整体显示与排布方式,而flex元素的属性表示单一元素的排布方式。下面,根据上面脑图的思路,依次介绍flex的属性。声明:下面师范的所有元素都遵从以下HTML结构 和基本样式<style>.container{ height:200px; background-color:#999;}.container >.item{ background-color:#456; width:80px; font-size:30px; color:white; text-align:center;}</style><div class=“container”> <div class=“item”>1</div> <div class=“item”>2</div> <div class=“item”>3</div> <div class=“item”>4</div> …</div>容器属性flex-directionflex-direction顾名思义,是控制flex元素的整体布局方向的,它包括四个属性:1.row //从左到右 默认2.row-reverse //从右到左3.column //从上到下4.column-reverse //从下到上1、flex-direction:row2.flex-direction:row-reverse3.flex-direction:column4.flex-direction: column-reverse上面四个图是分别在容器上(.container)设置flex-direction四个属性得到的效果。flex-wrapflex-wrap是控制元素是换行显示还是单行显示,它共有三个属性1.no-wrap //不换行 默认2.wrap // 换行3.wrap-reverse //换行反序为了更加明显的看出区别,我特别添加了一个难看的边框。在容器属性上添加flex-wrap,分别设置三个wrap属性1.flex-wrap: no-wrap2.flex-wrap: wrap3.flex-wrap: wrap-reverse在这里需要注意no-wrap属性:如果容器元素设置了最小宽度,而且元素的最小宽度之和>父容器的宽度,则显示内容溢出。如果容器元素没有设置最小宽度或者最小宽度之和<父容器的宽度,则容器元素收缩并将父元素填满,在上面no-wrap例子中,就没有设置子元素的最小宽度,读者可以自行添加验证。设置wrap-reverse属性后,我们可以看到它的换行结果与wrap的换行结果在行这一维度上是相反的。读者可以试试将flex-direction设置为column或者其他非默认值,再查看在不同的flex-wrap值下的显示,会有不同的结果哟。flex-flowflex-flow是 flex-direction与flex-wrap的统写,语法是flex-flow:<‘flex-direction’> || <‘flex-wrap’>justify-contentjustify-content控制flex元素水平方向的对齐方式,它共有 个属性:1.flex-start // 默认值 默认情况下左对齐2.flex-end // 右对齐3.center // 居中下面以space开头的属性都是描述剩余空间的排布方式的4.space-around //剩余空间围绕在每个子元素的周围5.space-between //剩余空间只分布在子元素之间,两端元素左右没有剩余空间6.space-evenly // 剩余空间均匀分布在元素两端、之间下面看例子:1.flex-start2.flex-end3.center4.space-between5.space-around6.space-evenly为了更加明显的看出不同space下的额外空间分布特点,我使用红框框出每一属性下的剩余元素。几个属性分布不同不言而喻了。align-contentalign-content与justify-content对应,代表元素垂直方向上的分布。而这种分布方式只有在多行的情况下才能够凸显出来,单行情况下设置此属性无效。相对于justify-content,它多出来一个stretch的属性,代表拉伸,默认属性。1.stretch2.flex-start3.flex-end4.space-between5.space-around6.space-evenly可以看出,它的排布方式与justify-content的逻辑是一致的,只不过方向不同而已。align-items既然有了多行情况下控制元素排布方式,就会有单行情况下元素排布方式。align-items就是在单行情况下,控制元素排布方式的。共有5个属性:1.stretch 默认属性,会将元素的高度拉伸至父容器的高度2.flex-start 顶部对齐3.flex-end 底部对齐4.baseline 基线对齐5.center 居中注意:以上所有的例子展示都是在其他属性默认情况的显示情况,如果更改其他属性(如:flex-direction 与 flex-wrap)值,会有不同的显示效果。元素属性orderorder属性可以控制flex元素的排布顺序,flex元素会根据order从小到大依次排布,order的默认值为0,因此如果想要某个元素排在前面,只需要将他的order值设为比0小的值即可。flex-growflex-grow控制元素所占宽度,默认值为0,当容器内有剩余空间时,flex-grow不为0的元素将会按照以下规则扩展:容器中只有一个元素设置了flex-grow 1、flex-grow 值>=1 那么这个元素会填充容器的剩余空间.container .item:first-child{ order:2; flex-grow:1;}2、flex-grow 在0-1之间,那么这个元素会多占用空间为剩余空间乘以这个flex-grow的值。.container .item:first-child{ order:2; flex-grow:0.5;}.container{ display:flex; justify-content:space-around;//如果子元素的flex-grow<1,此属性依然有效}.container .item:first-child{ order:2; flex-grow:0.5;}容器中有多个元素设置了flex-grow1、所有元素的flex-grow的值之和>1则占用全部的剩余空间,多占用的剩余空间比例即为各个元素所设置flex-grow的比例。2、所有元素的flex-grow的值之和<1所占用的剩余空间的比例即为各个元素的felx-grow的值的比例。flex-shrinkflex-shrink的属性与flex-grow相反,指的是当空间不足的时候,元素的收缩比例,默认值为1;其核心思路与grow一致,这里不再赘述,读者可以自行检验。flex-basisflex-basis定义了在分配剩余空间之前,每个元素的默认宽度,默认为auto即元素的宽度;当flex-basis的值不为auto时,其显示的优先级是高于元素的width的。flexflex属性为以上三个属性的统称,语法为:flex: none | auto | [ <‘flex-grow’> <‘flex-shrink’>? || <‘flex-basis’> ]flex翻译为中文就是弹性的,所以这个属性就是说明当有空间过大or空间不足时,每个元素如何分布。align-selfalign-self顾名思义,就是确定单个元素垂直分布状态;其在父容器对应的属性是algin-items;其属性值有align-items一致,只不过多了一个auto默认属性,表示与父元素的auto-items值一致。来看例子:对应css代码:.container{ display:flex; align-items:center;}.container .item:nth-child(2n+1){ order:2; flex-grow:2; align-self:flex-start;}我在父元素上添加align-items属性,使flex元素居中对齐,在子元素上添加align-self属性,使奇数子元素向上对齐。当有多行的情况下,但是align-content未设置,我们可以看到,每一个设置了align-self属性的子元素会在当前的行按照align-self属性显示,但是当align-content属性设置后,其align-self属性失效(见下图)。对应代码:.container{ display:flex; align-content:center; flex-wrap:wrap;}.container .item:nth-child(2n+1){ order:2; flex-grow:2; align-self:flex-start;}总结flex布局就总结到这里,里面有些类似属性没有举例子,还需要读者自己去验证。相对于其他解决方案,flex布局更加简洁,也更加具有语义性;最显而易见的,可以很方便的解决我们平时面试过程中遇到的多栏布局,垂直居中问题。其实细细品读flex,相比于Grid而言,他还是更加线性化,就是把所有的元素都看成一条线,确定这条线的方向、居中垂直方式,当这条线超过父元素的范围,我们怎样处理。所以,虽然flex看似有许多属性,但是合理的理解后,还是非常简单的。这篇是glex与Grid的上篇,主要介绍了flex,而Grid的相关属性与应用,我们下篇见。参考文献张鑫旭:写给自己看的display: flex布局教程阮一峰:Flex 布局教程 ...

February 17, 2019 · 1 min · jiezi

解决mac下webstorm编辑器识别less的问题

之前在使用webstorm开发vue项目过程中,发现代码里的less有些地方总是飘红报错,虽然不影响整体代码运行,但是看起来总是很乱很难受,如下图(由于当时忘记截图,在网上找别人的图片,但是遇到问题是一样的 ) https://segmentfault.com/img/…然后我在网上找了很多解决方案,大致有以下几个1.加上 rel=“stylesheet/less”<style lang=“less” rel=“stylesheet/less”>…</style>2.加上 type=“text/less”<style scoped lang=“less” type=“text/less”>…</style>3.先全局安装npm install less -g ;然后 webstorm>tools>file watchers> + >less配置一下总结:以上三种方法我都做了尝试,发现并不能解决我的报错问题,继续找其他解决办法继续搜索发现又有人说是版本问题,于是看了下自己的webstorm版本,16版,好吧 实在是太老了,于是下载最新版,尝试看是否能解决我的问题,在安装最新版的webstorm过程中,又遇到一个坑,装完发现WebStrom Mac闪退打不开,原来是之前安装的版本没有完全卸载,如果有遇到同样问题的 请按照以下方法删除残留版本,在命令框输入以下命令cd librarycd Preferences输入下面命令,删除所有残留的webstorm版本rm -rf WebStorm2016.3将所有残留版本删除之后,重新装了最新版的2018.3.4的 问题完美解决了 再也不飙红了

February 15, 2019 · 1 min · jiezi

大话css预编译处理(三):基础语法篇

一、Sass、LESS和Stylus的语法每一种语言都有自己一定的语法规则,CSS预处理器语言也不例外,在真正使用CSS预处器语言之前还有一个不可缺少的知识点,就是对语法的理解。值得庆幸的是,这三款CSS预处理器语言的语法和CSS语法都差不多。1.Sass语法Sass3.0版本开始使用的是标准的CSS语法,和SCSS可以说是一样的。这样Sass代码转换成CSS代码变得更容易。默认Sass使用.scss扩展名。Sass语法规则可以像CSS那样书写:/style.sass新版语法规则/h1{ color:#936; background-color:#333;} 正如你所看到的,在Sass样式中,这样的代码是在简单不过的了。重要的一点是,Sass也同时支持老的语法,老的语法和常规的CSS语法略有不同,他需要严格的语法,任何的缩进和字符的错误都会造成样式的编译错误。Sass可以省略大括号({})和分号(;),完全依靠严格的缩进和格式化代码,而且文件使用.sass扩展名,他的语法类似于:/style.sass/h1 color:#936 background-color: #3332.LESS语法LESS是CSS的一种扩展形式,它并没有阉割CSS的功能,而是在现有的CSS语法上,添加了很多额外的功能。就语法规则而言,LESS和Sass一样,都是使用CSS的标准语法,只是LESS的源文件的扩展名是.less,其基本语法类似于:/style.less/h1 { color: #963; background-color: #333;}3.Stylus语法Stylus的语法花样多一些,它的文件扩展名是.styl,Stylus也接受标准的CSS语法,但是他也像Sass老的语法规则,使用缩进控制,同时Stylus也接受不带大括号({})和分号的语法,如下所示:/style.styl//类似于CSS标准语法/h1 { color: #963; background-color:#333;}/省略大括号({})/h1 color: #963; background-color: #333;/省略大括号({})和分号(;)/h1 color:#963 background-color:#333在Stylus样式中,你也可以在同一个样式文件中使用不同的语法规则,下面这样的写法也不会报错:/style.styl/h1 { color #963}h2 font-size:1.2em 二、 Sass、LESS和Stylus特性这三款CSS预处理器语言具有一些相同的特性,例如:变量、混入、嵌套、函数等。在这一节中,我们依次来对比一下这三款CSS预处理器语言各种特性的异同之处,以及使用方法。1.变量(Variables)如果你是一个开发人员,变量应该是你最好朋友之一。在CSS预处理器语言中你也可以声明变量,并在整个样式表中使用。CSS预处理器语言支持任何变量(例如:颜色、数值、文本)。然后你可以在任意地方引用变量。a)Sass的变量Sass声明变量必须是“$”开头,后面紧跟变量名和变量值,而且变量名和变量值需要使用冒号(:)分隔开。就像CSS属性设置一样:/声明变量/$mainColor: #963;$siteWidth: 1024px;$borderStyle: dotted;/调用变量/ | /转译出来的CSS/——————————————+——————————body { | body { color: $mainColor; | color: #963; border:1px $borderStyle $mainColor; | border:1px dotted #963; max-width: $siteWidth; | max-width: 1024px;} | } b) LESS的变量LESS样式中声明变量和调用变量和Sass一样,唯一的区别就是变量名前面使用的是“@”字符:/声明变量/ @mainColor: #963; @siteWidth: 1024px; @borderStyle: dotted; /调用变量/ | /转译出来的CSS/ —————————————-+——————————- body { | body { color: @mainColor; | color:#963; border:1px @borderStyle @mainColor; | border:1px dotted #963; max-width: @siteWidth; | max-width:1024px; } | } c)Stylus的变量Stylus样式中声明变量没有任何限定,你可以使用“$”符号开始。结尾的分号(;)可有可无,但变量名和变量值之间的等号(=)是需要的。有一点需要注意的是,如果我们使用“@”符号开头来声明(0.22.4)变量,Stylus会进行编译,但其对应的值并不会赋值给变量。换句话说,在Stylus中不要使用“@”符号开头声明变量。Stylus中调用变量的方法和LESS、Sass是完全相同的。/声明变量/mainColor = #963;siteWidth = 1024px;$borderStyle = dotted;/调用变量/ | /转译出来的CSS/—————————————-+——————————–body | body { color mainColor | color: #963; border 1px $borderStyle mainColor | border:1px dotted #963 max-width siteWidth | max-width:1024px; | } Stylus还有一个独特功能,不需要分配值给变量就可以定义引用属性:/水平垂直居中/ | /转译出来的CSS/————————————+————————————#logo | #logo { position absolute | position:absolute; top 50% | top:50%; left 50% | left:50%; width w = 150px | width:150px; height h = 80px | height:80px; margin-left -(w / 2) | margin-left:-75px; margin-top -(h / 2) | margin-top:-40px; | } 从上面的代码中我们可以看出,CSS预处理器语言中的变量是值级别的重复使用,可以将相同的值定义成变量统一管理起来。CSS预处理器语言中变量的特性适用于定义主题(也就是我们常说的换肤),我们可以将背景颜色、字体颜色、边框属性等常规样式统一定义,这样不同的主题只需要定义不同的变量文件就可以。2.作用域(Scope)CSS预处理器语言中的变量和其他程序语言一样,可以实现值的复用,同样它也存在生命周期,也就是Scope(变量范围,开发人员习惯称之为作用域),简单点讲就是局部变量还是全局变量的概念,查找变量的顺序是先在局部定义中找,如果找不到,则查找上级定义,直至全局。下面我们通过一个简单的例子来解释这三款CSS预处理器的作用域使用。a)Sass的作用域Sass中作用域在这三款预处理器是最差的,可以说在Sass中是不存在什么全局变量。具体来看下面的代码:/Sass样式/$color: black;.scoped { $bg: blue; $color: white; color: $color; background-color:$bg;}.unscoped { color:$color;} 先看转译出来的CSS样式:.scoped { color:white;/是白色/ background-color:blue;}.unscoped { color:white;/白色(无全局变量概念)/} 示例明显的告诉我们,在Sass样式中定义变量,调用变量是没有全局变量一个概念存在,因此在Sass中定义了相同变量名时,在调用之时千万要多加小心,不然会给你的样式带来错误。b)LESS的作用域LESS中的作用域和其他程序语言中的作用域非常的相同,他首先会查找局部定义的变量,如果没有找到,会像冒泡一样,一级一级往下查找,直到根为止,同样上面的例子,我们来看看他在LESS下所起的变化。/LESS样式/ @color: black; .scoped { @bg: blue; @color: white; color: @color; background-color:@bg; } .unscoped { color:@color; }转译出来的CSS样式:.scoped { color:white;/白色(调用了局部变量)/ background-color:blue;}.unscoped { color:black;/黑色(调用了全局变量)/}c)Stylus的作用域Stylus虽然起步比较晚,但其作用域的特性和LESS一样,可以支持全局变量和局变量。会向上冒泡查找,直到根为止。3.混合(Mixins)Mixins是CSS预处理器中语言中最强大的特性,简单点来说,Mixins可以将一部分样式抽出,作为单独定义的模块,被很多选择器重复使用。平时你在写样式时肯定有碰到过,某段CSS样式经常要用到多个元素中,这样你就需要重复的写多次。在CSS预处理器语言中,你可以为这些公用的CSS样式定义一个Mixin,然后在你CSS需要使用这些样式的地方直接调用你定义好的Mixin。这是一个非常有用的特性,Mixins被当作一个公认的选择器,还可以在Mixins中定义变量或者默认参数。a)Sass的混合Sass样式中声明Mixins时需要使用“@mixin”,然后后面紧跟Mixins的名,他也可以定义参数,同时可以给这个参数设置一个默认值,但参数名是使用“$”符号开始,而且和参数值之间需要使用冒号(:)分开。在选择器调用定义好的Mixins需要使用“@include”,然后在其后紧跟你要调用的Mixins名。不过在Sass中还支持老的调用方法,就是使用加号“+”调用Mixins,在“+”后紧跟Mixins名。一起来看个简单的例子,比如说在你的Sass样式中定义了一个名叫“error”的Mixin,这个“error”设置了一个参数“$borderWidth”,在没特别定义外,这个参数的默认值设置为“2px”:/声明一个Mixin叫作“error”/@mixin error($borderWidth:2px){ border:$borderWidth solid #f00; color: #f00;}/调用error Mixins/.generic-error { @include error();/直接调用error mixins/}.login-error { @include error(5px);/调用error mixins,并将参数$borderWidth的值重定义为5px/} b)LESS的混合在LESS中,混合是指将定义好的“ClassA”中引入另一个已经定义的“Class”,就像在当前的“Class”中增加一个属性一样。不过LESS样式中声明Mixins和Sass声明方法不一样,他更像CSS定义样式,在LESS可以将Mixins看成是一个类选择器,当然Mixins也可以设置参数,并给参数设置默认值。不过设置参数的变量名是使用“@”开头,同样参数和默认参数值之间需要使用冒号(:)分隔开。正如Sass混合是的示例,同样在LESS样式中定义一个名叫“error”的Mixin,这个“error”设置了一个参数“@borderWidth”,在没有特别定义外,这个参数的默认值是“2px”:/声明一个Mixin叫作“error”/.error(@borderWidth:2px){ border:@borderWidth solid #f00; color: #f00;}/调用error Mixins/.generic-error { .error();/直接调用error mixins/}.login-error { .error(5px);/调用error mixins,并将参数@borderWidth的值重定义为5px/} c)Stylus的混合Stylus中的混合和前两款CSS预处理器语言的混合略有不同,他可以不使用任何符号,就是直接声明Mixins名,然后在定义参数和默认值之间用等号(=)来连接。/声明一个Mixin叫作“error”/error(borderWidth=2px){ border:borderWidth solid #f00; color: #f00;}/调用error Mixins/.generic-error { error();/直接调用error mixins/}.login-error { error(5px);/调用error mixins,并将参数$borderWidth的值重定义为5px/}三个示例都将会转译成相同的CSS代码:.generic-error { border: 2px solid #f00; color:#f00;}.login-error { border:5px solid #f00; color: #f00;} 4.嵌套(Nesting)CSS预处理器语言中的嵌套指的是在一个选择器中嵌套另一个选择器来实现继承,从而减少代码量,并且增加了代码的可读性。比如说,我们在CSS中多个元素有一个相同的父元素,那么写样式会变得很乏味,我们需要一遍一遍的在每个元素前写这个父元素,除非给特定的元素添加类名“class”或者ID。section { margin:10px;}section nav { height:25px;}section nav a { color: #0982c1;}section nav a:hover { text-decoration: underline;} 相反,使用CSS预处理器语言的嵌套特性,我们可以在父元素的大括号({})里写这些元素。同时可以使用“&”符号来引用父选择器。对于Sass、LESS和Stylus这三款CSS预处理器语言的嵌套选择器来说,他们都具有相同的语法:section { margin:10px; nav { height:25px; a { color:#0982c1; &:hover { text-decoration:underline; } } }} 上面的预处理器转译出来的CSS代码和我们开始展示的CSS代码是相同的,非常的方便吧!5.继承(Inheritance)对于熟悉CSS的同学来说,对于属性的继承并不陌生。平时在写CSS样式常碰到多个元素应用相同的样式时,我们在CSS中通常都是这样写:p,ul,ol{/样式写在这里/}这样做非常的好,但往往我们需要给单独元素添加另外的样式,这个时候我们就需要把其中选择器单独出来写样式,如此一来我们维护样式就相当的麻烦。为了应对这个问题,CSS预处理器语言可以从一个选择继承另个选择器下的所有样式。a)Sass和Stylus的继承Sass和Stylus的继承是把一个选择器的所有样式继承到另个选择器上。在继承另个选择器的样式时需要使用“@extend”开始,后面紧跟被继承的选择器:.block { margin: 10px 5px; padding: 2px;}p { @extend .block;/继承.block选择器下所有样式/ border: 1px solid #eee;}ul,ol { @extend .block; /继承.block选择器下所有样式/ color: #333; text-transform: uppercase;} 上面的代码转译成CSS:.block,p,ul,ol { margin: 10px 5px; padding:2px;}p { border: 1px solid #eee}ul,ol { color:#333; text-transform:uppercase;} b)LESS的继承LESS支持的继承和Sass与Stylus不一样,他不是在选择器上继承,而是将Mixins中的样式嵌套到每个选择器里面。这种方法的缺点就是在每个选择器中会有重复的样式产生。.block { margin: 10px 5px; padding: 2px;}p { .block;/继承.block选择器下所有样式/ border: 1px solid #eee;}ul,ol { .block; /继承.block选择器下所有样式/ color: #333; text-transform: uppercase;}转译出来的CSS代码:.block { margin: 10px 5px; padding:2px;}p { margin: 10px 5px; padding:2px; border: 1px solid #eee}ul,ol { margin: 10px 5px; padding:2px; color:#333; text-transform:uppercase;}正如所看到的,上面的代码“.block”的样式将会被插入到相应的你要继承的选择器中,但需要注意的是优先级的问题。6.运算符(Operations)CSS预处理器语言还具有运算的特性,其简单的讲,就是对数值型的Value(如:数字、颜色、变量等)进行加减乘除四则运算。这样的特性在CSS样式中是想都不敢想的,但在CSS预处理器语言中对样式做一些运算一点问题都没有了,例如:@base_margin: 10px;@double_margin: @base_margin * 2;@full_page: 960px;@half_page: @full_page / 2;@quarter_page: (@full_page / 2) / 2; 上面代码是LESS的运算示例,声明一下,在取得“@quarter_page”变量时,我们可以直接除以4,但是在这里,我们只是想演示一下圆括号组成的“运算顺序”(这个运算顺序小学生也知道)。在复合型运算中,小括号也是很有必要的,例如:border: (@width / 2) solid #000;Sass在数字运算上要比LESS更专业,他可以直接换算单位了。Sass可以处理无法识别的度量单位,并将其输出。这个特性很明显是一个对未来的尝试——证明W3C作出的一些改变。Stylus的运算是三款预处理器语言中最强大的一款,他拥有其他程序语言一样的运算功能,简单点的加减乘除,复杂的有关系运算、逻辑运算等。受限于篇幅,感兴趣的同学可以到官网上仔细阅读。7.颜色函数颜色函数是CSS预处理器语言中内置的颜色函数功能,这些功能可以对颜色进行处理,例如颜色的变亮、变暗、饱和度控制、色相控制,渐变颜色等处理十分的方便。a)Sass颜色函数lighten($color, 10%); /* 返回的颜色在$color基础上变亮10% /darken($color, 10%); / 返回的颜色在$color基础上变暗10% /saturate($color, 10%); / 返回的颜色在$color基础上饱和度增加10% /desaturate($color, 10%); / 返回的颜色在$color基础上饱和度减少10% /grayscale($color); / 返回$color的灰度色*/complement($color); /* 返回$color的补色 /invert($color); / 返回$color的反相色 /mix($color1, $color2, 50%); / $color1 和 $color2 的 50% 混合色*/这只是Sass中颜色函数的一个简单列表,更多详细的介绍可以阅读Sass文档。颜色函数可以运用到任何一个元素上,只要其有颜色的属性,下面是一个简单的例子:$color: #0982C1;h1 { background: $color; border: 3px solid darken($color, 50%);/边框颜色在$color的基础上变暗50%/} b)LESS颜色函数lighten(@color, 10%); /* 返回的颜色在@color基础上变亮10% /darken(@color, 10%); / 返回的颜色在@color基础上变暗10%/saturate(@color, 10%); / 返回的颜色在@color基础上饱和度增加10% /desaturate(@color, 10%); / 返回的颜色在@color基础上饱和度降低10%/spin(@color, 10); / 返回的颜色在@color基础上色调增加10 /spin(@color, -10); / 返回的颜色在@color基础上色调减少10 /mix(@color1, @color2); / 返回的颜色是@color1和@color2两者的混合色 /LESS的完整颜色函数功能,请阅读LESS文档。下面是LESS中如何使用一个颜色函数的简单例子:@color: #0982C1;h1 { background: @color; border: 3px solid darken(@color, 50%);} c)Stylus的颜色函数lighten(color, 10%); / 返回的颜色在’color’基础上变亮10% /darken(color, 10%); / 返回的颜色在’color’基础上变暗10% /saturate(color, 10%); / 返回的颜色在’color’基础上饱和度增加10% /desaturate(color, 10%); / 返回的颜色在’color’基础上饱和度降低10% / 有关于Stylus的颜色函数介绍,请阅读Stylus文档。下面是Stylus颜色函数的一个简单实例:color = #0982C1h1 background color border 3px solid darken(color, 50%) 从上面展示的部分颜色函数可以告诉我们,Sass、LESS和Stylus都具有强大的颜色函数功能,功能特性上都大同小异,只是在使用方法上略有不同。而且他们都具有相同的一个目的,就是方便操作样式中的颜色值。8.导入(Import)在CSS中,并不喜欢用@import来导入样式,因为这样的做法会增加http的请求。但是在CSS预处理器中的导入(@import)规则和CSS的有所不同,它只是在语义上导入不同的文件,但最终结果是生成一个CSS文件。如果你是通过“@import‘file.css’”导入“file.css”样式文件,那效果跟普通CSS导入样式文件一样。注意:导入文件中定义了变量、混合等信息也将会被引入到主样式文件中,因此需要避免他们的相互冲突。Sass、LESS和Stylus三款CSS预处理器语言,导入样式的方法都是一样:被导入文件的样式:/ file.{type} /body { background: #EEE;} 需要导入样式的文件:@import “reset.css”;@import “file.{type}";p { background: #0982C1;} 转译出来的CSS代码:@import “reset.css”;body { background: #EEE;}p { background: #0982C1;} 9.注释(Comment)CSS预处理器语言中的注释是比较基础的一部分,这三款预处理器语言除了具有标准的CSS注释之外,还具有单行注释,只不过单行注释不会被转译出来。a)Sass、LESS和Stylus的多行注释多行注释和CSS的标准注释,他们可以输出到CSS样式中,但在Stylus转译时,只有在“compress”选项未启用的时候才会被输出来。/ 我是注释/body padding 5px b)Sass、LESS和Stylus的单行注释单行注释跟JavaScript语言中的注释一样,使用双斜杠(//),但单行注释不会输出到CSS中。//我是注释 @mainColor:#369;//定义主体颜色 在Stylus中除了以上两种注释之外,他还有一种注释,叫作多行缓冲注释。这种注释跟多行注释类似,不同之处在于始的时候,这里是”/!”。这个相当于告诉Stylus压缩的时候这段无视直接输出。/!给定数值合体/add(a, b) a + b 上面从九个常用的特性对Sass、LESS和Stylus三款CSS预处理器语言的使用做了对比,在某些特性上可以说是一模一样,而有一些特性上功能其实一样,只是在部分书写规则上有所不同。当然有些特性是完全不同。在这里几是从使用方法上做为一个比较,主要目的是让大家经过对比之后,使自己选择哪一款CSS预处理器语言有所方向和帮助。三、 CSS预处理器的高级应用我们知道,Sass、LESS和Stylus都具有变量、混合、嵌套、函数和作用域等特性,但这些特性都是一些普通的特性。其实除了这些特性之外,他们还拥有一些很有趣的特性有助于我们的开发,例如条件语句、循环语句等。接下来,我们同样从使用上来对比一下这三款CSS预处理器语言在这方面应用又有何不同异同。a)条件语句说到编程,对于编程基本控制流,大家并不会感到陌生,除了循环就是条件了。条件提供了语言的可控制,否则就是纯粹的静态语言。提供的条件有导入、混合、函数以及更多。在编程语言中常见的条件语句:if/else if/else if表达式满足(true)的时候执行后面语然块,否则,继续后面的else if或else。在这三款CSS3预处理器语言中都具有这种思想,只不过LESS中表达的方式略有不现,接下来我们依次看看他们具体如何使用。Sass的条件语句Sass样式中的条件语句和其他编程语言的条件语句非常相似,在样式中可以使用“@if”来进行判断:p { @if 1 + 1 == 2 { border: 1px solid; } @if 5 < 3 { border: 2px dotted; } @if null { border: 3px double; }}编译出来的CSS:p { border: 1px solid; }在Sass中条件语句还可以和@else if、@else配套使用:$type: monster;p { @if $type == ocean { color: blue; } @else if $type == matador { color: red; } @else if $type == monster { color: green; } @else { color: black; }}转译出来的CSS:p {color:green;} Stylus的条件语句Stylus的条件语句的使用和其他编程的条件语句使用基本类似,不同的是他可以在样式去省略大括号({}):box(x, y, margin = false) padding y x if margin margin y xbody box(5px, 10px, true) Stylus同样可以和else if、else配套使用:box(x, y, margin-only = false) if margin-only margin y x else padding y x Stylus除了这种简单的条件语句应用之外,他还支持后缀条件语句。这就意味着if和unless(熟悉Ruby程序语言的用户应该都知道unless条件,其基本上与if相反,本质上是“(!(expr))”)当作操作符;当右边表达式为真的时候执行左边的操作对象。例如,我们定义了negative()来执行一些基本的检查。下面我们使用块式条件:negative(n) unless n is a ‘unit’ error(‘无效数值’) if n < 0 yes else no 接下来,我们利用后缀条件让我们的方法简洁:negative(n) error(‘无效数值’) unless n is a ‘unit’ return yes if n < 0 no 当然,我们可以更进一步。如这个“n < 0 ? yes : no”可以用布尔代替:“n < 0”。后缀条件适合于大多数的单行语句。如“@import,@charset”混合书写等。当然,下面所示的属性也是可以的:pad(types = margin padding, n = 5px) padding unit(n, px) if padding in types margin unit(n, px) if margin in typesbody pad()body pad(margin)body apply-mixins = true pad(padding, 10) if apply-mixins 上面代码转译出来的CSS:body { padding: 5px; margin: 5px;}body { margin: 5px;}body { padding: 10px;} LESS的条件语句LESS的条件语句使用有些另类,他不是我们常见的关键词if和else if之类,而其实现方式是利用关键词“when”。.mixin (@a) when (@a >= 10) { background-color: black; } .mixin (@a) when (@a < 10) { background-color: white; } .class1 { .mixin(12) } .class2 { .mixin(6) } 转译出来的CSS:.class1 { background-color: black; } .class2 { background-color: white; } 利用When以及<、>、=、<=、>=是十分简单和方便的。LESS并没有停留在这里,而且提供了很多类型检查函数来辅助条件表达式,例如:iscolor、isnumber、isstring、iskeyword、isurl等等。.mixin (@a) when (iscolor(@a)) { background-color: black; } .mixin (@a) when (isnumber(@a)) { background-color: white; } .class1 { .mixin(red) } .class2 { .mixin(6) }转译出来的CSS.class1 { background-color: black; } .class2 { background-color: white; } 另外,LESS的条件表达式同样支持AND和OR以及NOT来组合条件表达式,这样可以组织成更为强大的条件表达式。需要特别指出的一点是,OR在LESS中并不是or关键词,而是用,来表示or的逻辑关系。.smaller (@a, @b) when (@a > @b) { background-color: black; } .math (@a) when (@a > 10) and (@a < 20) { background-color: red; } .math (@a) when (@a < 10),(@a > 20) { background-color: blue; } .math (@a) when not (@a = 10) { background-color: yellow; } .math (@a) when (@a = 10) { background-color: green; } .testSmall {.smaller(30, 10) } .testMath1 {.math(15)} .testMath2 {.math(7)} .testMath3 {.math(10)}转译出来的CSS.testSmall { background-color: black; } .testMath1 { background-color: red; background-color: yellow; } .testMath2 { background-color: blue; background-color: yellow; } .testMath3 { background-color: green; } b)循环语句Sass和Stylus还支持for循环语句,而LESS并没支持for循环语句,但值得庆幸的是,在LESS中可以使用When来模拟出for循环的特性。Sass的循环语句Sass中使用for循环语句需要使用@for,并且配合“from”和“through”一起使用,其基本语法:@for $var from <start> through <end> {语句块}我们来看一个简单的例子:@for $i from 1 through 3 { .item-#{$i} { width: 2em * $i; }} 转译出来的CSS代码:.item-1 { width: 2em; }.item-2 { width: 4em; }.item-3 { width: 6em; } 在Sass中循环语句除了@for语句之外,还有@each语句和@while语句@each循环语法:@each $var in <list>{语句块} 来看个简单的实例:@each $animal in puma, sea-slug, egret, salamander { .#{$animal}-icon { background-image: url(’/images/#{$animal}.png’); }} 转译出来的CSS.puma-icon { background-image: url(’/images/puma.png’); }.sea-slug-icon { background-image: url(’/images/sea-slug.png’); }.egret-icon { background-image: url(’/images/egret.png’); }.salamander-icon { background-image: url(’/images/salamander.png’) }@while循环使用和其他编程语言类似:$i: 6;@while $i > 0 { .item-#{$i} { width: 2em * $i; } $i: $i - 2;}转译出来的CSS.item-6 { width: 12em; }.item-4 { width: 8em; }.item-2 { width: 4em; }Stylus的循环语句在Stylus样式中通过for/in对表达式进行循环,形式如下:for <val-name> [, <key-name>] in <expression> 例如:body for num in 1 2 3 foo num 转译出来CSSbody { foo: 1; foo: 2; foo: 3;} 下面这个例子演示了如何使用<key-name>:body fonts = Impact Arial sans-serif for font, i in fonts foo i font 转译出来的CSSbody { foo: 0 Impact; foo: 1 Arial; foo: 2 sans-serif;} LESS的循环语句在LESS语言中并没有现在的循环语句,可是像其条件语句一样,通过when来模拟出他的循环功能。.loopingClass (@index) when (@index > 0) { .myclass { z-index: @index; } // 递归 .loopingClass(@index - 1);}// 停止循环.loopingClass (0) {}// 输出.loopingClass (3); 转译出的CSS.myclass {z-index: 3;}.myclass {z-index: 2;}.myclass {z-index: 1;} 相比之下,Sass和Stylus对条件语句和循环语句的处理要比LESS语言强大。因为他们具有真正的语言处理能力。综上所述,我们对Sass、LESS和Stylus做一个简单的对比总结: 三者都是开源项目;Sass诞生是最早也是最成熟的CSS预处理器,有Ruby社区和Compass支持;Stylus早期服务器NodeJS项目,在该社区得到一定支持者;LESS出现于2009年,支持者远超于Ruby和Node JS社区;Sass和LESS语法较为严谨、严密,而Stylus语法相对散漫,其中LESS学习起来更快一些,因为他更像CSS的标准;Sass和LESS相互影响较大,其中Sass受LESS影响,已经进化到了全面兼容CSS的SCSS;Sass和LESS都有第三方工具提供转译,特别是Sass和Compass是绝配;Sass、LESS和Stylus都具有变量、作用域、混合、嵌套、继承、运算符、颜色函数、导入和注释等基本特性,而且以“变量”、“混合”、“嵌套”、“继承”和“颜色函数”称为五大基本特性,各自特性实现功能基本相似,只是使用规则上有所不同;Sass和Stylus具有类似于语言处理的能力,比如说条件语句、循环语句等,而LESS需要通过When等关键词模拟这些功能,在这一方面略逊一层; ...

February 13, 2019 · 5 min · jiezi

CSS 预处理语言之 less 篇

less前言Less 是一门 CSS 预处理语言,它扩充了 CSS 语言,增加了诸如变量、混合(mixin)、函数等功能,让 CSS 更易维护、方便制作主题、扩充。安装客户端使用// 引入 .less 文件,rel 属性值为:“stylesheet/less”<link rel=“stylesheet/less” type=“text/css” href=“index.less”>// 在引入 .less 文件之后,引入 less.js 文件,官网下载或者使用CDN;<script src=“https://cdn.bootcss.com/less.js/3.9.0/less.js" type=“text/javascript”></script>监控模式 是客户端的一个功能,当改变样式的时候,客户端将自动刷新。 使用:只需在URL后面加上’#!watch’,然后刷新页面就可以了。服务端使用// 安装 (通过 npm) > npm install less ( npm install less@latest // 安装最新稳定版本 ) // 使用 // 在node中调用编译器 var less = require(“less”); less.render(".class{color:#184e1}”, function(e, css){ console.log(css); }) // 输出 .class { color:#184e1; } // 在命令行下使用 > lessc index.less > index.css // ( 如何要将编译后的 CSS 压缩掉,那么加一个 -x 参数就可以了.)详情请点击 less 官网 。语法1.变量Less 变量 :以 @ 开头 定义变量允许我们定义一系列通用样式,在需要的地方调用。后期调整全局样式|主题的时候,只需修改几行代码就可以,方便快捷,易于维护。// less@boxW:1220px;.container{ width : @boxW;}// 生成css.container{ width : 1220px;}属性变量// less@borderStyle: border-style;@Soild:solid;#wrap{ @{borderStyle}: @Soild;//变量名 必须使用大括号包裹}// 生成的 CSS#wrap{ border-style:solid;}使用变量名定义变量// less@say:" Hello Less ~";@var:“say”;.el{ content: @@var;}// 生成css.el { content: " Hello Less ~";}[注]:当变量作为选择器、属性、URL变量时,变量名 必须使用大括号包裹2.混合Less 混合 :可以将一个定义好的 style1 引入到另一个 style 中,使后者继承前者的所有属性. 与 # 皆可作为 方法前缀。1).无参调用定义一些通用的属性集为一个class,然后在另一个class中去调用这些属性// less.br2 { border-radius: 2px; } // 这样定义,.br2 会暴露到 css 中button{ width:100px; height:50px; .br2; // 等价于 .br2();}// 生成cssbutton { width: 100px; height: 50px; border-radius: 2px;}2).带参调用可以像函数一样定义一个带参数的属性集合:// less.mt(@mt) { margin-top: @mt; }.mb(@mb) { margin-bottom: @mb; }div{ .mt(10px); .mb(20px)}// 生成cssdiv { margin-top: 10px; margin-bottom: 20px;}给参数设置默认值// less.mt(@mt:10px) { margin-top: @mt; }.mb() { margin-bottom: 20px; } // 这样定义,.mb 不会暴露到 css 中div{ .mt; .mb;}// 生成cssdiv { margin-top: 10px; margin-bottom: 20px;}[注]:在 Less 中定义的不带参属性集合,如果想隐藏这个集合( 即 不让它暴露到css 中),但可以在其他地方引用,可以这样写:.mb { margin-bottom: 20px; } 要写成 .mb() { margin-bottom: 20px; }@arguments 变量@arguments 变量 包含了所有传递进来的参数// less.box-shadow (@x: 0, @y: 0, @blur: 1px, @color: #000) { box-shadow: @arguments;}.el{ .box-shadow(2px, 5px);}// 生成css.el{ box-shadow: 2px 5px 1px #000;}数量不定的参数如果你希望你的方法接受数量不定的参数,你可以使用… ,犹如 ES6 的扩展运算符。// less.boxShadow(…){ box-shadow: @arguments;}.textShadow(@a,…){ text-shadow: @arguments;}#main{ .boxShadow(1px,4px,30px,red); .textShadow(1px,4px,30px,red);}// 生成 CSS#main{ box-shadow: 1px 4px 30px red; text-shadow: 1px 4px 30px red;}循环方法( 递归实现 )// less.generate-columns(@n, @i: 1) when (@i =< @n) { .column-@{i} { width: (@i * 100% / @n); } .generate-columns(@n, (@i + 1));}.generate-columns(4);// 生成 CSS.column-1 { width: 25%;}.column-2 { width: 50%;}.column-3 { width: 75%;}.column-4 { width: 100%;}属性拼接+_ 代表的是 空格;+ 代表的是 逗号。// less .boxShadow() { box-shadow+: inset 0 0 10px #555;}.main { .boxShadow(); box-shadow+: 0 0 20px black;}// 生成 CSS.main { box-shadow: inset 0 0 10px #555, 0 0 20px black;}///////////////////////////////// less .Animation() { transform+: scale(2);}.main { .Animation(); transform+: rotate(15deg);}// 生成 CSS.main { transform: scale(2) rotate(15deg);}3.嵌套Less 嵌套 :我们可以在父选择器中嵌套子选择器,实现子继承父。优点:减少了代码量,是结构更加清晰。// less.btn-blue { background-color: #118431;color: #fff; p{ color:#1184e1; } &:hover { background-color: #39a2ed; }}// 生成css.btn-blue { background-color: #118431; color: #fff;}.btn-blue p { color: #1184e1;}.btn-blue:hover { background-color: #39a2ed;}& 符号:串联选择器时使用,代表的上一层选择器的名字。此处例子中:& 直接替换为 .btn-blue 。4.运算Less 提供了加,减,乘,除操作,可以做属性值和颜色值的运算// less@v2-contWidth: 1220px;@v2-m: 20px;@v2-col-1:(@v2-contWidth - @v2-m * 11) / 12;@v2-col-3:@v2-col-1 * 3 + @v2-m * 2;.v2-col-1 { width: @v2-col-1; }.v2-col-3 { width: @v2-col-3; }// 生成css.v2-col-1 { width: 83.33333333px;}.v2-col-3 { width: 290px;}[注]:- 加减法时 以第一个数据的单位为基准 - 乘除法时 注意单位一定要统一5. 继承extend 是 Less 的一个伪类。它可继承 所匹配声明中的全部样式。// less.par{ color:#1184e1; .child{color:#333;}}.sib{ &:extend(.par);}// 生成css.par, .sib { color: #1184e1;}.par .child { color: #333;}6.Color 函数引用官网的例子// return a color which is 10% lighter than @color// 返回比@color轻10%*的颜色lighten(@color, 10%); // return a color which is 10% darker than @colordarken(@color, 10%); // return a color 10% more saturated than @color// 返回比@color饱和10%以上的颜色saturate(@color, 10%); // return a color 10% less saturated than @colordesaturate(@color, 10%); // return a color 10% less transparent than @color// 返回比@color少10%的颜色透明fadein(@color, 10%); // return a color 10% more transparent than @colorfadeout(@color, 10%); // return @color with 50% transparency// 返回@color,透明度为50%fade(@color, 50%); // return a color with a 10 degree larger in hue than @color// 返回颜色比@color大10度的颜色spin(@color, 10); // return a color with a 10 degree smaller hue than @colorspin(@color, -10); // return a mix of @color1 and @color2// 返回@ color1和@ color2的混合mix(@color1, @color2); 7.Math 函数引用官网的例子round(1.67); // returns 2ceil(2.4); // returns 3floor(2.6); // returns 2// 将一个值转化为百分比percentage(0.5); // returns 50%8.匹配| 引导1).匹配 (根据值和参数匹配)只有被匹配的混合才会被使用。变量可以匹配任意的传入值,而变量以外的固定值就仅仅匹配与其相等的传入值。// 语法.mixin (@s, @color) { 。。。 }.class { .mixin(@switch, #888);}// 让.mixin根据不同的@switch值而输出内容// less.mixin (dark, @color) { color: darken(@color, 10%);}.mixin (light, @color) { color: lighten(@color, 10%);}.mixin (@_, @color) { // 如果匹配的参数 是变量,则将会匹配,如 @_ 。 display: block;}@switch: light;.class { .mixin(@switch, #888);}// 生成css.class { color: #a2a2a2; display: block;}2).引导 (根据表达式进行匹配)when关键字用以定义一个导引序列,来实现条件判断。导引中可用的全部比较运算有: >、 >=、 =、 =<、 < 。= 代表的是等于// less.posi (@posi, @bdw) when (@posi = ’top’) { border-top-width:@bdw;}.posi (@posi, @bdw) when (@posi = ‘bottom’) { border-bottom-width:@bdw;}.line(@posi, @bdw){ .posi(@posi, @bdw);}.v2-line_t_s-e5{ .line(’top’, 1px);}.v2-line_b_s-e5{ .line(‘bottom’, 10px);}// 生成css.v2-line_t_s-e5 { border-top-width: 1px;}.v2-line_b_s-e5 { border-bottom-width: 10px;}导引序列使用逗号‘,’—分割,当且仅当所有条件都符合时,才会被视为匹配成功。.mixin (@a) when (@a > 10), (@a < -10) { … }基于值的类型进行匹配,我们就可以使用is函式.mixin (@a, @b: 0) when (isnumber(@b)) { … }// 常见的检测函式:iscolorisnumberisstringiskeywordisurl// 判断一个值是纯数字,还是某个单位量ispixelispercentageisem在导引序列中可以使用and关键字实现与条件;使用not关键字实现或条件.mixin (@a) when (isnumber(@a)) and (@a > 0) { … }.mixin (@b) when not (@b > 0) { … }9.命名空间为了更好组织CSS或者单纯是为了更好的封装,将一些变量或者混合模块打包起来,之后可以重复使用#bundle { .button () { border: 1px solid black; &:hover { background-color: white } } .tab { … } .citation { … }}// #header 的子元素 a 有 .button 的样式,// 可以这样:#header a 中引入 .button#header a { color: orange; #bundle > .button;}–>// 等价于#header a { color: orange; #bundle; .button;}<–// 生成css#header a { color: orange; border: 1px solid black;}#header a:hover { background-color: #ffffff;}[注]: 1.父元素不能加 括号。如:#bundle > .button 2.不得单独使用命名空间的方法。如:.button // 会报错10.作用域LESS 中的作用域跟其他编程语言非常类似,首先会从本地查找变量或者混合模块,如果没找到的话会去父级作用域中查找,直到找到为止.一句话理解就是:就近原则@var: red;#page { @var: white; #header { color: @var; // white }}#footer { color: @var; // red }11.字符串插值变量可以用类似ruby和php的方式嵌入到字符串中,像@{name}这样的结构:@base-url: “http://assets.fnord.com”;background-image: url("@{base-url}/images/bg.png");12.避免编译有时候我们需要输出一些不正确的CSS语法或者使用一些 LESS不认识的专有语法.要输出这样的值我们可以在字符串前加上一个 ~将要避免编译的值用 “”包含起来,结构: ~’ 值 ‘.class { filter: ~“ms:alwaysHasItsOwnSyntax.For.Stuff()”;}// 输出为.class { filter: ms:alwaysHasItsOwnSyntax.For.Stuff();}13. JavaScript 表达式JavaScript 表达式也可以在.less 文件中使用。// 可以通过反引号的方式使用@var: "hello".toUpperCase() + '!'; –> @var: “HELLO!”;// 可以同时使用字符串插值和避免编译@str: “hello”;@var: ~"@{str}".toUpperCase() + '!'; –> @var: HELLO!;// 可以访问JavaScript环境@height: document.body.clientHeight;// 将一个JavaScript字符串解析成16进制的颜色值, 你可以使用 color 函数@color: color(window.colors.baseColor);@darkcolor: darken(@color, 10%);14.其他reference// 使用@import (reference)导入外部文件,但不会添加 把导入的文件 编译到最终输出中,只引用。@import (reference) “bs.less”; ...

January 24, 2019 · 4 min · jiezi

vuex重置所有state(可定制)

在正式场景中我们经常遇到一个问题,就是登出页面或其他操作的时候,我们需要重置所有的vuex,让其变为初始状态,那么,就涉及到了多种方法:1、页面刷新:window.location.reload()这个方法通过路由判断优化或是逻辑优化,始终页面时重新加载,就会导致用户体验很差,对浏览器来说也是一种不必要的负担,所以我尝试之后就放弃了。2、写一个重置的方法然后调取actions.resetVuex = function() { store.commit(state.a, null) store.commit(state.b, null) store.commit(state.c, null) …}store.dispatch(‘resetVuex’)这样又会出现多个module,多个state,需要手动添加多个,工作量巨大且不易维护,而且如果我们state初始是个个数组,一个对象这些更不好操作,更优最多就是我们初始的时候深拷贝一份,但是也需要每个module里进行操作和封装这两种方法是可以解决问题的,但是我还是没有采用这两种方式,因为感觉已经牺牲了某些东西来达成目的了,通过我反复的实践,和摸索我采取了以下方法:首先页面加载,第一次加载引入store的时候,store的所有state肯定是初始值,那么我就做一个本地缓存记录下来:这里我采用了store插件(引用方式参考 https://github.com/nbubna/store)在main.js创建vue实例之前:import _store from ‘store’import createStore from ‘./store’…const store = createStore() //我创建好的 vuex库_store({ initState: store.state }) //缓存一个名为initState的初始状态我们知道main.js是页面载入的时候执行一次的那么缓存的initState就是自己最开始创建store里的state状态(包含了module里的所有state);然后我们在store创建的全局写一个mutation方法这里我采用了store插件(引用方式参考 https://github.com/nbubna/store)这里我采用了lodash插件(引用方式参考 https://www.lodashjs.com/)import _ from ’lodash’import _store from ‘store2’…const store = new Vuex.Store({ state: { token: ’’ }, mutations: { resetAllState (state, payload) { if (payload instanceof Array === false) { // 验证传入的是一个数组 return } const initState = _store(‘initState’) // 取出初始值的缓存 const _initState = payload.length ? _.omit(initState, payload) : initState // 判断传入值有无数据,有数据剔除相对应的值 _.extend(state, _initState) } }, modules: { … } })这个名叫resetAllState的mutation方法里就是讲全局的state替换成我们缓存的state。这里为什么 payload 是一个数组呢?因为这就是标题所描述的可定制,如果页面内重置绝大部分状态,但需要保留其中一些状态的时候我们可以通过我们传递过来的state值来剔除相应的state,使其不被更新。当然我们也可以传入值来更新相应值,其他所有值不进行更新(这里我们就不详细说明)以上,就是我实践思考出来的方法,可能有不足的地方,欢迎大家提问、交流或提出更好的建议。谢谢 ...

January 17, 2019 · 1 min · jiezi

less学习之Bootstrap(按钮篇)

less学习之Bootstrap按钮篇)如我上一篇less学习之Bootstrap里面,介绍了Bootstrap的目录结构,说明了在variables.less这个文件里面,定义了主题色,也包括了按钮的主题色。接下来看一看 buttons.less与 mixins/buttons.less.文件 buttons.less 与 mixins/buttons.less内容不是很多,总结下来就是:1、“.btn”的基础样式定义。2、按钮的各种状态含义的样式定义,例如:btn-primary、btn-success等。3、伪连接,按钮的样式显示为连接的样式。4、按钮尺寸的class:lg、sm、xs。5、input类型的按钮定义。基础样式定义代码:.btn { display: inline-block; … … &, &:active, &.active { &:focus, &.focus { .tab-focus(); } } … …// 余下的为hover、disabled时的样式}说明:知识点1:&amp;在less与scss的语法中,表示同父级,就上一个例子来说,就是编译之后&amp;将会被.btn替换,如果是多层时也是相同的道理。提示1:运用了函数tab-focus。此函数定义在mixins/tab-focus.less中,代码很短.tab-focus() { outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px;}修改浏览器默认的大纲样式:表现在按钮、form表单等原生组件上。提示2: 运用了函数user-select。此函数定义在mixins/vendor-prefixes中。.user-select(@select) { -webkit-user-select: @select; -moz-user-select: @select; -ms-user-select: @select; // IE10+ user-select: @select;}作用,让文本是否能够选择。提示3: 运用了函数opacity。此函数定义在mixins/opacity中。.opacity(@opacity) { opacity: @opacity; @opacity-ie: (@opacity * 100); filter: “alpha(opacity=@{opacity-ie})”;}此处做了IE的兼容IE,IE的透明度采用 filtger:alpha(opacity=value),其中 0 <= value && value <= 100.符号“”,可以意为JavaScript里面的 evel ,可以将字符串转化为表达式。所以说一些复杂的选择器也能够作为变量定义。特别说明函数button-variantBootstrap里面抽象出来的函数,作用于按钮不同状态下的颜色变化。例如:hover、focus、active等状态。函数说明参数:@color; @background; @border // 分别时字体颜色、背景颜色、边框颜色结构如下:.button-variant(@color; @background; @border) { color: @color; background-color: @background; border-color: @border; &:focus, &.focus { color: @color; background-color: darken(@background, 10%); border-color: darken(@border, 25%); } … …// 余下的为hover、disabled时的样式 .badge { color: @background; background-color: @color; }}由上面两个文件可以总结出的结论是:.less里面写的是选择器定义、变量定义,而mixins/.less里面写的是函数。本篇总结关于Bootstrap听到过不少的见闻,有好有坏,我有身边也有人说这个框架很垃圾。但是对于Bootstrap这个框架怎么样,我不做评价,但是Bootstrap用来作为学习的资料时非常合适的,Less的语法糖都了知道,那么如何才能让Less用起来得心应手?无疑,源码是一种途径。接下来的安排,自己写的文章自己也会去实现它,另外关于Less的学习也不会停止。 ...

January 16, 2019 · 1 min · jiezi

vue-cli中vuex IE兼容

vue-cli中使用vuex的项目 在IE中会出现页面空白 控制台报错的情况:我们只需要安装一个插件,然后在main.js中全局引入即可安装 npm install –save-dev -polyfill引入 import ‘babel-polyfill’

January 16, 2019 · 1 min · jiezi

less学习之Bootstrap

less学习笔记之bootstrap目录说明源代码里面的目录是这样的(只给出部分): .csscomb.json│ .csslintrc│ alerts.less│ badges.less│ bootstrap.less│ breadcrumbs.less│ button-groups.less│ buttons.less│ carousel.less│ close.less│ …│└─mixins alerts.less background-variant.less border-radius.less buttons.less center-block.less clearfix.less forms.less gradients.less …文件 variables.less顾名思义,为整个Bootstrap定义的全局变量。知识点一:Less的作用域和css很相似,变量和混合(mixins)在当前文件无法找到时会继承父级作用,如果任然没有找到则会编译抛出异常。定义在Bootstrap中使用的灰色和品牌颜色。@gray-base: #000;@gray-darker:lighten(@gray-base, 13.5%);@gray-dark: lighten(@gray-base, 20%); @gray: lighten(@gray-base, 33.5%); // #555@gray-light: lighten(@gray-base, 46.7%); @gray-lighter: lighten(@gray-base, 93.5%); // 这部分定义的主要色:成功、失败、警告等等。@brand-primary: darken(#428bca, 6.5%); // #337ab7@brand-success: #5cb85c;@brand-info: #5bc0de;@brand-warning: #f0ad4e;@brand-danger: #d9534f;具体体现:知识点2:函数 lighten与darken描述: 参数:color, amount, method功能: color + amount 表示在color的基础上,变得更淡或者更深,加上method后表示在color * method 的基础上,变淡/深 amount,这里先不解释less中色值是怎么计算的。之后也定义了默认背景色。定义字体风格字体大小定义Bootstrap的基础字体为14px。知识点3:函数ceil和floor简单说明:分别为向上取整和向下取整输入框风格定义cursor:not-allowed //当button与input处于disabled时,鼠标指针的样式优先级定义设置一些默认层级优先级z-index,用于特定的组件,例如:navbar、dropdown、popover、modal-background、tooltip、navbar-fixed。值都为1000+,这也就是有时候我们自己自定义了一些优先级,但是还是达不到效果,可以想一想是不是值不够?

January 15, 2019 · 1 min · jiezi

Less 函数巧妙解决白天和夜间模式

前言最近接到一个需求,是做白天和夜间模式的切换,里面涉及到背景色,主要文字色,副标题,备注的相关颜色的切换。由于是在老代码中进行改造,而且目前css是用less写的。思路正常情况下,做这个实现,基本有以下方法拷贝一份原有样式,把最上层的样式名加个 -dark, 重写内部子层级的样式,然后在按外部模式引用。Less 函数,定义一个less函数,传递不同的颜色值进去Less 函数,传递模式名称进去,在函数内部定义出需要变更的颜色属性,动态加入模式名称第一种:哈哈,很多人下意识是这种方法。但是,两套模板,你要改下样式的话,两套都要改,不符合我们的易维护的理念,舍弃。第二张:不错的想法,目前网上搜到过几种这样的方式。但是存在一个问题,要传很多参数,以后变化起来又要加参数,使用起来不是很方便。第三种:SIX SIX SIX,只传入主题名。调用起来很方便。核心理念,用函数式想法解决CSS重复问题。实现这里的实现,我就只写第三种了。第一步:定义出不同主题色第二步:定义模式切换方法,利用 Less 变量插值拼接出主题色变量,然后在样式里@@取值第三步:根据模式字段判断,引用不同的主题了 ,如下 白天引用 .test 夜间用 .test-dark// 白天色@bgColor: #F7F8FA;@textColor: #333333;@subTextColor: #666666;@tipsColor: #CCCCCC;@errorColor: #EE6560;// 夜间色@bgColor-dark: #171B30;@textColor-dark: #FFFFFF;@subTextColor-dark: rgba(255, 255, 255, 0.6);@tipsColor-dark: rgba(255, 255, 255, 0.4);// 模式切换.styleChange(@theme) { // 定义页面显示各种颜色,拼接 theme 主题 @bgColor: “bgColor@{theme}”; @textColor: “textColor@{theme}”; @subTextColor: “subTextColor@{theme}”; @tipsColor: “tipsColor@{theme}”; width: 100%; background: @@bgColor; // 使用 @@style 双@的方法取值}// 白天模式.test { .styleChange(’’); // 执行less 函数}// 夜间模式.test-dark { .styleChange(-dark); // 执行less函数,传入 -dark ,表示夜间}写在最后好久没有更新了,谢谢关注的朋友,我胡汉三又回来了。

January 14, 2019 · 1 min · jiezi

前端性能优化从css说起

我们都知道性能对于一个网站来说相当重要,以至于很多公司都会专门招聘人员优化网站性能,网上关于探讨网站性能优化的文章也非常多。性能是什么呢?简单来说,就是用户打开网站到网页完全呈现在用户面前所耗费的时间,研究表明:用户最满意的打开网页时间是2-5秒,如果等待超过10秒,99%的用户会关闭这个网页。影响网站的性能有多重因素,我们就着重从前端方面来进行探讨,首先我们先了解一下网页的解析过程。主要过程有:1.解析HTML构建DOM树 ;2.解析css构建CSSOM树 ;3.根据DOM树和CSSOM来构造 Rendering Tree(渲染树);4.Layout页面位置计算布局; 5.Paint绘制;css的加载不会阻塞DOM树的解析,但是会阻塞DOM树的渲染和后面js语句的执行,所以说才有了优化css的必要性,针对这一问题,我们可以从以下方面进行考虑优化。1.结合构建工具(webpack,gulp…),对css文件进行打包压缩,抽离公共样式,删除多余的样式、空格、注释。2.减少样式选择器的层级,减少样式匹配时间。 3.尽量使用class选择器,增强样式的复用;中还有两个重要的知识点repaint(重绘)和reflow(回流),repaint主要是针对某一个DOM元素进行的重绘,reflow则是回流,针对整个页面的重排,我们都知道这两个特性都会消耗网页性能,他们的触发场景也是不同的。不涉及任何DOM元素排版问题的变动为repaint,例如元素的color/text-align/text-decoration等等属性的变动,除上面所提到的DOM元素style修改基本为reflow,例如元素的任何涉及长、宽、行高、边框、display等style的修改。很多时候我们是无法避免引起repaint和reflow,但是我们还是要尽量通过各种方法来减少引起这两个特性,我们可以从以下方面进行考虑优化。1.尽可能在DOM末梢通过改变class来修改元素的style属性:尽可能的减少受影响的DOM元素。2.避免设置多项内联样式:使用常用的class的方式进行设置样式,以避免设置样式时访问DOM的低效率。3.设置动画元素position属性为fixed或者absolute:由于当前元素从DOM流中独立出来,因此受影响的只有当前元素,元素repaint。4.牺牲平滑度满足性能:动画精度太强,会造成更多次的repaint/reflow,牺牲精度,能满足性能的损耗,获取性能和平滑度的平衡。5.避免使用table进行布局:table的每个元素的大小以及内容的改动,都会导致整个table进行重新计算,造成大幅度的repaint或者 reflow。改用div则可以进行针对性的repaint和避免不必要的reflow。6.避免在CSS中使用运算式:学习CSS的时候就知道,这个应该避免,不应该加深到这一层再去了解,因为这个的后果确实非常严重,一旦存在动画性的repaint/reflow,那么每一帧动画都会进行计算,性能消耗不容小觑7.css放在head中,减少引起repaint和reflow;接下来我们再来讨论一下base64图片与CssSprites(雪碧图或css精灵),在网页中我们会用到很多图标,如果每一个图标是单独的一张图片,那网页加载的时候,就会有多个请求去请求图片,显而易见会影响网页性能,所以要采取方法对网页中图标使用进行优化处理。Css Sprites(雪碧图):将许多的小图片整合到一张大图片中,利用css中的background-image属性,background-position属性定位某个图片位置,来达到在大图片中引用某个部位的小图片的效果。优点:减少网页的http请求,提升网页加载速度;合并多张小图片,减少资源体积。缺点:前期需要处理图片,增加工程量;不利于改动和维护。&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbspbase64编码:base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,要求把每三个8Bit的字节转换为四个6Bit的字节,Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,通俗点来讲就是将资源原本二进制形式转成以64个字符基本单位,所组成的一串字符串。优点:减少http请求;图片可以避免跨域问题。缺点:低版本IE不兼容;过多使用base64图片会使得css过大,不利于css加载和解析;&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp在网页开发中我们经常会在引入图片,也会使用到上面两种方法来优化处理网页,他们有各自不同的使用场景。Css Sprites 主要针对一些不需要经常变动的小图片,如表情,标志等,base64主要适用于小于几k的图片,图片太大的话反而得不偿失。&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbspcss洋洋洒洒写了一些关于css优化的东西,当然也汲取了前辈们的智慧,算是总结一下吧,我相信关于css的优化知识还有很多,不断学习吧!!

January 5, 2019 · 1 min · jiezi

百度云曲显平:AIOps时代下如何用运维数据系统性地解决运维问题?

本文是根据百度云智能运维负责人曲显平10月20日在msup携手魅族、Flyme、百度云主办的第十三期魅族技术开放日《百度云智能运维实践》演讲中的分享内容整理而成。内容简介:本文主要从百度运维技术的发展历程、如何做智能运维、故障管理场景、服务咨询场景和面对的挑战等几个方面介绍了百度云智能运维实践。百度运维技术的三个阶段第一阶段:基础运维平台 2008年2012年2008年,在百度运维部建立之前,还没有一个标准而统一的运维平台。例如,搜索、广告、贴吧都有各自的运维平台。存在的问题:技术和平台能力无法复用,业务之间需要交互时比较复杂。解决方法:①为帮助业务解决问题,我们把各个分散在不同业务的运维平台整合起来做成一套标准化运维平台;②有了统一运维平台后,运维部门内的角色就分为了两个,即标准的运维工程师和运维平台研发工程师。第二阶段:开放的运维平台 2012年2014年第一阶段仍然存在的问题: ①个性化需求很多,统一平台很难全部解决②PaaS出现之后,运维平台和PaaS的关系解决方法:①开放运维平台,即全部API化。②通过提供标准化的监控数据的采集、计算、报警能力,最基础的程序分发、数据分发、任务调度能力,解决自身平台的需求。③利用PaaS方法,把一些研发的技术平台和运维技术平台整合在一起,解决重复造轮子的问题。第三阶段:AIOps阶段 2014年开始百度从2014年就开始了智能运维的实践。最早的时候,我们更多是通过完善底层的大数据平台能力,提供一些数据分析和挖掘的算法和工具,解决运维数据没有得到合理运用,运维人工效率低等问题,这是偏大数据的方法。百度对于AIOps的理解在2015年,AI变得异常火热,百度也是想将自身先进的机器学习算法应用到运维领域之中,于是我们和百度的大数据实验室、深度学习实验室进行了合作。运维研究人员把需求和归整好的数据提交给实验室的人员,然后他们会根据数据训练模型,最终提供一些库和方法供业务使用。2016年,Gartner提出了AIOps这个词,也就是我们说的智能运维,这和百度的实践是不谋而合的。三个核心内容随着智能运维的发展,百度也是把数据、工程和策略三个,作为最核心内容来系统地解决运维行业的应用。从数据角度来讲,首先要构建一个完整的数据仓库,接着要建设运维知识库。知识库是在数据仓库上抽象进行的。从工程角度,一方面,分析数据和训练算法模型需要大数据平台和框架,另一方面,运维业务研发人员还做了一套运维工程研发框架,用以解决标准化、可扩展和复用的问题。这个框架十月份刚刚开源,感兴趣的朋友可以看下。在百度内部,一致的运维“语言”非常关键。我们要统一不同的工具和平台,形成一致的运维模式。所以不管是故障感知、故障诊断决策、弹性伸缩决策还是运维操作和执行,只有统一起来才能解决这个问题。一致不仅是数据一致、工程一致,还需要策略本身的一致性。自动驾驶分级在构建整个百度智能运维体系的过程中,我们重点参考了自动驾驶里的分级理论。百度是有这样两个部门的,一个叫L3,一个叫L4。L3部门重点在做类似于辅助驾驶或者高度辅助驾驶;L4部门做的是高度完全自动驾驶。下图是关于自动驾驶的分级。运维能力分级自动化运维能力分级当时我们团队参照这个自动驾驶分级,构建出了一个自动化运维能力的分级标准,用以评估我们各个方向的自动化水平,一共分为六个能力等级,即人工、工具辅助、部分自动化、有条件的自动化、高速自动化和完全自动化。关键点:决策规划由运维系统做出,而不是人人负责:制定优化目标(比如,可用性、效率、成本等)运维系统负责:根据其对待处理的需求、待解决的问题的理解,以及对运维对象的认知(经验),自主做出解决方案(规划)并在控制执行过程中根据目标和运维对象的状态反馈来适时调整执行规划。智能化运维能力分级在自动化能力分级之中,我们还细化出了一个智能化运维能力分级(我们始终认为智能运维是实现完全自动化运维的一种手段)。实现智能化能力,重点解决的是在运维感知和决策过程中,人工效率低和准确率不足的问题。关键点:决策规划由运维系统做出,而不是人人负责:制定优化目标(比如,可用性、效率、成本等)运维系统负责:根据其对待处理的需求、待解决的问题的理解,以及对运维对象的认知(经验),自主做出解决方案(规划)并在控制执行过程中根据目标和运维对象的状态反馈来适时调整执行规划。如何做运维我们希望每一个运维工具都像一个小型的运维机器人一样,解决运维的问题。运维工程师需要把每一个运维工具抽象化,同时也要像一个标准框架一样,可以在代码库里克隆,把框架代码复制下来。通过三个基本核心,感知、决策和执行来进行编写执行器,接着可以通过配置实现一些具体任务调度的配置或者并发执行的配置;每一个运维工程师要实现感知逻辑、决策逻辑、执行逻辑,利用运维核心解决可靠性的问题。在测试方面,要在线下建立看代码的逻辑去验证。结合这个看代码,把比较核心的运维故障抽象出来,再把一些常见的故障模拟出来,具体的情况可以在这里面运行;写完一个运维工具或者算法,需要直接在上面运行,从而检测出是否有效。故障处理场景百度内部如何解决故障处理场景故障处理场景一般分四个主要阶段:故障发现、服务止损、服务恢复、故障总结。在服务止损方面,核心是如何让用户感知不到这个故障,对于运维来讲,更多用的方法是隔离、降级,而非从代码BUG入手解决的问题。在服务恢复方面,这个一般是在服务止损或者说故障被隔离之后,很大程度上需要运维和研发共同合作,比如定位代码的BUG,最终要决定如何把线上的问题真正解决掉。恢复,更多用的是修复来解决。在百度,大多数的故障都是可以用隔离和降级解决的,只有那些极特殊的case,才会通过程序回滚来恢复。回滚风险很大,而且效率很低。在整个解决故障处理场景的阶段,每一个阶段都可以结合智能运维的方法。从开始服务部署、监控添加、故障发现、止损决策、止损操作、根因诊断、恢复操作,最后报告自动生成。把AIOps应用到故障处理最核心的基础是,全面覆盖监控。在百度,做的最全面的是云上的监控,所以包含这四个维度的监控:系统监控、业务监控、内网监控和外网监控。系统监控主要的监控对象是机器/容器和服务的动态内容;业务监控针对业务和用户的访问日志等;内网监控则针对IDC内网设备和内网链路;外网监控为了保障用户、运营商链路到百度IDC中间的状态。有了全面的监控之后,才能开始现在业界常提到的一个智能运维技术,自动异常检测。典型的异常检测场景有关异常检测场景,我为大家举三个典型的例子,第一个,周期波动的数据。上图中的蓝、绿、黄三条线分别代表着今天、昨天、上周的时间线,蓝线比较明显,后面还有绿线和黄线。它们相对来说周期性体现得特别强。这种数据很难用传统的计算方法设置阈值。针对这种场景,我们会使用不同类的算法,专门解决这种问题。第二个,关心突变的数据。突变的数据也是一个比较典型的场景,周期性数据更多参考的是天级和周级的数据,而这个场景更多说的是某一个细节层面,可以理解为它是对一小块数据的放大。第三个,关心是否超出了一定波动范围的数据。这种场景是我们用普通的监控方法很难覆盖的,很多情况下,其均值或基线不会有特别明显的变化,但系统现在确实出现了很大的不同状态,可能仅仅是波动更剧烈了,对于这类场景,我们更多的是去看波动的情况,就是除基线以外的一些特征。今年八月份,百度云开源了一个数据标注的工具-Curve 。我们始终觉得算法虽然很重要,但远没有数据本身重要。做机器学习时,数据的建设才是最需要花时间解决的问题,百度的运维工程师也是重点在解决数据标准和数据获取的问题。如何应对报警风暴当出现大规模报警时,手机可能会直接被打爆。异常检测重点解决的是故障感知的问题。当故障被感知后,需要通知给运维工程师。首先,做逐级通告,对报警进行分级。接着做数据的整理,整理出每一个数据,最后抽象化数据的特征,按照每个维度或特征进行报警的归并。完成前两步之后,报警会有一定改善。最后要用数据分析方法或者机器学习的方法处理。数据的特征已经被抽象化,所以有很多方法可以解决,第一种方法是传统数据挖掘,比如关联分析,频繁项集挖掘是最被广泛使用到的方法,它可以有效将同类报警进行合并。第二种方法是机器学习,因为前面抽象出了特征,那做分类聚类都是比较直接的事情。从我们的实践情况看,最后的效果两者相差不大,大家都可以尝试。报警产生后,就相当于感知阶段结束,之后就到达故障处理阶段。接下来,我分享几个百度内部觉得效果最好的处理方法。第一个方法,多维度定位。这个更多偏业务问题的定位。业务都有访问日志,日志由各个不同维度的数据组成。一个故障的出现可能有不同维度,运维工程师需要通过访问日志的数据进行计算分析,分析出真正影响故障的维度。在这个基础上,可以做可视化。这是一类结合业务特征的可视化方法,如上图,这是一个模块拓扑图,很多圈圈,很多研发,这里有健康度、响应时间等等各种维度的展示。像模块响应时间,又可能会分很多类、很多维度或者很多模块,底下是每一个不同的模块,都可能产生对应的一些情况。接下来,百度现在大部分在用的是基于信息熵的维度特征推荐。例如,一个出现故障问题的指标,大的流量下降,可能有不同的维度。运维工程师会对每一个维度里的子维度数据进行分析,分析下降的程度,以及对于现在整个流量总体的下降程度的不同占比,然后做一个排序,就可以得到故障影响较高的某几个维度,从而帮助工程师尽快定位到这个问题或者缩小问题的范围。第二个方法,基于服务拓扑或者服务关联做定位。这是内部比较重要的故障判断基础和指导意见。百度运维倾向于把一个问题的分析分成六个维度:①时间维度,缩小时间范围;②网络拓扑模型,缩小空间范围,区分整体和局部故障;③服务管理模型,推导异常集群、实例或者机器;④变更关联模型,定位程序、配置、数据、运营活动上线;⑤模块关联模型,上下游关联服务的异常传播链;⑥多维度模型,维度关联层级分析,缩小业务范围。上图是一类典型的故障诊断框架。我们可能有很多故障的分类,比如有网络故障,细分一点是有交换机故障、链路故障,可能有系统故障,业务问题、操作问题等各种各样的,都是属于假说生成,可能都是备选故障问题。中间有一个证据评分,相当于基于前面的模型拓扑关系,对不同的故障做评分,把拓扑关系的线做权重,然后做置信计算和排序,最后给出最优决策判断。有关自愈的问题· 故障自愈 通过自动化、智能化处理故障节省人力投入,通过预设定的处理流程和只能化判断策略,提高故障处理可靠性,同时降低故障时间,为业务可用性保驾护航。· 智能自愈①感知:通过监控系统获取业务运行指标、智能异常检测、网络异常事件多种触发方式②决策:根据不同感知方式可以配置不同决策模型③执行:在单机执行基础上,提供集群级别、分布式的处理方式在执行故障自愈过程中,并不止是一个工具的执行,而是包括了调度、伸缩、隔离预案处理甚至多个不同业务的联动。自愈本身的核心并非自动化过程,更多是决策的过程。举一个典型案例叫单机房故障自愈。单机房,不仅仅指机房网络故障,更多指的是故障范围只要限定在一个IDC内部,不管这个故障是代码BUG,还是外面流量接入出了问题,还是机房整个掉电,只要故障范围是在一个IDC内都可以解决。基础能力达标后,我们要设计一个故障自愈系统,核心部分是外网流量调度止损决策器和内网流量调度止损决策器。外网比较简单,而内网则涉及到一些负载均衡策略、弹性伸缩策略、主备切换策略等。盲测验收最后讲一下盲测验收。有了故障自愈的系统后,怎么证明你的方案好用呢?在不通知业务的情况下,我们会和IDC同事进行配合,拔网线或是制造网络拥塞,这时候才能进行完整的切换,从而可以证明基础能力是否达标。百度现在单机房故障自愈已经覆盖了所有核心业务线,自愈时效控制在5分钟内,并且对于非数据库依赖的业务,可以做到1-2分钟完成机房级自愈。咨询服务场景服务咨询的场景可分为以下三种:①通过聊天窗口(IM软件、浏览器等)实时查询业务状态,用户可视化、可追查各种问题;②通过聊天窗口(IM软件、浏览器等)实时触发运维操作,运维工程师可远程上线、启停任务等;③当运维操作完成,出现状态变化或异常等情况时,运维工程师可主动发送相关通知,或按照策略自动进行后续操作。在百度内部,我们将这种场景称为ChatOps:•“放心”:分级发布和可用性干预、保障•“贴心”:监控、部署一站式集成,信息主动推送和确认•“省心”:高度自动化,减少人工介入和等待•“开心”:助力业务发展,如迭代效率提升•将运维人员从日渐琐碎、枯燥、疲惫、低价值、高事故率的工作中解放出来•实现运维人员的转型和增值AIOps的挑战最后说一下AIOps的挑战。现有的AIOps技术,比如指标异常检测、故障自愈等,更多解决的是数据本身的特征和问题,还没抽象到服务、程序本身的特征这个层次上,也就是说,我们并没有真正地了解和解决问题本身。比如,不同类的服务所产生的故障和表征是不一样的,我们希望让数据更多、业务场景可扩展,而非针对几个横向的场景;在业务运营方面,我们不仅仅局限在IDC、操作系统、机器,而是注重资源和性能优化,运维还可以继续拓展。对内,可以做系统优化、成本优化;对外,帮助所有用户做云服务资源池优化,让大家更好的节约成本,提升服务能力。以上内容来自曲显平老师的分享。声明:本文是由msup原创,转载请联系 meixu.feng@msup.com.cn

December 29, 2018 · 1 min · jiezi

支付宝小程序编译less

最近在踏坑支付宝小程序,目前支付宝小程序的框架还不是很成熟,然后项目要求比较高,为了避免一些无法预料的坑,所以选择了原生的支付宝小程序的开发。支付宝小程序是不支持less编译的,对于习惯了各种变量,各种minxin写法的我来说十分的不方便。把wxss-cli,稍微改造一下即可支持支付宝小程序的less编译。1.全局安装wxss-cli,把改造过的包放在全局的node_modules中(下载地址)2.在对应的页面目录中新建less文件,例如:原本目录中有.acss .axml .js .json四个文件,同目录下新增与.acss同名的less文件(注意同名哈)3.运行编译命令 进入项目目录中,指定编译的目录,比如编译pages下面所有的less文件wxss ./pages4.其他命令wxss -V 查看版本wxss -h 查看帮助

December 28, 2018 · 1 min · jiezi

vue-cli2.0转3.0之项目搭建

因为项目技术架构需要,要是用vue-cli 3.0进行搭建,所以简单的分享下3.0如何优雅的开始。下面做一下简单的介绍,希望可以帮到有需要的朋友。vue-cli 3.0 正式版于 8月10号发布!首先,既然不是一个版本,如果想使用V-C3,你需要卸载之前安装的2.0(有方式可以共存,暂不赘述),卸载了不会影响你以前的功能,使用不爽,可以再安装回去,安装就不说了,说下卸载。第一步 卸载Vue-cli2命令是:npm uninstall -g vue-cli第二步 安装V-C3.0方式很多,譬如 npm install -g @vue/cli 或者 yarn global add @vue/cli,根据嗜好,自选。第三步 创建项目相对2.0,V-C3创建就不是之前init webp….. 一大堆了。直接 vue create project,project是项目名字。so easy,如下图(mac报err-13,请使用sudo):我选了默认,没用淘宝镜像,选择Y后,会有如下图所示:这个时候你可以选择会车确认,但是个人建议,进行多选,根据自己需要选择,选择Manua…这一行,然后就会出现:自己空格就可以选择了,除了E2E,都是我需要的,所以如上图所选。回车后,显示: Use class-style component syntax? 接下来就不细说了,一路Y就可以。最终,我的选择如图,设置成功:最终目录为:第三步 干活吧安装成功后,可以写业务了。根据提示,运行一把,feel一下 3.0666,跑起来的感觉很棒。

December 10, 2018 · 1 min · jiezi

css-in-js 探讨

Web开发是需要掌握多种技术。我们习惯于与多种语言密切合作。而且,随着开发Web应用程序变得越来越普遍和差别细微化,我们经常寻找创造性的方法来弥合这些语言之间的差距,从而使我们的开发环境和工作流程更容易,更高效。最常见的示例通常是使用模板语言时。例如,可以使用一种语言来生成更详细的语言(通常是HTML)的代码。这是前端框架的关键作用之一 -操作HTML。这个领域最出名的就是JSX,因为它不是真正的模板语言;它是JavaScript的语法扩展,它使得使用HTML非常简洁。Web应用程序经历了许多状态组合,单独管理状态通常很有挑战性。这就是为什么CSS有时会被淘汰的原因 - 即使通过不同的状态和媒体查询管理样式同样重要且同样具有挑战性。在这个由两部分组成的系列中,我想将CSS放在聚光灯下,并探索弥合它与JavaScript之间的差距。在本系列中,我将假设您正在使用像webpack这样的模块解析器。因此,我将在我的示例中使用React,但相同或类似的原则适用于其他JavaScript框架,包括Vue。CSS领域正朝着多个方向发展,因为要解决许多挑战并且没有“正确”的路径。我一直在花费大量精力尝试各种方法,主要是在个人项目上,所以这个系列的目的只是告知,而不是给你解决方案。CSS的挑战在深入研究代码之前,有必要解释Web应用程序样式化方面最显着的挑战。 我将在本系列中讨论的是范围,条件和动态样式以及可重用性。作用域作用域定是众所周知的CSS挑战,它的目的是编写不会影响到组件外部的样式,从而避免意外的副作用。 我们希望在不影响编码体验的情况下实现功能。条件和动态样式虽然前端应用程序中的状态开始变得越来越先进,但CSS仍然是静态的。 我们只能有条件地应用样式集 - 如果按钮是主要的,我们可能会应用“primary”类并在单独的CSS文件中定义它的样式以应用它在屏幕上的样式。 有几个预定义的按钮变化是可管理的,但如果我们想要有各种按钮,如为Twitter,Facebook,Pinterest定制的特定按钮,可能还会有其他很多种? 我们真正想要做的只是传递颜色并使用CSS定义状态,如悬停,焦点,禁用等。这称为动态样式,因为我们不再在预定义样式之间切换 - 我们不知道接下来会发生什么。 可能会想到内联样式来解决此问题,但它们不支持伪类,属性选择器,媒体查询等。可重用性重用规则集,媒体查询等是我最近很少看到的一个主题,因为它已经被Sass和Less等预处理器解决了。 但是我仍然想在这个系列中再次提起它。我将列出一些处理这些挑战的技术以及它们在本系列的两个部分中的局限性。 没有任何技术优于其他技术,它们甚至不相互排斥; 您可以选择一个或组合它们,具体取决于您的决定是否能改善您的项目质量。开始吧我们将使用名为Photo的示例组件演示不同的样式技术。 我们将呈现可能具有圆角的响应式图像,同时将替代文本显示为标题。 它会像这样使用:<Photo publicId=“balloons” alt=“Hot air balloons!” rounded />在构建实际组件之前,我们将抽象出srcSet属性以保持示例代码简洁。 那么,让我们创建一个带有两个实用程序的utils.js文件,用于使用Cloudinary生成不同宽度的图像:import { Cloudinary } from ‘cloudinary-core’const cl = Cloudinary.new({ cloud_name: ‘demo’, secure: true })export const getSrc = ({ publicId, width }) => cl.url(publicId, { crop: ‘scale’, width })export const getSrcSet = ({ publicId, widths }) => widths .map(width => ${getSrc({ publicId, width })} ${width}w) .join(’, ‘)我们设置Cloudinary实例以使用Cloudinary的演示云名称,以及根据指定选项为图像publicId生成URL的url方法。 我们只对修改此组件的宽度感兴趣。我们将分别将这些实用程序用于src和srcset属性:getSrc({ publicId: ‘balloons’, width: 200 })// => ‘https://res.cloudinary.com/demo/image/upload/c_scale,w_200/balloons'getSrcSet({ publicId: ‘balloons’, widths: [200, 400] })// => ‘https://res.cloudinary.com/demo/image/upload/c_scale,w_200/balloons 200w, https://res.cloudinary.com/demo/image/upload/c_scale,w_400/balloons 400w’如果你不熟悉srcset和sizes属性,我建议先阅读一下有关响应式图像的内容。 这样,您可以更轻松地按照示例进行操作。CSS-in-JSCSS-in-JS是一种样式方法,它将CSS模型抽象到组件级别,而不是文档级别。 这个想法是CSS可以限定为特定组件 - 并且只限于该组件 - 以使这些特定样式不与其他组件共享或泄露到其他组件,并且仅在需要时才调用。 CSS-in-JS库通过在<head>中插入<style>标签在运行时创建样式。使用这个概念的第一个库是JSS。 以下是使用其语法的示例:import React from ‘react’import injectSheet from ‘react-jss’import { getSrc, getSrcSet } from ‘./utils’const styles = { photo: { width: 200, ‘@media (min-width: 30rem)’: { width: 400, }, borderRadius: props => (props.rounded ? ‘1rem’ : 0), },}const Photo = ({ classes, publicId, alt }) => ( <figure> <img className={classes.photo} src={getSrc({ publicId, width: 200 })} srcSet={getSrcSet({ publicId, widths: [200, 400, 800] })} sizes="(min-width: 30rem) 400px, 200px" /> <figcaption>{alt}</figcaption> </figure>)Photo.defaultProps = { rounded: false,}export default injectSheet(styles)(Photo)乍一看,样式对象看起来像用对象表示法编写的CSS,带有附加功能,比如传递一个函数来设置基于props的值。 生成的类是唯一的,因此您永远不必担心它们与其他样式冲突。 换句话说,你可以自由的使用作用域! 这就是大多数CSS-in-JS库的工作方式 - 当然,我们将在功能和语法方面进行一些改进。您可以通过属性看到渲染图像的宽度从200px开始,然后当视口宽度变为至少30rem时,宽度增加到400px宽。 我们生成了额外的800宽度,以覆盖更大的屏幕密度:1x screens 使用 200 and 4002x screens 使用 400 and 800styled-components是另一个CSS-in-JS库,但是使用更熟悉的语法巧妙地使用模板文字而不是对象看起来更像CSS:import React from ‘react’import styled, { css } from ‘styled-components’import { getSrc, getSrcSet } from ‘./utils’const mediaQuery = ‘(min-width: 30rem)‘const roundedStyle = css border-radius: 1rem;const Image = styled.img width: 200px; @media ${mediaQuery} { width: 400px; } ${props =&gt; props.rounded &amp;&amp; roundedStyle}; const Photo = ({ publicId, alt, rounded }) => ( <figure> <Image src={getSrc({ publicId, width: 200 })} srcSet={getSrcSet({ publicId, widths: [200, 400, 800] })} sizes={${mediaQuery} 400px, 200px} rounded={rounded} /> <figcaption>{alt}</figcaption> </figure>)Photo.defaultProps = { rounded: false,}export default Photo我们经常创建语义中性元素,如<div>和<span>,仅用于样式目的。这个库以及许多其他库允许我们在一个动作中创建和设置它们。我最喜欢这种语法的好处是它就像常规的CSS,减去插值。这意味着我们可以更轻松地迁移CSS代码,并且我们可以使用现有的css知识,而不必熟悉在对象语法中编写CSS。请注意,我们可以在我们的样式中插入几乎任何东西。此特定示例演示了如何将媒体查询保存在变量中并在多个位置重用它。响应式图像是一个很好的用例,因为sizes属性基本上包含CSS,所以我们可以使用JavaScript来使代码更简洁。假设我们决定在视觉上隐藏字幕,但仍然可以让屏幕阅读器访问它。我知道实现这一目标的更好方法是使用alt属性,但为了这个例子,让我们使用不同的方式。我们可以使用一个名为polished的样式mixin库 - 它适用于CSS-in-JS库,非常适合我们的示例。这个库包含一个名为hideVisually的mixin,它正是我们想要的,我们可以通过插入它的返回值来使用它:import { hideVisually } from ‘polished’const Caption = styled.figcaption ${hideVisually()};<Caption>{alt}</Caption>即使hideVisually输出一个对象,样式组件库也知道如何将其作为样式进行插值。CSS-in-JS库具有许多高级功能,如主题,供应商前缀甚至内联关键CSS,这使得完全停止编写CSS文件变得容易。 此时,您可以开始了解为什么CSS-in-JS成为一个诱人的概念。缺点和局限CSS-in-JS的明显缺点是它引入了一个运行时:需要通过JavaScript加载,解析和执行样式。 CSS-in-JS库的作者正在添加各种智能优化,如Babel插件,但仍然存在一些运行时成本。同样重要的是要注意PostCSS没有解析这些库,因为PostCSS不是设计用于运行时的。许多人使用stylis作为结果,因为它更快。这意味着我们遗憾的是无法使用PostCSS插件。我要提到的最后一个缺点是工具。 CSS-in-JS正在以非常快的速度发展,文本编辑器扩展,linters,代码格式化等等需要追赶新功能以保持同等水平。例如,人们正在使用VS Code扩展样式组件来表示类似情感的CSS-in-JS库,即使它们并非都具有相同的功能。我甚至看到提议功能的API选择受到保留语法突出显示的目标的影响!未来有两个新的CSS-in-JS库,Linaria和astroturf,它们通过将CSS提取到文件中来管理零运行时。 它们的API类似于样式组件,但它们的功能和目标各不相同。Linaria的目标是通过内置函数(如作用域,嵌套和供应商前缀)来模仿CSS-in-JS库的API,如样式组件。 相反,astroturf是基于CSS模块构建的,具有有限的插值功能,并鼓励使用CSS生态系统而不是使用JavaScript。结论CSS-in-JS是一体化的样式解决方案,用于弥合CSS和JavaScript之间的差距。 它们易于使用,并且包含有用的内置优化 - 但所有这些都需要付出代价。 最值得注意的是,通过使用CSS-in-JS,我们基本上从CSS生态系统中退出并使用JavaScript来解决我们的问题。零运行时解决方案通过恢复CSS工具来缓解一些缺点,这些工具将CSS-in-JS讨论提升到更有趣的水平。 与CSS-in-JS相比,预处理工具的实际限制是什么? 这将在本系列的下一部分中介绍。 ...

December 10, 2018 · 2 min · jiezi