Taohong的博客


  • Home

  • Archives

css工程化

Posted on 2018-06-09 | In 技术

工程化特性

  • 组织
  • 优化
  • 构建
  • 维护

PostCSS

作用

  1. 模块化
  2. 加前缀
  3. 兼容性
  4. …

特点

  1. PostCSS本身只有解析能力
  2. 各种特性全靠插件
  3. 目前至少有200多个插件

常用插件

  • import 模块合并
  • autoprefixier 自动添加前缀
  • cssnano 压缩代码
  • cssnext 使用css新特性
  • precss 变量、mixin、循环等

css动画

Posted on 2018-06-09 | In 技术

补间动画 transition

关键帧动画 keyframes

  1. 相当于多个补间动画
  2. 与元素状态的变化无关
  3. 定义更加灵活

逐帧动画

  1. 适用于无法补间计算的动画
  2. 资源较大
  3. 使用steps()

css布局

Posted on 2018-06-09 | In 技术

布局重点

  1. table布局
  2. 技巧性布局
  3. flexbox/grid布局
  4. 响应式布局

盒模型

content + padding + border + margin

? box-sizing

display/position

display 确定元素的显示类型

block/inline/inline-block

position 确定元素的位置

static/relative/absolute/fixed

flexbox 布局

float + margin 布局

  • 元素“浮动”
  • 脱离文档流
  • 但不脱离文本流

对自身对影响

  • 形成“块”(BFC)
  • 位置尽量考上
  • 位置尽量靠左(右)

对兄弟元素的影响

  • 上面贴非float元素(一般)
  • 旁边贴float元素
  • 不影响其他块级元素的位置
  • 影响其他块级元素的内部文本

对父级

  • 从布局上消失
  • 高度塌陷

修复高度塌陷

  1. 把父元素变为BFC(如加上 overflow:auto)
  2. 添加元素(一般加上伪元素)

三栏布局

用 float + margin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<!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>
.container{
width:800px;
height:200px;
}
.left{
background:red;
/* float:left; */
/* height:100%; */
width:200px;
position: absolute;
height:200px;
}
.right{
background:blue;
float:right;
width:200px;
height:100%;
}
.middle{
margin-left:200px;
margin-right:200px;
}

</style>
</head>
<body>
<div class="container">
<div class="left">
左
</div>
<div class="right">
右
</div>
<div class="middle">
中间
</div>
</div>
</body>
</html>

布局的核心是–如何进行元素的横向排列

inline-block 布局

  1. 像文本一样排 block 元素
  2. 没有清除浮动的问题
  3. 需要处理间隙
    1. 父元素字体大小设为0
    2. 去除元素间的空白

响应式设计和布局

  1. 在不同设备上正常使用
  2. 一般处理大小问题
  3. 主要方法
    1. 隐藏 + 折行 + 自适应空间
    2. rem/viewprot/media query

css面试题

Posted on 2018-06-09 | In 技术

基础

如何确定css优先级

  1. 选择器权重(id+100,类/属性/伪类+10,元素/伪元素+1,其他+0)
  2. !important
  3. 内联样式
  4. 相同权重,后写的高

伪类和伪元素的区别

  1. 伪类是状态,伪元素是元素
  2. 伪类用:,伪元素用::

效果

如何用一个div画XXX

  • box-shadow 无限投影
  • ::before
  • ::after

如何产生不占空间的边框

  1. box-shadow
  2. outline

动画

transtion/keyframes 如何写

略

css动画实现方式有几种

  • transtion
  • keyframes(animation)

过度动画和关键帧动画的区别

  1. 过渡动画需要有状态变化
  2. 关键帧动画不需要状态变化
  3. 关键帧动画能控制更精细

如何实现逐帧动画

  1. 使用关键帧动画
  2. 去掉补间(steps)

webpack常见面试题

Posted on 2018-06-08 | In 技术
介绍常见webpack面试题,分为 1. 概念 2. 配置 3. 开发 4. 优化 四方面。
Read more »

如何从0开始配置webapck

Posted on 2018-06-08 | In 技术

思维导图

vue基础

Posted on 2018-06-07 | In 技术

内部指令

名称 说明
v-if v-else 是否加载html中的DOM
v-show 是否用display属性显示出来
v-for 循环渲染
v-text v-html 输出text 输出html
v-on 绑定事件监听,缩写@
v-model 双向绑定,修饰符.lazy、.number、.trim
v-bind 绑定标签的属性,缩写:
其它 v-pre,v-cloak,v-once 输出原始值,渲染整个DOM后再显示,渲染一次

全局API

什么是全局API?

全局API并不在构造器里,而是先声明全局变量或者直接在Vue上定义一些新功能,Vue内置了一些全局API,比如Vue.directive。说的简单些就是,在构造器外部用Vue提供给我们的API函数来定义新的功能。

