Asd528099

Asd528099 查看完整档案

填写现居城市  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 该用户太懒什么也没留下

个人动态

Asd528099 提出了问题 · 11月20日

请问VUE h5如何导出Excel

请问VUE h5如何导出Excel

关注 3 回答 2

Asd528099 收藏了文章 · 11月3日

总结移动端H5开发常用技巧(干货满满哦!)

前言

年后第一天到公司上班,整理一些在移动端H5开发常见的问题给大家做下分享,这里很多是自己在开发过程中遇到的大坑或者遭到过吐糟的问题,希望能给大家带来或多或少的帮助,喜欢的大佬们可以给个小赞,如果有问题也可以一起讨论下。

下面是最近一个月整理的JS基础总结,可供大家温故而知新。

本人github: github.com/Michael-lzg

开箱即用的JS干货助力金三银四
JS基础总结(1)——数据类型
JS基础总结(2)——原型与原型链
JS基础总结(3)——作用域和闭包
JS基础总结(4)——this指向及call/apply/bind
JS基础总结(5)—— JS执行机制与EventLoopd

html 篇

常用的meta属性设置

meta对于移动端的一些特殊属性,可根据需要自行设置


<meta name="screen-orientation" content="portrait"> //Android 禁止屏幕旋转
<meta name="full-screen" content="yes">             //全屏显示
<meta name="browsermode" content="application">     //UC应用模式,使用了application这种应用模式后,页面讲默认全屏,禁止长按菜单,禁止收拾,标准排版,以及强制图片显示。
<meta name="x5-orientation" content="portrait">     //QQ强制竖屏
<meta name="x5-fullscreen" content="true">          //QQ强制全屏
<meta name="x5-page-mode" content="app">            //QQ应用模式

电话号码识别

在 iOS Safari (其他浏览器和 Android 均不会)上会对那些看起来像是电话号码的数字处理为电话链接,比如:

  • 7 位数字,形如:1234567
  • 带括号及加号的数字,形如:(+86)123456789
  • 双连接线的数字,形如:00-00-00111
  • 11 位数字,形如:13800138000

关闭识别

<meta name="format-detection" content="telephone=no" />

开启识别

<a href="tel:123456">123456</a>

邮箱识别(Android)

安卓上会对符合邮箱格式的字符串进行识别,我们可以通过如下的 meta 来管别邮箱的自动识别:

<meta content="email=no" name="format-detection" />

同样地,我们也可以通过标签属性来开启长按邮箱地址弹出邮件发送的功能:

<a mailto:dooyoe@gmail.com">dooyoe@gmail.com</a>

css 篇

0.5px细线

移动端 H5 项目越来越多,设计师对于 UI 的要求也越来越高,比如 1px 的边框。在高清屏下,移动端的 1px 会很粗。

那么为什么会产生这个问题呢?主要是跟一个东西有关,DPR(devicePixelRatio) 设备像素比,它是默认缩放为 100%的情况下,设备像素和 CSS 像素的比值。目前主流的屏幕 DPR=2(iPhone 8),或者 3(iPhone 8 Plus)。拿 2 倍屏来说,设备的物理像素要实现 1 像素,而 DPR=2,所以 css 像素只能是 0.5。

下面介绍最常用的方法

/* 底边框 */
.b-border {
  position: relative;
}
.b-border:before {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: #d9d9d9;
  -webkit-transform: scaleY(0.5);
  transform: scaleY(0.5);
  -webkit-transform-origin: 0 0;
  transform-origin: 0 0;
}
/* 上边框 */
.t-border {
  position: relative;
}
.t-border:before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 1px;
  background: #d9d9d9;
  -webkit-transform: scaleY(0.5);
  transform: scaleY(0.5);
  -webkit-transform-origin: 0 0;
  transform-origin: 0 0;
}
/* 右边框 */
.r-border {
  position: relative;
}
.r-border:before {
  content: '';
  position: absolute;
  right: 0;
  bottom: 0;
  width: 1px;
  height: 100%;
  background: #d9d9d9;
  -webkit-transform: scaleX(0.5);
  transform: scaleX(0.5);
  -webkit-transform-origin: 0 0;
  transform-origin: 0 0;
}
/* 左边框 */
.l-border {
  position: relative;
}
.l-border:before {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 1px;
  height: 100%;
  background: #d9d9d9;
  -webkit-transform: scaleX(0.5);
  transform: scaleX(0.5);
  -webkit-transform-origin: 0 0;
  transform-origin: 0 0;
}

/* 四条边 */
.setBorderAll {
  position: relative;
  &:after {
    content: ' ';
    position: absolute;
    top: 0;
    left: 0;
    width: 200%;
    height: 200%;
    transform: scale(0.5);
    transform-origin: left top;
    box-sizing: border-box;
    border: 1px solid #e5e5e5;
    border-radius: 4px;
  }
}

屏蔽用户选择

禁止用户选择页面中的文字或者图片

