加油!离回家更近一步!!!
vue 模板编译的过程
缓存公共的 mount 函数,并重写浏览器平台的 mount 判断是否传入了 render 函数,没有的话,是否传入了 template ,没有的话,则获取 el 节点的 outerHTML 作为 template 调用 baseCompile 函数 解析器(parse) 将模板字符串的模板编译转换成 AST 抽象语法树 优化器(optimize) - 对 AST 进行静态节点标记,主要用来做虚拟DOM的渲染优化 通过 generate 将 AST 抽象语法树转换为 render 函数的 js 字符串 将 render 函数 通过 createFunction 函数 转换为 一个可以执行的函数 将 最后的 render 函数 挂载到 option 中 执行 公共的 mount 函数 最后生成真实Dom。
vue 实现 nextTick 原理
使用原理: Vue是异步执行dom更新的,一旦观察到数据变化,Vue就会开启一个队列,然后把在同一个事件循环(event loop)当中观察到数据变化的watcher推送进这个队列。如果这个watcher被触发多次,只会被推送到队列一次。这种缓冲行为可以有效的去掉重复数据造成的不必要的计算和DOM操作。而在下一个事件循环时,Vue会清空队列,并进行必要的DOM更新。 当你设置vm.someData = ‘new value’,DOM并不会马上更新,而是在异步队列被清除,也就是下一个事件循环开始时执行更新时才会进行必要的DOM更新。如果此时你想要根据更新的DOM状态去做某些事情,就会出现问题。。为了在数据变化之后等待Vue 完成更新DOM,可以在数据变化之后立即使用Vue.nextTick(callback)。这样回调函数在DOM更新完成后就会调用。
Etag 是 http 哪个版本出来的?它出来是为了解决什么问题?
是HTTP1.1版本出来的。是HTTP头信息。 Etag由服务器端生成,客户端通过If-Match或者说If-None-Match这个条件判断请求来验证资源是否修改。
设置小于12px的字体
在谷歌下css设置字体大小为12px及以下时,显示都是一样大小,都是默认12px。
解决办法:
- 使用Webkit的内核的-webkit-text-size-adjust的私有CSS属性来解决,只要加了-webkit-text-size-adjust:none;字体大小就不受限制了。但是chrome更新到27版本之后就不可以用了。所以高版本chrome谷歌浏览器已经不再支持-webkit-text-size-adjust样式,所以要使用时候慎用。
- 使用css3的transform缩放属性-webkit-transform:scale(0.5); 注意-webkit-transform:scale(0.75);收缩的是整个元素的大小,这时候,如果是内联元素,必须要将内联元素转换成块元素,可以使用display:block/inline-block/…;
- 使用图片:如果是内容固定不变情况下,使用将小于12px文字内容切出做图片,这样不影响兼容也不影响美观。
webpack
是一个前端模块化打包工具。
grunt/gulp更加强调的是前端流程的自动化,模块化不是它的核心。 webpack更加强调模块化开发管理,而文件压缩合并预处理等功能,是他附带的功能。
webpack安装
环境依赖于node
npm install --save-dev webpack
npm install --save-dev webpack@<version>
webpack4依赖 webpack-cli@3
本地安装(局部安装,安装在本项目)
yarn init -y
yarn add webpack@4 webpack-cli@3
全局安装(不要使用,不建议使用)
yarn global add webpack@4 webpack-cli@3
–save-dev 代表这个包是一个开发依赖(只会安装在当前的项目中,简写 -D)
目前来说,不建议将工具包安装为全局包,因为这样不好
- 例如:我们在全局内安装了 webpack5 版本。
- 如果是在公司进行开发的时候,隔了一段时间,公司老大给了一个要维护一下两年前开发出来的一个项目,但是这个项目当时依赖的 webpack版本是4版本。现在要维护4的同时,还要做5版本项目的开发。这种情况下,就出现版本的冲突,这个就是全局包面临的困境。
+为了解决这种困境,那么我们就不要想工具包安装为全局包,而是把这些包安装成项目中的依赖包。如果安装成项目包,则不会提供一个全局的执行命令。则这个时候 npm 提供了一个 npx 的命令,该命令可以帮我们去执行我们项目中依赖的工具包提供的命令。
webpack配置文件
想要自动的生成dist文件,自主命名,新建webpack.config.js文件
webpack的配置文件
* 1. 定义入口 项目启动js文件
* 2. 定义出口 打包后的文件
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/app.js',
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
},
麻烦的话可以在package.json文件里配置
"scripts": {
"dev": "webpack --watch --progress --profile --color"
},
运行的时候直接 yarn dev
module: {
rules: [
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
}
]
}
}
less-loader的基本使用
如果引入less文件,一般是不能转化的,需要用到less-loader
yarn add less-loader less
webpack.config.js文件新增
{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
}
html-webpack-plugin和webpack-dev-server的基本使用
不用手动引入打包后的js文件
- html-webpack-plugin可以使用一个 html 模板文件作为项目的首页
- webpack-dev-server 负责开启一个调试服务器
yarn add html-webpack-plugin@4 webpack-dev-server@3
webpackconfig.js 配置
const path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: './src/app.js',
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
},
module: {},
plugins: [new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/assets/index.html'
})]
}
package.json配置
"scripts": {
"serve": "webpack-dev-server --config webpack.config.js"
}
webpack和babel的使用
babel:是一个编译工具,可以把 es6+ 的语法特性转换为 es5 浏览器可识别的语法。
yarn add babel-cli babel-preset-es2015
webpack中的babel构建相关环境
yarn add webpack@4 webpack-cli@3 @babel/core @babel/preset-react @babel/preset-env babel-preset-mobx @babel/plugin-proposal-object-rest-spread @babel/plugin-transform-runtime @babel/runtime babel-loader
在package.json同及目录创建一个.babelrc文件
{
"presets": ["@babel/preset-env", "@babel/preset-react", "mobx"],
"plugins": [
"@babel/plugin-proposal-object-rest-spread",
"@babel/plugin-transform-runtime"
]
}
修改webpack.config.json内容
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
},
就能写js语法了
运行 npx webpack
webpack和vue-loader配合使用
yarn add webpack@4 webpack-cli@3 vue vue-loader css-loader@3 style-loader@1 vue-template-compiler
import Vue from 'vue'
import App from './app.vue'
const root = document.createElement('div')
document.body.appendChild(root)
new Vue({
render: (h) => h(App)
}).$mount(root)
app.vue
<template>
<div id="test">{{text}}</div>
</template>
<script>
export default {
data() {
return {
text: '我的第一个单组件'
}
}
}
</script>
<style>
#test{
color: red;
}
</style>
const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
plugins: [
new VueLoaderPlugin()
],
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.css$/,
use: ['style-loader','css-loader']
}
]
}
};
运行 npx webpack
|| 和 && 操作符的返回值
|| 和 && 首先会对第一个操作数执行条件判断,如果其不是布尔值就先强制转换为布尔类型,然后再执行条件判断。
- 对于 || 来说,如果条件判断结果为 true 就返回第一个操作数的值,如果为 false 就返回第二个操作数的值。
- && 则相反,如果条件判断结果为 true 就返回第二个操作数的值,如果为 false 就返回第一个操作数的值。
|| 和 && 返回它们其中一个操作数的值,而非条件判断的结果
常用的正则表达式
var regex = /#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g;
var regex = /^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/;
var regex = /^[1-9][0-9]{4,10}$/g;
var regex = /^1[34578]\d{9}$/g;
var regex = /^[a-zA-Z\$][a-zA-Z0-9_\$]{4,16}$/;
常见的DOM操作有哪些
1)DOM 节点的获取
DOM 节点的获取的API及使用:
getElementById
getElementsByTagName
getElementsByClassName
querySelectorAll
var imooc = document.getElementById('imooc')
var pList = document.getElementsByTagName('p')
console.log(divList.length)
console.log(divList[0])
var moocList = document.getElementsByClassName('mooc')
var pList = document.querySelectorAll('.mooc')
复制代码
2)DOM 节点的创建
创建一个新节点,并把它添加到指定节点的后面。 已知的 HTML 结构如下:
<html>
<head>
<title>DEMO</title>
</head>
<body>
<div id="container">
<h1 id="title">我是标题</h1>
</div>
</body>
</html>
复制代码
要求添加一个有内容的 span 节点到 id 为 title 的节点后面,做法就是:
var container = document.getElementById('container')
var targetSpan = document.createElement('span')
targetSpan.innerHTML = 'hello world'
container.appendChild(targetSpan)
复制代码
3)DOM 节点的删除
删除指定的 DOM 节点, 已知的 HTML 结构如下:
<html>
<head>
<title>DEMO</title>
</head>
<body>
<div id="container">
<h1 id="title">我是标题</h1>
</div>
</body>
</html>
复制代码
需要删除 id 为 title 的元素,做法是:
var container = document.getElementById('container')
var targetNode = document.getElementById('title')
container.removeChild(targetNode)
复制代码
或者通过子节点数组来完成删除:
复制代码
4)修改 DOM 元素
修改 DOM 元素这个动作可以分很多维度,比如说移动 DOM 元素的位置,修改 DOM 元素的属性等。
将指定的两个 DOM 元素交换位置, 已知的 HTML 结构如下:
<html>
<head>
<title>DEMO</title>
</head>
<body>
<div id="container">
<h1 id="title">我是标题</h1>
<p id="content">我是内容</p>
</div>
</body>
</html>
复制代码
现在需要调换 title 和 content 的位置,可以考虑 insertBefore 或者 appendChild:
var container = document.getElementById('container')
var title = document.getElementById('title')
var content = document.getElementById('content')
container.insertBefore(content, title)
|