名称 说明
Vue.extend 使用基础 Vue 构造器,创建一个“子类”
Vue.nextTick 在下次 DOM 更新循环结束之后执行延迟回调
Vue.set 向响应式对象中添加一个属性
Vue.delete 删除对象的属性
Vue.directive 注册或获取全局指令
Vue.filter 注册或获取全局过滤器
Vue.component 注册或获取全局组件
Vue.use 安装 Vue.js 插件
Vue.mixin 全局注册一个混入
Vue.compile 在 render 函数中编译模板字符串。只在独立构建时有效
Vue.version 提供字符串形式的 Vue 安装版本号

选项

数据

名称 说明
data Vue 实例的数据对象
props 用于接收来自父组件的数据
propsData 创建实例时传递 props。主要作用是方便测试。
computed 计算属性将被混入到 Vue 实例中
methods methods 将被混入到 Vue 实例中
watch 一个对象,键是需要观察的表达式,值是对应回调函数

DOM

名称 说明
el 提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标
render 一个字符串模板作为 Vue 实例的标识使用
renderError 当 render 函数遭遇错误时,提供另外一种渲染输出

生命周期钩子

名称 说明
beforeCreate 在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
created 在实例创建完成后被立即调用。
beforeMount 在挂载开始之前被调用
mounted el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。
beforeUpdate 数据更新时调用,发生在虚拟 DOM 打补丁之前。
updated 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
beforeDestroy 实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed Vue 实例销毁后调用。
activated keep-alive 组件激活时调用。
deactivated keep-alive 组件停用时调用。

资源

名称 说明
directives 包含 Vue 实例可用指令的哈希表。
filters 包含 Vue 实例可用过滤器的哈希表。
components 包含 Vue 实例可用组件的哈希表。

组合

名称 说明
parent 指定已创建的实例之父实例,在两者之间建立父子关系
mixins 选项接受一个混入对象的数组。
extends 允许声明扩展另一个组件
provide / inject 提供/注入 主要为高阶插件/组件库提供用例

VS code ESLint 配置

Posted on 2018-05-31 | In 技术

下面是说明如何在 VS Code 中对 vue 代码进行检查和自动修复

安装插件

安装 VS code 插件 vetur 和 ESLint

  • vetur 是 vue 官方的插件,集成了许多开发必要的功能
  • ESlint 是 检查工具

配置 浏览器设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"eslint.validate": [
"javascript",
"javascriptreact",
// 支持 *.vue
{
"language": "vue",
"autoFix": true
},
],
// 保存时设置文件的格式。格式化程序必须可用,不能自动保存文件,并且不能关闭编辑器。
"editor.formatOnSave": true,
// 在保存和关闭时自动修复代码
"eslint.autoFixOnSave": true,
// Vetur 自动使用 eslint-plugin-vue 检测 <template>。Linting配置基于 eslint-plugin-vue 的基本规则集。这是成 false 关闭它
"vetur.validation.template": false
}

安装依赖

1
yarn add -D eslint eslint-plugin-vue

设置 ESLint 规则。下面是一个例子:

在 .eslintrc 中配置

1
2
3
4
5
6
7
8
9
{
"extends": [
"eslint:recommended",
"plugin:vue/recommended"
],
"rules": {
"vue/html-self-closing": "off"
}
}

参考链接

Vetur Linting 配置

VS Code debug 配置

Posted on 2018-05-31 | In 技术

下面是说明通过 Vue CLI 生成的 Vue.js 应用程序中,如何使用 VS Code 的 Debugger for Chrome 扩展进行调试

先决条件

  1. 安装好chrome 和 VSCode
  2. 通过 vue-cli 创建项目

在 Chrome Devtools 中展示源代码

打开 config/index.js 并找到 devtool 属性。将其更新为:

1
devtool: 'source-map',

从 VS Code 启动应用

配置 .vscode/launch.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "vuejs: chrome",
"url": "http://localhost:8080",
"webRoot": "${workspaceFolder}/src",
"breakOnLoad": true,
"sourceMapPathOverrides": {
"webpack:///src/*": "${webRoot}/*"
}
}
]
}

调试

  1. 设置断点
  2. 用终端工具输入 npm start启动项目
  3. 来到 Debug 视图,选择 ‘vuejs: chrome’ 配置,然后按 F5 或点击那个绿色的 play 按钮。
  4. 随着一个新的 Chrome 实例打开 http://localhost:8080,你的断点现在应该被命中了。

我在调试中碰到了返回 500 Internal Privoxy Error 的情况,后来发现是代理工具 shadowsocks 代理模式设置为全局模式的原因,把模式修改为 PAC 模式后便可正常调试了。

参考链接

vue官方配置说明

参考vue-cli的脚手架开发

Posted on 2018-05-17 | In 技术

前言

我在公司的业务主要有三种:

  • 管理后台,页面结构基本不变,模块可重复使用。
  • webApp,页面的交互较复杂,要根据设计深度定制。
  • 简单页面,一般是配合native app 使用的页面,例如活动页面,简单的内容介绍页面,交互少,开发周期短。

业务上基本形成了稳定的套路,这时候开发一套自己的脚手架工具是必要的

  • 减少重复性工作,提高开发效率。
  • 给不同的业务创建不同的模版,容易迭代和维护。