div {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

清除输入框内阴影

在 iOS 上,输入框默认有内部阴影,以这样关闭:

div {
  -webkit-appearance: none;
}

如何禁止保存或拷贝图像

代码如下

img {
  -webkit-touch-callout: none;
}

输入框默认字体颜色

设置 input 里面 placeholder 字体的颜色

input::-webkit-input-placeholder,
textarea::-webkit-input-placeholder {
  color: #c7c7c7;
}
input:-moz-placeholder,
textarea:-moz-placeholder {
  color: #c7c7c7;
}
input:-ms-input-placeholder,
textarea:-ms-input-placeholder {
  color: #c7c7c7;
}

用户设置字号放大或者缩小导致页面布局错误

设置字体禁止缩放

body {
  -webkit-text-size-adjust: 100% !important;
  text-size-adjust: 100% !important;
  -moz-text-size-adjust: 100% !important;
}

android系统中元素被点击时产生边框

部分android系统点击一个链接,会出现一个边框或者半透明灰色遮罩, 不同生产商定义出来额效果不一样。去除代码如下

a,button,input,textarea{
  -webkit-tap-highlight-color: rgba(0,0,0,0)
  -webkit-user-modify:read-write-plaintext-only; 
}

iOS 滑动不流畅

ios 手机上下滑动页面会产生卡顿,手指离开页面,页面立即停止运动。整体表现就是滑动不流畅,没有滑动惯性。 iOS 5.0 以及之后的版本,滑动有定义有两个值 auto 和 touch,默认值为 auto。

解决方案

  1. 在滚动容器上增加滚动 touch 方法
.wrapper {
  -webkit-overflow-scrolling: touch;
}
  1. 设置 overflow 设置外部 overflow 为 hidden,设置内容元素 overflow 为 auto。内部元素超出 body 即产生滚动,超出的部分 body 隐藏。
body {
  overflow-y: hidden;
}
.wrapper {
  overflow-y: auto;
}

js 篇

移动端click屏幕产生200-300 ms的延迟响应

移动设备上的web网页是有300ms延迟的,往往会造成按钮点击延迟甚至是点击失效。解决方案:

  • fastclick可以解决在手机上点击事件的300ms延迟
  • zepto的touch模块,tap事件也是为了解决在click的延迟问题

触摸事件的响应顺序

  1. ontouchstart
  2. ontouchmove
  3. ontouchend
  4. onclick

audio 和 video 在 ios 和 andriod 中自动播放

这个不是bug,由于自动播放网页中的音频或视频,会给用户带来一些困扰或者不必要的流量消耗,所以苹果系统和安卓系统通常都会禁止自动播放和使用 JS 的触发播放,必须由用户来触发才可以播放。加入自动触发播放的代码

$('html').one('touchstart', function() {
  audio.play()
})

iOS 上拉边界下拉出现空白

手指按住屏幕下拉,屏幕顶部会多出一块白色区域。手指按住屏幕上拉,底部多出一块白色区域。

在 iOS 中,手指按住屏幕上下拖动,会触发 touchmove 事件。这个事件触发的对象是整个 webview 容器,容器自然会被拖动,剩下的部分会成空白。

解决方案

document.body.addEventListener(
  'touchmove',
  function(e) {
    if (e._isScroller) return
    // 阻止默认事件
    e.preventDefault()
  },
  {
    passive: false
  }
)

ios 日期转换 NAN 的问题

将日期字符串的格式符号替换成'/'

'yyyy-MM-dd'.replace(/-/g, '/')

软键盘问题

IOS 键盘弹起挡住原来的视图

  • 可以通过监听移动端软键盘弹起 Element.scrollIntoViewIfNeeded(Boolean)方法用来将不在浏览器窗口的可见区域内的元素滚动到浏览器窗口的可见区域。 如果该元素已经在浏览器窗口的可见区域内,则不会发生滚动。
  • true,则元素将在其所在滚动区的可视区域中居中对齐。
  • false,则元素将与其所在滚动区的可视区域最近的边缘对齐。 根据可见区域最靠近元素的哪个边缘,元素的顶部将与可见区域的顶部边缘对准,或者元素的底部边缘将与可见区域的底部边缘对准。
window.addEventListener('resize', function() {
  if (
    document.activeElement.tagName === 'INPUT' ||
    document.activeElement.tagName === 'TEXTAREA'
  ) {
    window.setTimeout(function() {
      if ('scrollIntoView' in document.activeElement) {
        document.activeElement.scrollIntoView(false)
      } else {
        document.activeElement.scrollIntoViewIfNeeded(false)
      }
    }, 0)
  }
})

onkeyUp 和 onKeydown 兼容性问题

IOS 中 input 键盘事件 keyup、keydown、等支持不是很好, 用 input 监听键盘 keyup 事件,在安卓手机浏览器中没有问题,但是在 ios 手机浏览器中用输入法输入之后,并未立刻相应 keyup 事件

IOS12 输入框难以点击获取焦点,弹不出软键盘

定位找到问题是 fastclick.js 对 IOS12 的兼容性,可在 fastclick.js 源码或者 main.js 做以下修改

FastClick.prototype.focus = function(targetElement) {
  var length
  if (
    deviceIsIOS &&
    targetElement.setSelectionRange &&
    targetElement.type.indexOf('date') !== 0 &&
    targetElement.type !== 'time' &&
    targetElement.type !== 'month'
  ) {
    length = targetElement.value.length
    targetElement.setSelectionRange(length, length)
    targetElement.focus()
  } else {
    targetElement.focus()
  }
}

IOS 键盘收起时页面没用回落,底部会留白

通过监听键盘回落时间滚动到原来的位置

window.addEventListener('focusout', function() {
  window.scrollTo(0, 0)
})

//input输入框弹起软键盘的解决方案。
var bfscrolltop = document.body.scrollTop
$('input')
  .focus(function() {
    document.body.scrollTop = document.body.scrollHeight
    //console.log(document.body.scrollTop);
  })
  .blur(function() {
    document.body.scrollTop = bfscrolltop
    //console.log(document.body.scrollTop);
  })

IOS 下 fixed 失效的原因

软键盘唤起后,页面的 fixed 元素将失效,变成了 absolute,所以当页面超过一屏且滚动时,失效的 fixed 元素就会跟随滚动了。不仅限于 type=text 的输入框,凡是软键盘(比如时间日期选择、select 选择等等)被唤起,都会遇到同样地问题。

解决方法: 不让页面滚动,而是让主体部分自己滚动,主体部分高度设为 100%,overflow:scroll

<body>
  <div class='warper'>
    <div class='main'></div>
  <div>
  <div class="fix-bottom"></div>
</body>
.warper {
  position: absolute;
  width: 100%;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  overflow-y: scroll;
  -webkit-overflow-scrolling: touch; /* 解决ios滑动不流畅问题 */
}
.fix-bottom {
  position: fixed;
  bottom: 0;
  width: 100%;
}

推荐文章

从零开始构建一个webpack项目
总结几个webpack打包优化的方法
总结前端性能优化的方法
几种常见的JS递归算法
搭建一个vue-cli的移动端H5开发模板
封装一个toast和dialog组件并发布到npm
一文读尽前端路由、后端路由、单页面应用、多页面应用
关于几个移动端软键盘的坑及其解决方案
浅谈JavaScript的防抖与节流

关注的我的公众号不定期分享前端知识,与您一起进步!

查看原文

Asd528099 提出了问题 · 11月3日

求教,移动端,图片如何做适配不变形

需求:用户可以自行上传图片,切不受限制,然后显示在手机上,手机上有好多页面,div都是不同的宽高,如果适配且不变形

关注 3 回答 3

Asd528099 收藏了文章 · 10月29日

CSS样式全部属性和难记忆点(归纳)

有一些CSS的冷门样式太多了,但是又想记住,可以看这篇文章,这篇文章包括了一些css需要记忆的一些属性,不包括平时经常使用的(相信你已经接触的太多了)
f11225c1afc79ebe65fe22b5292980a0.jpg

伪类选择器

:link未访问
:visited已访问
:hover鼠标移动到链接上
:active选定的链接

文字阴影

简写:
text-shadow:水平位置 垂直位置 模糊距离 阴影颜色;

text-indent:首行缩进 ;
word-spacing: 单词间距;
letter-spacing:字间距;

link答疑

type="text/css"在link中可以忽略不写,写了比较规范,rel定义当前文档和被链接文档之间的关系,在这里需要指定为“stylesheet”,表示被链接的文档是一个样式文件

行内元素&块级元素

行内元素:高宽无效,水平的paddingmargin有效,但垂直方向无效

常见的行内元素:<a> <strong> <b> <i> <del> <s> <ins> <u> <span>

块级元素:高宽有效,都可以自定义

选择器

交集选择器

p.one{color:red;font-size:14px;}

是“即...又...的意思”,p.one选择的是类名为.one的 段落标签

并集选择器(逗号分割)

.one,p,#test{color:red;}

伪元素选择器

E::first-letter 文本的第一个单纯或字

E::first-line 文本第一行

E::selection 改变文本选中的样式(有点好用)

E::befor和E::after 该元素是行内元素 结合content使用

“:”和“::”在于区分伪类和伪元素

背景(background)

background-image:none/url(url)
属性作用
background-color背景颜色色值/inherit(继承父元素)/transparent(默认)
background-image背景图片地址none/url()
background-repeat是否平铺repeat/no-repeat/repeat-y/repeat-x
background-position背景位置length length (百分数) / positon postiontop/center/bottom/left/right
background-attachment背景是固定还是滚动scroll(滚动) fixed(固定)
背景的合写(复合属性)
background:背景颜色 背景图片地址 背景平铺 背景滚动 背景位置;background: transparent url(*1111.jpg*) no-repeat scroll 50% 0;
background-size设置图片尺寸px 百分比/cover(保证填充满背景区域,溢出部分隐藏)/contain(保证图片始终完整显示在背景区域) 例如:background-size:50%;比原来小一半

一般使用习惯(参考):

  .img {
            width: 400px;
            height: 400px;
            border: 1px solid #fff;
            background: #fff url(1111.jpg) no-repeat;
            background-position: 30px 50px;
            background-size: 200px 210px;
        }

文本修饰

`text-decoration`   修饰文本
描述
none默认
underline定义文本下的一条线。下划线自带的
overline定义文本上的一条线
line-through定义穿过文本的一条线

盒子模型

应该都比较熟悉,只讲几个比较容易忘记的属性

border-style

属性作用
none没有边框
solid边框是单实线(常用)
dashed边框为虚线
dotted边框为点线
double边框为双实线

表格table的边框

table{border-collapse:collapse;}`collapse`单词是合并的意思。表示边框合并在一起

外边距实现盒子居中

可以让一个盒子实现水平居中:

.header{width:960px; margin:0 auto;}
文字居中:text-align:center;

相邻块元素垂直外边距的合并(容易出现的bug)

1.上下相邻的元素,上:margin-bottom,下:margin-top,会发生合并(外边距塌陷),合并的边距值等于其中大的那者
1DFE31C84806F274BCDA5E9B0CE0632A.png
解决方法:避免

2.嵌套元素垂直外边距的合并
3436CADB9762F484E6936907AB9253D2.png
解决方案:
1.为父元素定义1像素的上边框
2.可以为父元素添加:overflow:hidden(触发BFC)

CSS盒模型

box-sizing:content-box;默认

box-sizing:border-box;盒子大小为width,也就是说paddingborder都包含到了width里面

盒子阴影

box-shadow:水平 垂直 模糊距离 阴影尺寸 颜色 内/外阴影;

想要内阴影就用inset

实际用法:box-shadow:0 15px 30px rgba(0,0,0,.4);

CSS定位

CSS的定位机制有三种:普通流(标准流)、浮动定位

清除浮动

解决父级元素因为子浮动引起的内部高度为0的问题
应用场景:比如文章,做瀑布流布局等等,很多时候我们不需要给父盒子高度,因为比如文章的内容你是无法估量其高度的,我们需要自适应地撑开盒子。所以才会清除浮动。

解决方法:

1.选择器{clear:both;}

2.父级添加overflow:hidden;,触发BFC的方式实现清除浮动效果

3.:after 案例:百度 淘宝网 网易

 .clearfix::after{
            content: ".";
            display: block;
            height: 0;
            clear: both;
            visibility: hidden;
        }
        .clearfix{
            *zoom: 1;
        }

4.beforeafter 案例:小米 腾讯 代码更简洁

  .clearfix::after,.clearfix:before {
            content: ".";
            display: table;/* 这句话可以触发BFC */
        }

        .clearfix::after {
            clear: both;
        }

        .clearfix {
            *zoom: 1;
        }
给父盒子的class属性添加clearfix就可以使用了

定位

描述是否脱标占用位置移动位置基准
static自动定位(默认)不脱标,正常模式正常模式
relative相对定位不脱标,占有位置相对自身位置移动(自恋型)
absolute绝对定位完全脱标,不占有位置相对于定位父级移动位置(拼爹型)
fixed固定定位(相对于浏览器窗口进行定位)完全脱标,不占有位置相对于浏览器移动位置(认死理型)
Tip:“子绝父相”牢记于心

绝对定位中的盒子水平/垂直居中

绝对定位的盒子margin无效

解决方法:

  1. left:50%
  2. 走自己外边距负的一半:margin-left

z-index

默认是0,属性越大,定位元素位置越居上。

只有relative,absolute,fixed可以使用这个属性

元素的显示隐藏

overflow display visibility比较常见

display

none隐藏对象
block转换块级元素,显示元素

visibility

visible对象可见
hidden对象可视

overflow

auto超出自动显示滚动条,不超出不显示滚动条
hidden不显示超过对象尺寸的内容,超出的部分隐藏
scroll不管超出内容否,总是显示滚动条

CSS高级技巧

鼠标cursor

cursor:default 小白  |  pointer 小手  |  move 移动  |  text 文本;
尽量不要用hand,火狐不支持
pointer: ie6以上支持

轮廓outline

outline:outline-color || outline-style  ||  outline-width

一般不会关心设置多少,去掉就好:outline:0;或outline:none;
(比如在点击表单input时候会默认有一个黑色轮廓,我们可以去掉,也可以用 outline-color: red;改变轮廓颜色)

防止拖拽文本域resize

image.png

resize:none可以防止 火狐 谷歌 等浏览器随意拖拽textarea破坏布局

vertical-align垂直对齐

它不影响块级元素的内容对齐,只针对行内和行内块元素,通常用来控制图片/表单与文字的对齐

MDN文档讲述这个属性很棒:

   链接:[https://developer.mozilla.org/zh-CN/docs/Web/CSS/vertical-align](https://developer.mozilla.org/zh-CN/docs/Web/CSS/vertical-align)

去除图片底侧空白缝隙

图片或表单等行内元素,它的底线和父级盒子的基线对齐。这样会造成一个问题,图片底侧会有一个空白缝隙。

解决方法:

  1. 给img vertical-align:middle | top;等等。让图片不要和基线对齐
  2. 给img添加display:block;

溢出的文字隐藏

word-break

主要处理英文单词

属性作用
normal使用浏览器默认的换行规则
break-all运行在单词内换行
keep-all只能在半角空格或连字符处换行

white-space

属性作用
normal默认
nowrap强制在同一内显所有文本,直到文本结束或者遇到<br>才换行

text-overflow文字溢出

设置一个省略标记(...)显示文本的溢出

属性作用
clip不显示(...),简单的裁切
ellipsis当对象内文本溢出时显示省略标记(...)
注意首先要强制一行内显示,然后搭配overflow:hidden;使用

CSS精灵图

很多图片集合到一张内,减少服务器接受和发送请求的次数,提高页面加载速度

使用:用到CSS的background-image,background-repeat,background-position进行背景定位,也可以简写操作

字体图标iconfont

优点:有文字的属性,体积小,几乎支持所有浏览器,移动端必备

格式:.svg

程序员推荐图标字体网站:http://icomoon.io(iconmoon字库,允许用户自定义选择图标使它们生成字型,种类很多,国外网站打开速度比较慢)

如何引入

  1. 创建fonts文件夹,里面包含了字体文件
  2. 在样式内声明字体

    @font-face {  /* 声明字体 */
      font-family: 'icomoon'; /* 自己声明的字体包 */
      src:  url('../fonts/icomoon.eot?8qhwk5'); /* 路径 */
      src:  url('../fonts/icomoon.eot?8qhwk5#iefix') format('embedded-opentype'),
        url('../fonts/icomoon.ttf?8qhwk5') format('truetype'),
        url('../fonts/icomoon.woff?8qhwk5') format('woff'),
        url('../fonts/icomoon.svg?8qhwk5#icomoon') format('svg');
      font-weight: normal;
      font-style: normal;
    }
  3. 给盒子使用字体

    font-family:"icomoon";
  4. 盒子里添加结构

    span::before{
        content:"\e900";
    }
    或者
    <span>□<span>/* □是从网站复制过来的(无法看见)*/

滑动门技术

6DE269D1FC2A2D2EF1533DBA59CC0588.png
设置导航栏时候,字数不一样多,比如图里的,怎么适应内部的文本内容呢?
image.png

方法:利用CSS(背景位置)和盒子padding撑开宽度。

6686F110C08A823687C198861DA87F92.png

<li> <li>
           <a href="#">
               <span>导航栏内容</span>
           </a>
       </li>
 a {
            margin: 100px;
            display: inline-block;
            height: 33px;
            background: url() no-repeat;
            padding-left: 15px;
            color: #fff;
            text-decoration: none;
            line-height: 15px;
        }

        a span {
            display: inline-block;
            height: 33px;
            background: url() no-repeat right;
            padding-right: 15px;
        }
  1. a设置背景左侧padding-left:15px;,padding撑开合适宽度
  2. span设置背景右侧padding-right:15px;剩下由文字自身撑开宽度
  3. 之所以a包含span是因为整个导航都是可以点击

动画(太多,系统学习参考文档)

CSS3中使用transition可以实现补间动画(过渡效果)

语法格式:transition:要过渡的属性 花费时间 运动曲线 何时开始;

属性描述CSS
transition简写,设置四个过渡属性3
transition-property规定应用过渡的属性的名字3
transiton-duration定义过渡效果花费的时间。默认是03
transition-timing-function规定过渡效果的时间曲线。默认是"ease"3
transiton-delay规定过渡效果何时开始。默认是03

属性太多,看MDN文档:https://developer.mozilla.org/zh-CN/docs/Web/CSS/transition

flex弹性布局

这块学习比较困难,可以参考我之前写的一篇文章
链接:https://segmentfault.com/a/1190000023520335

查看原文

Asd528099 收藏了文章 · 10月29日

我不能没有的5个Vue.js库

image

微信搜索【前端全栈开发者】关注这个脱发、摆摊、卖货、持续学习的程序员,第一时间阅读最新文章,会优先两天发表新文章。关注即可大礼包,准能为你节省不少钱!

1.Click Off to Close

有的时候,我们需要在用户点击元素之外的时候触发一个事件。最常见的用例是当你想通过点击关闭一个下拉框或对话框时。这是一个必不可少的包,几乎在我构建的每个应用中都会用到。

首选:vue-clickaway

https://github.com/simplesmiler/vue-clickaway

我通常会将它安装在 main.js 中,以便在我的应用程序中使用。如果你只在一个或两个页面上使用它,你可能会想单独导入它。

如果你真的单独导入,请记住,指令需要在指令下暴露。

directives: { onClickaway }

而不是组件:

components: { onClickaway }

使其全局可用(在 main.js 中):

import { directive as onClickaway } from 'vue-clickaway'
Vue.directive('on-clickaway', onClickaway)

在模板中:

想象一下,我有一个完整的选择框,其中包含 li 元素列表(此处未显示)。上面的按钮用于触发我的自定义选择框项目列表,当我在该元素外点击时,会触发一个关闭选项列表的方法。这比强迫用户始终单击元素右上角处的“X”按钮要好得多。我们只需将以下内容添加到按钮即可获得此功能: v-on-clickaway = "closeMethodName"

注意:你应该总是在 close 方法中使用 vue-clickaway ,而不是 toggle 方法。我的意思是这个方法连接到v-on-clickaway 应该是这样的:

closeMethod() {
  this.showSomething = false
}

而不是这样:

toggleMethod() {
  this.showSomething = !this.showSomething
}

如果你使用了 toggle 方法,那么每当你在该元素外点击时,无论你点击什么,它都会打开,然后一遍遍地关闭该元素。这很可能不是你想要的结果,所以请记住使用 close 方法来防止这种情况发生。

2.Toasts (Notification Bar)

首选:vue-toastification

https://maronato.github.io/vue-toastification/

你有很多toast和类似通知的选择,但我是Maronato的vue-toastification的忠实粉丝。它提供了大量的选项来覆盖你的大部分边界情况,而且样式和动画导致了出色的用户体验,远远超过其他软件包。

Vue-toastification提供了几种在其文档中使用它的方法。你可以在组件级别,全局级别甚至在Vuex内执行此操作,如果你希望根据状态或与服务器相关的操作显示toasts。

全局使用(在 main.js 中):

import Toast from 'vue-toastification'
// Toast styles
import 'vue-toastification/dist/index.css'
Vue.use(Toast, {
  transition: 'Vue-Toastification__bounce',
  maxToasts: 3,
  newestOnTop: true,
  position: 'top-right',
  timeout: 2000,
  closeOnClick: true,
  pauseOnFocusLoss: true,
  pauseOnHover: false,
  draggable: true,
  draggablePercent: 0.7,
  showCloseButtonOnHover: false,
  hideProgressBar: true,
  closeButton: 'button',
  icon: true,
  rtl: false
})

你可以在每个组件中单独控制样式,但在上面的案例中,我通过将它导入 main.js,然后在那里设置我想使用的选项,使它在我的应用程序中到处可用,这使我不必每次都编写相同的选项属性。Vue-toastification有一个很好的在线演示,在这里你可以看到每个选项属性的结果,只需要复制粘贴你想要的选项,就像我上面做的那样。

选项1:在组件(模板)中使用Toast

<button @click="showToast">Show toast</button> 

选项2:在Vuex action中发现错误(或成功)时调用Toast

你只需将 .error 改为 `.success.info.warning 即可更改所需的Toast类型,也可以将其完全删除以作为默认的Toast通知。

Toasts可以让你根据实时状态的变化或者发生了不可预见的错误来显示消息,这大大改善了用户的体验。Toasts提供了比模态或丑陋的提示框更好的视觉指示,例如,用户必须提供一个额外的点击来关闭。用户会很感激你给他们一个视觉上的提示,让他们知道出了什么问题,防止他们盯着屏幕茫然地等待一些永远不会发生的事情。确认他们执行的操作是否成功完成也很有用。

3.Tables

首选:vue-good-table

https://xaksis.github.io/vue-good-table

表格是许多Web应用程序的重要组成部分,选择错误的表格会让你陷入无尽的痛苦之中。尝试了很长的包选项列表后,我相信vue-good-table将解决你大部分的表需求。它不仅仅是为了好玩才叫“good-table”。它真的很好,提供了更多的选择和功能,超出了你的能力范围。

在以下情况下,我将 :rows 数据绑定到名为 getOrderHistory 的Vuex getter。

在本地 data() 中定义我的列:

label 是显示的列标题,而 field 是我在Vuex getter中绑定的数据。

在上图中,我还使用了vue-good-table的一些自定义选项,比如设置我的日期的输入和输出格式(这让我可以把服务器提供的一个很长的时间戳改成对我的用户来说更易读的东西)。我还使用 formatFn 来格式化我的价格,调用了一个我命名为 toLocale 的单独方法,然后我通过绑定 tdClass 到我在 local <style> 中设置的类来定制每个单元格的外观。Vue-good-table确实内置了无穷的可定制性,他们已经覆盖了非常广泛的边缘案例。

Vue-good-table还可以与自定义模板配合使用,因此你可以轻松地将按钮,选择框或您喜欢的其他任何东西注入到表格的单元格中。为此,你只需使用 v-if 定义应将其注入的位置。

要添加另一个自定义列,只需在你的 v-if 标签后面添加一个 v-else-if(在上面的例子中是一个跨度),然后在那里添加第二个自定义模板的逻辑。无论你需要什么,vue-good-table都能满足你的需求。

4.Date Picker

首选:vue2-datepicker

https://mengxiong10.github.io/vue2-datepicker/index.html#Basic

啊,日期选择器,这是许多应用程序的重要组成部分。在这个列表中,日期选择器的选择比其他任何东西都多,但Mengxiong打造的vue2-datepicker是我不断回归的一个选择。它的风格简单,提供了广泛的选择日期和日期范围的选项,并被包装在一个光滑和用户友好的UI中。它甚至支持i18n语言和日期格式的本地化。

注意:尽管包名为vue2-datepicker,但将这个包(或这里列出的其他包)添加到Vue 3.0应用程序中应该没有问题。

在组件或视图中导入,使其可以使用。

import DatePicker from 'vue2-datepicker';
// styles
import 'vue2-datepicker/index.css';

在模板中:

在这里,我使用的是 range 选项,允许用户选择日期范围,并将用户输入的日期 v-model 以一个名为 dateRange 的数据值绑定。然后,vue-good-table(如下)使用 dateRange 对我的表的结果进行排序。我还使用事件选项 @clear@input 来触发重置表(resetList)或发送服务器请求表数据(searchDate)的方法。Vue2-datepicker提供了更多的选项和事件,以方便你的使用,但这些是我发现自己最经常使用的。

5.User Ratings

首选:vue-star-rating

https://github.com/craigh411/vue-star-rating

虽然你可能不会在每个项目中都使用这个功能,但对于任何需要用户评级元素的网站(比如Amazon或Rotten Tomatoes),vue-star-rating是我的首选。自己创建看似是一件微不足道的事情,但当你进入细节后,星级评定很快就会变得比你预期的要复杂。如果需要特殊功能,它可以让你使用自定义SVG形状,并且可以轻松自定义大小,间距和颜色。

通过这些选项,可以很容易地将用户选择的评级 v-model 绑定到任何你想使用的地方,你可以通过一个prop将评级设置为可更改或只读。

如果你发现需要更多选择,请查看创建者的扩展软件包vue-rate-it

在模板中(带有选项):

将其导入到组件或视图中:


原文:https://medium.com/better-programming
作者:Titus Decali
翻译:公众号《前端全栈开发者》

image

查看原文

Asd528099 提出了问题 · 10月28日

请问 移动端开发 滚动条在底部导航上边如何让滚动条去下边

image.png

我不想让这个滚动条在底部菜单上边 太难看 如何解决这个问题 请教

关注 2 回答 1

Asd528099 提出了问题 · 10月27日

请问css 这种效果有什么方便的写法么

image.png
主要是两端圆点

关注 3 回答 3

Asd528099 收藏了文章 · 10月26日

前端项目自动化部署——超详细教程(Jenkins、Github Actions)

本教程主要讲解了怎么使用 Jenkins 和 Github Actions 部署前端项目。

  1. 第一部分是使用 Gitea 配置局域网 git 服务器,再使用 Jenkins 将 Gitea 下的项目部署到局域网服务器。
  2. 第二部分是使用 Github Actions 将 Github 项目部署到 Github Page 和阿里云。

阅读本教程并不需要你提前了解 Jenkins 和 Github Actions 的知识,只要按照本教程的指引,就能够实现自动化部署项目。

PS:本人所用电脑操作系统为 windows,即以下所有的操作均在 windows 下运行。其他操作系统的配置大同小异,不会有太大差别。

Gitea + Jenkins 自动构建前端项目并部署到服务器

Gitea 用于构建 Git 局域网服务器,Jenkins 是 CI/CD 工具,用于部署前端项目。

配置 Gitea

  1. 下载 Gitea,选择一个喜欢的版本,例如 1.13,选择 gitea-1.13-windows-4.0-amd64.exe 下载。
  2. 下载完后,新建一个目录(例如 gitea),将下载的 Gitea 软件放到该目录下,双击运行。
  3. 打开 localhost:3000 就能看到 Gitea 已经运行在你的电脑上了。
  4. 点击注册,第一次会弹出一个初始配置页面,数据库选择 SQLite3。另外把 localhost 改成你电脑的局域网地址,例如我的电脑 IP 为 192.168.0.118

在这里插入图片描述
在这里插入图片描述

  1. 填完信息后,点击立即安装,等待一会,即可完成配置。
  2. 继续点击注册用户,第一个注册的用户将会成会管理员。
  3. 打开 Gitea 的安装目录,找到 custom\conf\app.ini,在里面加上一行代码 START_SSH_SERVER = true。这时就可以使用 ssh 进行 push 操作了。

在这里插入图片描述

  1. 如果使用 http 的方式无法克隆项目,请取消 git 代理。
git config --global --unset http.proxy
git config --global --unset https.proxy

配置 Jenkins

  1. 需要提前安装 JDK,JDK 安装教程网上很多,请自行搜索。
  2. 打开 Jenkins 下载页面。

在这里插入图片描述

  1. 安装过程中遇到 Logon Type 时,选择第一个。

在这里插入图片描述

  1. 端口默认为 8080,这里我填的是 8000。安装完会自动打开 http://localhost:8000 网站,这时需要等待一会,进行初始化。
  2. 按照提示找到对应的文件(直接复制路径在我的电脑中打开),其中有管理员密码。

在这里插入图片描述

  1. 安装插件,选择第一个。

在这里插入图片描述

  1. 创建管理员用户,点击完成并保存,然后一路下一步。

在这里插入图片描述

  1. 配置完成后自动进入首页,这时点击 Manage Jenkins -> Manage plugins 安装插件。

在这里插入图片描述

  1. 点击 可选插件,输入 nodejs,搜索插件,然后安装。
  2. 安装完成后回到首页,点击 Manage Jenkins -> Global Tool Configuration 配置 nodejs。如果你的电脑是 win7 的话,nodejs 版本最好不要太高,选择 v12 左右的就行。

在这里插入图片描述

创建静态服务器

  1. 建立一个空目录,在里面执行 npm init -y,初始化项目。
  2. 执行 npm i express 下载 express。
  3. 然后建立一个 server.js 文件,代码如下:
const express = require('express')
const app = express()
const port = 8080

app.use(express.static('dist'))

app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`)
})

它将当前目录下的 dist 文件夹设为静态服务器资源目录,然后执行 node server.js 启动服务器。

由于现在没有 dist 文件夹,所以访问网站是空页面。
在这里插入图片描述
不过不要着急,一会就能看到内容了。

自动构建 + 部署到服务器

  1. 下载 Jenkins 提供的 demo 项目 building-a-multibranch-pipeline-project,然后在你的 Gitea 新建一个仓库,把内容克隆进去,并提交到 Gitea 服务器。

在这里插入图片描述

  1. 打开 Jenkins 首页,点击 新建 Item 创建项目。

在这里插入图片描述

  1. 选择源码管理,输入你的 Gitea 上的仓库地址。

在这里插入图片描述

  1. 你也可以尝试一下定时构建,下面这个代码表示每 5 分钟构建一次。

在这里插入图片描述

  1. 选择你的构建环境,这里选择刚才配置的 nodejs。

在这里插入图片描述

  1. 点击增加构建步骤,windows 要选 execute windows batch command,linux 要选 execute shell

  1. 输入 npm i && npm run build && xcopy .\build\* G:\node-server\dist\ /s/e/y,这行命令的作用是安装依赖,构建项目,并将构建后的静态资源复制到指定目录 G:\node-server\dist\ 。这个目录是静态服务器资源目录。