一方面是为了业务需要,一方面是为了练手,决定仿照vue-cli写一个脚手架工具。

思路

vue-cli 整体思路:

  • 将脚手架和各个模板独立发布到Git上。
  • 通过脚手架下载模版。
  • 通过与脚手架的交互信息,渲染模版,得到项目基本结构。

阅读vue-cli的代码,代码思路如下:

  1. vue 命令会执行 package.json 下的 bin 中指定的文件,也就是 bin/vue。这个文件中主要用到 commander 这个包,这个包可以用来设置不同的命令。
  2. vue init 执行 bin/vue-init。
  3. vue init 根据你输入的官方模版或者远程仓库中的模板名下载模版,用到的包是 download-git-repo。
  4. 仓库中有 template 目录,这里面是模版,有 meta.js 或者 meta.json 文件,里面的是配置内容,会被 inquirer 这个包使用,进行交互式问答,后面根据问答结果渲染模版。
  5. metalsmith 这个包根据问答内容渲染模版,这里还用到了模版引擎 handlers。

远程仓库工程结构

1
2
/template # ------ 模版
meta.json # ------ 互动内容

脚手架工程结构

1
2
3
/bin  # ------ 命令执行文件
/lib # ------ 工具模块
package.json

commander

nodejs内置了对命令行操作的支持,node工程下package.json中的bin字段可以定义命令名和关联的执行文件。

1
2
3
4
5
6
{
"name": "hxlz-create-app",
"bin": {
"hxlz": "./bin/hxlz.js"
}
}

经过这样配置的nodejs项目,在使用-g选项进行全局安装的时候,会自动在系统的[prefix]/bin目录下创建相应的符号链接(symlink)关联到执行文件。如果是本地安装,这个符号链接会生成在./node_modules/.bin目录下。这样做的好处是可以直接在终端中像执行命令一样执行nodejs文件。关于prefix,可以通过npm config get prefix获取。

定义命令

在bin目录下创建一个hxlz.js文件,用于处理命令行的逻辑。

1
2
3
4
5
6
7
8
#!/usr/bin/env node

const program = require('commander')

program.version('1.0.0')
.usage('<command> [项目名称]')
.command('init', '创建新项目')
.parse(process.argv)

定义子命令

ommander支持git风格的子命令处理,可以根据子命令自动引导到以特定格式命名的命令执行文件,文件名的格式是[command]-[subcommand],例如:

hxlz init => hxlz-init

在bin目录下创建一个hxlz-init.js文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env node

const program = require('commander')

program.usage('<project-name>').parse(process.argv)

// 根据输入,获取项目名称
let projectName = program.args[0]

if (!projectName) { // project-name 必填
// 相当于执行命令的--help选项,显示help信息,这是commander内置的一个命令选项
program.help()
return
}

go()

function go () {
// 预留,处理子命令
}

使用download-git-repo下载模板

新建lib/download.js文件,用于下载模版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const download = require('download-git-repo')

/**
* 下载模板
* @param {string} target 目标文件夹
* @param {string} repo 远程仓库
*/
module.exports = function (target, repo) {
target = path.join(target || '.', '.download-temp')
return new Promise((resolve, reject) => {
download(repo,
target, { clone: true }, (err) => {
if (err) {
reject(err)
} else {
// 下载的模板存放在一个临时路径中,下载完成后,可以向下通知这个临时路径,以便后续处理
resolve(path.resolve(process.cwd(), target))
}
})
})
}

使用Promise的风格处理异步

对hxlz-init.js进行修改

1
2
3
4
5
6
7
8
const download = require('./lib/download')

...
function go () {
download(rootName)
.then(target => console.log(target))
.catch(err => console.log(err))
}

处理远程仓库中的meta.json文件,使用inquirer.js处理命令行交互

这里直接使用了vue-cli的ask.js文件

文件地址

使用metalsmith处理模板

这里还用到了模版引擎handlebars

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const Metalsmith = require('metalsmith')
const Handlebars = require('handlebars')

module.exports = function (metadata = {}, src, dest = '.') {
if (!src) {
return Promise.reject(new Error(`无效的source:${src}`))
}

return new Promise((resolve, reject) => {
Metalsmith(process.cwd())
.metadata(metadata)
.clean(false)
.source(src)
.destination(dest)
.use((files, metalsmith, done) => {
const meta = metalsmith.metadata()
Object.keys(files).forEach(fileName => {
const t = files[fileName].contents.toString()
files[fileName].contents = new Buffer(Handlebars.compile(t)(meta))
})
done()
}).build(err => {
err ? reject(err) : resolve()
})
})
}

美化脚手架

通过一些工具包,让脚手架更加人性化。这里介绍两个在vue-cli中发现的工具包:

  • ora - 显示spinner
  • chalk - 给枯燥的终端界面添加一些色彩

参考链接

基于node.js平台的脚手架开发经历

从零开始搭建前端脚手架

1234…8

Taohong

记录前端技术,学习心得与生活感悟

80 posts
6 categories
65 tags
© 2020 Taohong
Powered by Hexo
|
Theme — NexT.Muse v5.1.4