在这里插入图片描述

  1. 保存后,返回首页。点击项目旁边的小三角,选择 build now

在这里插入图片描述

  1. 开始构建项目,我们可以点击项目查看构建过程。

在这里插入图片描述

  1. 构建成功,打开 http://localhost:8080/ 看一下结果。

在这里插入图片描述
在这里插入图片描述

  1. 由于刚才设置了每 5 分钟构建一次,我们可以改变一下网站的内容,然后什么都不做,等待一会再打开网站看看。

在这里插入图片描述

  1. 把修改的内容提交到 Gitea 服务器,稍等一会。打开网站,发现内容已经发生了变化。

在这里插入图片描述

使用 pipeline 构建项目

使用流水线构建项目可以结合 Gitea 的 webhook 钩子,以便在执行 git push 的时候,自动构建项目。

  1. 点击首页右上角的用户名,选择设置

在这里插入图片描述

  1. 添加 token,记得将 token 保存起来。

在这里插入图片描述

  1. 打开 Jenkins 首页,点击 新建 Item 创建项目。

在这里插入图片描述

  1. 点击构建触发器,选择触发远程构建,填入刚才创建的 token。

在这里插入图片描述

  1. 选择流水线,按照提示输入内容,然后点击保存

在这里插入图片描述

  1. 打开 Jenkins 安装目录下的 jenkins.xml 文件,找到 <arguments> 标签,在里面加上 -Dhudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=true。它的作用是关闭 CSRF 验证,不关的话,Gitea 的 webhook 会一直报 403 错误,无法使用。加好参数后,在该目录命令行下输入 jenkins.exe restart 重启 Jenkins。

在这里插入图片描述

  1. 回到首页,配置全局安全选项。勾上匿名用户具有可读权限,再保存。

在这里插入图片描述
在这里插入图片描述

  1. 打开你的 Gitea 仓库页面,选择仓库设置

在这里插入图片描述

  1. 点击管理 web 钩子,添加 web 钩子,钩子选项选择 Gitea
  2. 目标 URL 按照 Jenkins 的提示输入内容。然后点击添加 web 钩子

在这里插入图片描述
在这里插入图片描述

  1. 点击创建好的 web 钩子,拉到下方,点击测试推送。不出意外,应该能看到推送成功的消息,此时回到 Jenkins 首页,发现已经在构建项目了。

在这里插入图片描述

  1. 由于没有配置 Jenkinsfile 文件,此时构建是不会成功的。所以接下来需要配置一下 Jenkinsfile 文件。将以下代码复制到你 Gitea 项目下的 Jenkinsfile 文件。jenkins 在构建时会自动读取文件的内容执行构建及部署操作。
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {  // window 使用 bat, linux 使用 sh
                bat 'npm i'
                bat 'npm run build'
            }
        }
        stage('Deploy') {
            steps {
                bat 'xcopy .\\build\\* D:\\node-server\\dist\\ /s/e/y' // 这里需要改成你的静态服务器资源目录
            }
        }
    }
}
  1. 每当你的 Gitea 项目执行 push 操作时,Gitea 都会通过 webhook 发送一个 post 请求给 Jenkins,让它执行构建及部署操作。

在这里插入图片描述

小结

如果你的操作系统是 Linux,可以在 Jenkins 打包完成后,使用 ssh 远程登录到阿里云,将打包后的文件复制到阿里云上的静态服务器上,这样就能实现阿里云自动部署了。具体怎么远程登录到阿里云,请看下文中的 《Github Actions 部署到阿里云》 一节。

Github Actions 自动构建前端项目并部署到服务器

如果你的项目是 Github 项目,那么使用 Github Actions 也许是更好的选择。

部署到 Github Page

接下来看一下如何使用 Github Actions 部署到 Github Page。

在你需要部署到 Github Page 的项目下,建立一个 yml 文件,放在 .github/workflow 目录下。你可以命名为 ci.yml,它类似于 Jenkins 的 Jenkinsfile 文件,里面包含的是要自动执行的脚本代码。

这个 yml 文件的内容如下:

name: Build and Deploy
on: # 监听 master 分支上的 push 事件
  push:
    branches:
      - master
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest # 构建环境使用 ubuntu
    steps:
      - name: Checkout
        uses: actions/checkout@v2.3.1  
        with:
          persist-credentials: false

      - name: Install and Build # 下载依赖 打包项目
        run: |
          npm install
          npm run build

      - name: Deploy # 将打包内容发布到 github page
        uses: JamesIves/github-pages-deploy-action@3.5.9 # 使用别人写好的 actions
        with:  # 自定义环境变量
          ACCESS_TOKEN: ${{ secrets.VUE_ADMIN_TEMPLATE }} # VUE_ADMIN_TEMPLATE 是我的 secret 名称,需要替换成你的
          BRANCH: master
          FOLDER: dist
          REPOSITORY_NAME: woai3c/woai3c.github.io # 这是我的 github page 仓库
          TARGET_FOLDER: github-actions-demo # 打包的文件将放到静态服务器 github-actions-demo 目录下

上面有一个 ACCESS_TOKEN 变量需要自己配置。

  1. 打开 Github 网站,点击你右上角的头像,选择 settings

在这里插入图片描述

  1. 点击左下角的 developer settings

在这里插入图片描述

  1. 在左侧边栏中,单击 Personal access tokens(个人访问令牌)

在这里插入图片描述

  1. 单击 Generate new token(生成新令牌)

在这里插入图片描述

  1. 输入名称并勾选 repo

在这里插入图片描述

  1. 拉到最下面,点击 Generate token,并将生成的 token 保存起来。

在这里插入图片描述

  1. 打开你的 Github 项目,点击 settings

在这里插入图片描述
点击 secrets->new secret
在这里插入图片描述
创建一个密钥,名称随便填(中间用下划线隔开),内容填入刚才创建的 token。
在这里插入图片描述

在这里插入图片描述
将上文代码中的 ACCESS_TOKEN: ${{ secrets.VUE_ADMIN_TEMPLATE }} 替换成刚才创建的 secret 名字,替换后代码如下 ACCESS_TOKEN: ${{ secrets.TEST_A_B }}。保存后,提交到 Github。

以后你的项目只要执行 git push,Github Actions 就会自动构建项目并发布到你的 Github Page 上。

Github Actions 的执行详情点击仓库中的 Actions 选项查看。

在这里插入图片描述
在这里插入图片描述
具体详情可以参考一下我的 demo 项目 github-actions-demo

构建成功后,打开 Github Page 网站,可以发现内容已经发布成功。

在这里插入图片描述

Github Actions 部署到阿里云

初始化阿里云服务器

  1. 购买阿里云服务器,选择操作系统,我选的 ubuntu
  2. 在云服务器管理控制台选择实例->更多->密钥->重置实例密码(一会登陆用)
  3. 选择远程连接->VNC,会弹出一个密码,记住它,以后远程连接要用(ctrl + alt + f1~f6 切换终端,例如 ctrl + alt + f1 是第一个终端)
  4. 进入后是一个命令行 输入 root(默认用户名),密码为你刚才重置的实例密码
  5. 登陆成功, 更新安装源 sudo apt-get update && sudo apt-get upgrade -y
  6. 安装 npm sudo apt-get install npm
  7. 安装 npm 管理包 sudo npm install -g n
  8. 安装 node 最新稳定版 sudo n stable

创建一个静态服务器

mkdir node-server // 创建 node-server 文件夹
cd node-server // 进入 node-server 文件夹
npm init -y // 初始化项目
npm i express
touch server.js // 创建 server.js 文件
vim server.js // 编辑 server.js 文件

将以下代码输入进去(用 vim 进入文件后按 i 进行编辑,保存时按 esc 然后输入 :wq,再按 enter),更多使用方法请自行搜索。

const express = require('express')
const app = express()
const port = 3388 // 填入自己的阿里云映射端口,在网络安全组配置。

app.use(express.static('dist'))

app.listen(port, '0.0.0.0', () => {
    console.log(`listening`)
})

执行 node server.js 开始监听,由于暂时没有 dist 目录,先不要着急。

注意,监听 IP 必须为 0.0.0.0 ,详情请看部署Node.js项目注意事项

阿里云入端口要在网络安全组中查看与配置。

在这里插入图片描述

创建阿里云密钥对

请参考创建SSH密钥对绑定SSH密钥对 ,将你的 ECS 服务器实例和密钥绑定,然后将私钥保存到你的电脑(例如保存在 ecs.pem 文件)。

打开你要部署到阿里云的 Github 项目,点击 setting->secrets。

在这里插入图片描述
点击 new secret
在这里插入图片描述
secret 名称为 SERVER_SSH_KEY,并将刚才的阿里云密钥填入内容。

在这里插入图片描述
点击 add secret 完成。

在你项目下建立 .github\workflows\ci.yml 文件,填入以下内容:

name: Build app and deploy to aliyun
on:
  #监听push操作
  push:
    branches:
      # master分支,你也可以改成其他分支
      - master
jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1
    - name: Install Node.js
      uses: actions/setup-node@v1
      with:
        node-version: '12.16.2'
    - name: Install npm dependencies
      run: npm install
    - name: Run build task
      run: npm run build
    - name: Deploy to Server
      uses: easingthemes/ssh-deploy@v2.1.5
      env:
          SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_KEY }}
          ARGS: '-rltgoDzvO --delete'
          SOURCE: dist # 这是要复制到阿里云静态服务器的文件夹名称
          REMOTE_HOST: '118.190.217.8' # 你的阿里云公网地址
          REMOTE_USER: root # 阿里云登录后默认为 root 用户,并且所在文件夹为 root
          TARGET: /root/node-server # 打包后的 dist 文件夹将放在 /root/node-server

保存,推送到 Github 上。

以后只要你的项目执行 git push 操作,就会自动执行 ci.yml 定义的脚本,将打包文件放到你的阿里云静态服务器上。

这个 Actions 主要做了两件事:

  1. 克隆你的项目,下载依赖,打包。
  2. 用你的阿里云私钥以 SSH 的方式登录到阿里云,把打包的文件上传(使用 rsync)到阿里云指定的文件夹中。

如果还是不懂,建议看一下我的 demo

ci.yml 配置文件讲解

  1. name,表示这个工作流程(workflow)的名称。
  2. on,表示监听的意思,后面可以加上各种事件,例如 push 事件。

下面这段代码表示要监听 master 分支的 push 事件。当 Github Actions 监听到 push 事件发生时,它就会执行下面 jobs 定义的一系列操作。

name: Build app and deploy to aliyun
on:
  #监听push操作
  push:
    branches:
      # master分支,你也可以改成其他分支
      - master
jobs:
...
  1. jobs,看字面意思就是一系列的作业,你可以在 jobs 字段下面定义很多作业,例如 job1job2 等等,并且它们是并行执行的。
jobs:
  job1:
      ...
  job2:
      ...
  job3:
    ...

回头看一下 ci.yml 文件,它只有一个作业,即 build,作业的名称是自己定义的,你叫 good 也可以。

  1. runs-on,表示你这个工作流程要运行在什么操作系统上,ci.yml 文件定义的是最新稳定版的 ubuntu。除了 ubuntu,它还可以选择 Mac 或 Windows。

  1. steps,看字面意思就是一系列的步骤,也就是说这个作业由一系列的步骤完成。例如先执行 step1,再执行 step2...

setps 步骤讲解

setps 其实是一个数组,在 YAML 语法中,以 - 开始就是一个数组项。例如 ['a', 'b', 'c'] 用 YAML 语法表示为:

- a
- b
- c

所以 setps 就是一个步骤数组,从上到下开始执行。从 ci.yml 文件来看,每一个小步骤都有几个相关选项:

  1. name,小步骤的名称。
  2. uses,小步骤使用的 actions 库名称或路径,Github Actions 允许你使用别人写好的 Actions 库。
  3. run,小步骤要执行的 shell 命令。
  4. env,设置与小步骤相关的环境变量。
  5. with,提供参数。

综上所述,ci.yml 文件中的 setps 就很好理解了,下面从头到尾解释一边:

    steps:
    - uses: actions/checkout@v1
    - name: Install Node.js
      uses: actions/setup-node@v1
      with:
        node-version: '12.16.2'
    - name: Install npm dependencies
      run: npm install
    - name: Run build task
      run: npm run build
    - name: Deploy to Server
      uses: easingthemes/ssh-deploy@v2.1.5
      env:
          SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_KEY }}
          ARGS: '-rltgoDzvO --delete'
          SOURCE: dist # 这是要复制到阿里云静态服务器的文件夹名称
          REMOTE_HOST: '118.190.217.8' # 你的阿里云公网地址
          REMOTE_USER: root # 阿里云登录后默认为 root 用户,并且所在文件夹为 root
          TARGET: /root/node-server # 打包后的 dist 文件夹将放在 /root/node-server
  1. 使用 actions/checkout@v1 库克隆代码到 ubuntu 上。
  2. 使用 actions/setup-node@v1 库安装 nodejs,with 提供了一个参数 node-version 表示要安装的 nodejs 版本。
  3. ubuntushell 上执行 npm install 下载依赖。
  4. 执行 npm run build 打包项目。
  5. 使用 easingthemes/ssh-deploy@v2.1.5 库,这个库的作用就是用 SSH 的方式远程登录到阿里云服务器,将打包好的文件夹复制到阿里云指定的目录上。

env 上可以看到,这个 actions 库要求我们提供几个环境变量:

  1. SSH_PRIVATE_KEY: 阿里云密钥对中的私钥(需要你提前写在 github secrets 上),
  2. ARGS: '-rltgoDzvO --delete',没仔细研究,我猜是复制完文件就删除掉。
  3. SOURCE:打包后的文件夹名称
  4. REMOTE_HOST: 阿里云公网 IP 地址
  5. REMOTE_USER: 阿里云服务器的用户名
  6. TARGET: 你要拷贝到阿里云服务器指定目录的名称

如果你想了解一下其他 actions 库的实现,可以直接复制 actions 库的名称去搜索引擎搜索一下,例如搜索 actions/checkout 的结果为:

都看到这了,给个赞再走吧。

参考资料

更多文章,敬请关注

查看原文

Asd528099 收藏了文章 · 10月26日

你可能不知道的Animation动画技巧与细节

作者:凹凸曼 - 阿文

引言

在 web 应用中,前端同学在实现动画效果时往往常用的几种方案:

  1. css3 transition / animation - 实现过渡动画
  2. setInterval / setTimeout - 通过设置一个间隔时间来不断的改变图像的位置
  3. requestAnimationFrame - 通过一个回调函数来改变图像位置,由系统来决定这个回调函数的执行时机,比定时修改的性能更好,不存在失帧现象

在大多数需求中,css3 的 transition / animation 都能满足我们的需求,并且相对于 js 实现,可以大大提升我们的开发效率,降低开发成本。

本篇文章将着重对 animation 的使用做个总结,如果你的工作中动画需求较多,相信本篇文章能够让你有所收获:

  • Animation 常用动画属性
  • Animation 实现不间断播报
  • Animation 实现回弹效果
  • Animation 实现直播点赞效果 ❤️
  • Animation 与 Svg 又会擦出怎样的火花呢?🔥

    1. Loading 组件
    2. 进度条组件
  • Animation steps() 运用 ⏰

    1. 实现打字效果
    2. 绘制帧动画

Animation 常用动画属性

介绍完 animation 常用属性,为了将这些属性更好地理解与运用,下面将手把手实现一些 DEMO 具体讲述

Animation 实现不间断播报

实现不间断播报 DEMO

通过修改内容在父元素中的 y 轴的位置来实现广播效果

@keyframes scroll {
  0%{
    transform: translate(0, 0);
  }
  100%{
    transform: translate(0, -$height);
  }
}

.ul {
  animation-name: scroll;
  animation-duration: 5s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  /* animation: scroll 5s linear infinite; 动画属性简写 */
}

此处为了保存广播滚动效果的连贯性,防止滚动到最后一帧时没有内容,需要多添加一条重复数据进行填充

<div class="ul">
  <div class="li">小刘同学加入了凹凸实验室</div>
  <div class="li">小邓同学加入了凹凸实验室</div>
  <div class="li">小李同学加入了凹凸实验室</div>
  <div class="li">小王同学加入了凹凸实验室</div>
    <!--   插入用于填充的数据数据 -->
  <div class="li">小刘同学加入了凹凸实验室</div>
</div>

Animation 实现回弹效果

通过将过渡动画拆分为多个阶段,每个阶段的 top 属性停留在不同的位置来实现

实现回弹效果 DEMO

/* 规定动画,改变top,opacity */
@keyframes animate {
  0% {
    top: -100%;
    opacity: 0;
  }
  25% {
    top: 60;
    opacity: 1;
  }
  50% {
    top: 48%;
    opacity: 1;
  }
  75% {
    top: 52%;
    opacity: 1;
  }
  100%{
    top: 50%;
    opacity: 1;
  }
}

为了让过渡效果更自然,这里通过 cubic-bezier() 函数定义一个贝塞尔曲线来控制动画播放速度

过渡动画执行完后,为了将让元素应用动画最后一帧的属性值,我们需要使用 animation-fill-mode: forwards

.popup {
  animation-name: animate;
  animation-duration: 0.5s;
  animation-timing-function: cubic-bezier(0.21, 0.85, 1, 1);
  animation-iteration-count: 1;
  animation-fill-mode: forwards;
  /* animation: animate 0.5s cubic-bezier(0.21, 0.85, 1, 1) 1 forwards; 动画属性简写 */
}

Animation 实现点赞效果 Online Code

实现点赞效果 DEMO

相信大多数同学都知道点赞效果,本文章会实现一个简易版的点赞效果,主要讲述一下实现思路:

  1. 为了让气泡可以向上偏移,我们需要先实现一个 y 轴方向上移动的 @keyframes 动画
/* 规定动画,改变y轴偏移距离*/
@keyframes animation-y {
  0%{
   transform:  translate(-50%, 100px) scale(0);
  }
  50%{
   transform:  translate(-50%, -100px) scale(1.5);
  }
  100%{
    transform:  translate(-50%, -300px) scale(1.5);
  }
}
  1. 为了让气泡向上偏移时显得不太单调,我们可以再实现一个 x 轴方向上移动的 @keyframes 动画
/* 规定动画,改变x轴偏移距离 */
@keyframes animation-x {
  0%{
    margin-left: 0px;
  }
  25%{
    margin-left: 25px;
  }
  75%{
    margin-left: -25px;
  }
  100%{
    margin-left: 0px;
  }
}

这里我理解:

  • 虽然是修改 margin 来改变 x 轴偏移距离,但实际上与修改 transform没有太大的性能差异
  • 因为通过 @keyframes animation-y 中的 transform 已经新建了一个渲染层 ( PaintLayers )
  • animation 属性 可以让该渲染层提升至 合成层(Compositing Layers) 拥有单独的图形层 ( GraphicsLayer ),即开启了硬件加速 ,不会影响其他渲染层的 paint、layout
  • 对于合成层(Compositing Layers)相关知识不是很了解的同学,可以阅读一下这篇文章从浏览器渲染层面解析 css3 动效优化原理
  • 如下图所示:

如笔者这里理解有误,还请读者大佬指出,感激不尽~

  1. 给气泡应用上我们所实现的两个 @keyframes 动画
.bubble {
  animation: animation-x 3s -2s linear infinite,animation-y 4s 0s linear 1;
/*  给 bubble 开启了硬件加速 */
}
  1. 在点赞事件中,通过 js 操作动态添加/移除气泡元素
function like() {
  const likeDom = document.createElement('div');
  likeDom.className = 'bubble'; // 添加样式
  document.body.appendChild(likeDom);  // 添加元素
  setTimeout( () => {
    document.body.removeChild(likeDom);  // 移除元素
  }, 4000)
}

Animation 与 Svg 绘制 loading/进度条 组件 🔥 Online Code

Animation 与 Svg 绘制 loading/进度条 组件 🔥 DEMO

  1. 首先,我们使用 svg 绘制一个圆周长为2 * 25 * PI = 157 的圆
<svg with='200' height='200' viewBox="0 0 100 100"  >
  <circle cx="50" cy="50" r="25"  fill="transparent" stroke-width="4" stroke="#0079f5" ></circie>
</svg>

  1. 将实线圆绘制成虚线圆,这里需要用 stoke-dasharray:50, 50 (可简写为50) 属性来绘制虚线, stoke-dasharray 参考资料
  • 它的值是一个数列,数与数之间用逗号或者空白隔开,指定短划线(50px)缺口(50px)的长度。
  • 由于50(短划线) + 50(缺口) + 50(段划线) = 150, 150 < 157,无法绘制出完整的圆,所以会导致右边存在缺口(7px)
<svg with='200' height='200' viewBox="0 0 100 100"  >
  <circle cx="50" cy="50" r="25"  fill="transparent" stroke-width="4" stroke-dasharray="50" stroke="#0079f5" ></circie>
</svg>

  1. stroke-dashoffset 属性可以使圆的短划线和缺口产生偏移,添加 @keyframes 动画后能够实现从无到有的效果,stoke-dashoffset 参考资料
  • 设置 stroke-dasharray="157 157",指定 短划线(157px)缺口(157px) 的长度。
  • 添加 @keyframes 动画 修改stroke-dashoffset值, 值为正数逆时针偏移🔄,, 值为负数时,顺时针偏移🔃
@keyframes loading {
  0%{
    stroke-dashoffset: 0;
  }
  100%{
    stroke-dashoffset: -157; /* 线条顺时针偏移 */
  }
}
circle{
    animation: loading 1s 0s ease-out infinite;
}

  1. 修改短划线和缺口值
  • 为了让 loading 组件线条可见,我们需要一个50px的短划线,设置 stroke-dasharray="50"
  • 为了让短划线发生偏移后可以完全消失,缺口需要大于或等于圆周长157,设置 stroke-dasharray="50 157"
  • 添加 @keyframes 动画,为了让动画结束时仍处理动画开始位置,需要修改 stroke-dashoffset:-207(短划线+缺口长度)
  • 进度条也是类似原理,帮助理解 stroke-dashoffset 属性,具体实现请查看示例
@keyframes loading {
  0%{
    stroke-dashoffset: 0;
  }
  100%{
    stroke-dashoffset: -207; /* 保证动画结束时仍处理动画开始位置 */
  }
}
circle{
    animation: loading 1s 0s ease-out infinite;
}

Animation steps()运用

steps()animation-timing-function 的属性值

animation-timing-function : steps(number[, end | start])
  • steps 函数指定了一个阶跃函数,它接受两个参数
  • 第一个参数接受一个整数值,表示两个关键帧之间分几步完成
  • 第二个参数有两个值 start or end。默认值为 end
  • step-start 等同于 step(1, start)。step-end 等同于 step(1, end)

steps 适用于关键帧动画,第一个参数将两个关键帧细分为N帧,第二个参数决定从一帧到另一帧的中间间隔是用开始帧还是结束帧来进行填充。

看下图可以发现:

  • steps(N, start)将动画分为N段,动画在每一段的起点发生阶跃(即图中的空心圆 → 实心圆),动画结束时停留在了第 N 帧
  • steps(N, end)将动画分为N段,动画在每一段的终点发生阶跃(即图中的空心圆 → 实心圆),动画结束时第 N 帧已经被跳过(即图中的空心圆 → 实心圆),停留在了 N+1 帧。

实践出真知!

Animation 实现打字效果

Animation 实现打字效果 DEMO

  • 此处用英文字母(I'm an O2man.)举例,一共有13个字符。[经测试,多数中文字体每个字符宽高都相等]
  • steps(13)可以将 @keyframes 动画分为13阶段运行,且每一阶段运行距离相等

效果如下:

/* 改变容器宽度 */
@keyframes animate-x {
  0%{
    width: 0;
  }
}

p {
    width: 125px;
    overflow: hidden;
    border-right: 1px solid transparent;
    animation: animate-x 3s 0s steps(13) 1 forwards;
}
  • 可以发现仅仅这样还不够,动画运行过程中出现了字符被截断的情况,为了保证每个阶段运行后能准确无误地显示当前所处阶段的字符,我们还需要保证每个字符的width与动画每一阶段运行的距离相等
  • 设置Monaco字体属性,用以保证每个字符的 width 相同,具体像素受fontSize属性影响,示例中的字体宽度约为 9.6px,9.6px * 13(段数) = 124.8px (125px),所以当我们设置容器宽度为 125px,即可的达成目的:每个字符的 width 与动画每一阶段运行的距离相等(约为 9.6px )
p {
    /* 设置 Monaco 字体属性,字体大小为16px,用以保证每个字符的 width 相同,width 约为9.6p */
    font-family: Monaco;
    /* 9.6px * 13 = 124.8px (125px) */
    width: 125px ;
    font-size: 16px;
    overflow: hidden;
    border-right: 1px solid transparent;
    /* 同时应用动画 animate-x、cursor-x */
    animation: animate-x 3s 0s steps(13) 1 forwards,cursor-x 0.4s 0s linear infinite;
}

Animation 实现帧动画 ⏰

Animation 实现帧动画 ⏰ DEMO

.main {
  width: 260px;
  height: 200px;
  background: url(url) no-repeat;
  background-size: 100%;
  background-position: 0 0;
}
  • 添加 @keyframes 修改 background-position,让背景图移动
@keyframes animate {
    0% {
        background-position: 0 0;
    }

    100% {
        background-position: 0 100%;
    }
}
.main{
  width: 260px;
  height: 200px;
  background: url(url) no-repeat;
  background-size: 100%;
  background-position: 0 0;
  animation: animate 2s 1s steps(47) infinite alternate;
}
  • 同时, css 还提供了animation-play-state用于控制动画是否暂停
input:checked+.main{
    animation-play-state: paused;
}

文章篇幅较长,感谢大家的阅读,希望各位看客能够有所收获~ ~ ~


参考资料

Animation 常用动画属性
CSS 参考手册
steps() 参考资料
SVG 学习之 stroke-dasharray 和 stroke-dashoffset 详解
理解 CSS3 Animation 中的 steps()
【译】css 动画里的 steps()用法详解
CSS Will Change


欢迎关注凹凸实验室博客:aotu.io

或者关注凹凸实验室公众号(AOTULabs),不定时推送文章。

查看原文

Asd528099 收藏了文章 · 10月26日

前端更应懂产品

关注公众号“执鸢者”,回复“红宝书”获取“javaScript高级程序第四版(pdf)”并进入专业交流群.
个人观点:前端工程师是最接近用户的研发工程师,我的观点就是“前端更应懂产品”。有人肯定会质疑我的观点,产品不是产品经理的事情,我们敲代码的懂这个有什么用?我们程序员懂技术不就行了吗?的确,技术对我们来说很重要,但是我认为产品对程序员(特别是前端工程师)也很重要。一方面毕竟产品是技术变现的途径,没有变现怎么来维护公司正常运营,给我们提供学习技术的土壤;另一方面学习产品知识能够为我们的职业生涯续命——(某位前辈说的,我也很认同)。本着这种想法,自己一直想了解一些产品的知识,可是没有合适的契机。近期一位“同学”给我推荐了“腾讯8分钟产品课”,收获良多,算是自己入坑产品的第一门课程。(纯属个人观点,不喜勿喷
本文将利用八张图从用户、定位、需求、时机、匠心、危机、合作、商业化八个方面对整门课进行了总结,并加入一些自己的理解,与诸君共同交流、学习、进步,欢迎诸位留言交流。

一、用户

开发一款产品目的是服务于用户,说白了用户就是我们的金主“爸爸”,所以开发一款产品前应该做的就是定义我们的用户群体并从用户的角度去考虑问题,这样才能让我们的产品拥有更大的市场——归结一句就是从用户思维考虑问题。

二、定位

每一个产品开发初期都存在一个定位,后期的业务拓展都将服务该定位。就拿我们团队来说,核心是为媒体服务(为媒体投放广告),后期开展的工作都是围绕该核心进行,例如开发了很多智能工具,其目的是为了媒体进行最优投放。

三、需求

每一个产品都是为了解决人们生活中的痛点问题,所以我们应该有一双善于发现的眼睛,发现用户的心理诉求,让用户变的更方便、更舒适、更“懒”。基于我们发现的需求,按照需求的紧急程度依次完成。

四、时机

说白了就是要了解外部环境。就拿前端工程师找工作来说,目前市场上需要的是技术栈是React、Vue,你面试的时候再谈jQuery是不是就有点与外部环境脱节了,如果你是后者,显然没有了解目前的技术环境。

五、匠心

每一位工程师对待自己的产品都应该有工匠精神,不断进行打磨、不断进行优化、不断做的更加傻瓜好用,这样才能做到业界领先。

六、危机

生于忧患死于安乐,时刻保持危机感,不断去了解我们产品当前的状况,基于内外部环境变换去优化产品,才能让产品的生命周期更长。(此处有个疑问,短视频行业的未来是不是AR、VR、全息投影?)

七、合作

合作的前提条件是利益,找到共赢点才能更好的合作。

八、商业化

不管是谁,开发一款产品的目的肯定是为了赚钱,考虑好该产品的盈利点并获得利益才能正向的促进该产品的“进化”——(产品赚钱如果不损害用户体验该多好,感觉微信朋友圈的广告就很好,不仔细看根本看不出是广告)

欢迎大家关注公众号(回复“书籍”获取大量前端学习资料,回复“前端视频”获取大量前端教学视频)
1.如果觉得这篇文章还不错,来个分享、点赞、吧,让更多的人也看到
2.关注公众号执鸢者,领取学习资料,定期为你推送原创深度好文

image
查看原文

认证与成就

  • 获得 4 次点赞
  • 获得 46 枚徽章 获得 0 枚金徽章, 获得 7 枚银徽章, 获得 39 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2018-09-19
个人主页被 646 人浏览