标签:property eid 映射 border end require children 文件名 edit
前言:本人作为一个前端小白,梳理一下这段时间开发前端一个页面的过程,希望对自己起到备忘并思考的作用,希望我的经验对于别人也有一点帮助的作用。由于本文碎碎念的部分过长,导致本文过长。还请读者见谅。—更新中(更新周期大概还会持续一个月)
现如今,前端框架也越来越多了,比如ember,angular,以及这里要说到的vuejs.。下面的内容首先要介绍vue.js的原理。
vue.js是一个 MVVM 前端框架,(Model / View / ViewModel)
这里的viewModel是什么含义呢?
这意味着我们不需要撰写任何 DOM 操作代码,被绑定增强的 HTML 模板(<template>
)是底层数据状态的声明式的映射,数据不过是普通 JavaScript 对象。我们的视图完全由数据驱动。
vue将普通的对象(也就是js的普通的对象)的属性通过Object.defineProperty转换为[ES5特性]之一的 getter/setter。
OBJECT
OBJECT.DEFINEPROPERTY()
该方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。Object.defineProperties()与其一样,只是可以同时定义多个属性。
该方法允许精确添加或修改对象的属性。常用的场景
定义setter和getter。
定义对象属性是否可枚举enumerable。
可枚举的属性键值能够被for in和Object.keys获得。
最常见的例子就是,数组中索引属性是可枚举的,而成员方法就是不可枚举的。
~! 这也是为什么我们不要使用for in遍历数组的原因,因为可能有一些拙劣的上下文代码,为数组添加了一个可枚举的方法,因此我们在扩展一个特殊对象属性时特别需要特别关注这一点
OBJECT.KEYS()
把对象的返回一个包括对象可枚举键值的数组。
模板中每个指令/数据绑定 都有一个对应的 watcher 对象, 当修改对象值的时,首先会触发属性的setter,在setter被调用时,会触发 watcher 重新计算 ,也就会导致它的关联指令更新 DOM。
上面的内容把vuejs的内容已说明的很清楚了,如果你能理解指令和数据绑定(下面还会有更多的解释)的话。
Vue.js 的核心是一个响应的数据绑定系统,它让数据与 DOM 保持同步非常简单。在使用 jQuery 手工操作 DOM 时,我们的代码常常是命令式的、重复的与易错的。Vue.js 拥抱数据驱动的视图概念。通俗地讲,它意味着我们在普通 HTML 模板中使用特殊的语法将 DOM “绑定”到底层数据。一旦创建了绑定,DOM 将与数据保持同步。每当修改了数据,DOM 便相应地更新。这样我们应用中的逻辑就几乎都是直接修改数据了,不必与 DOM 更新搅在一起。这让我们的代码更容易撰写、理解与维护。
比如我想在一个项目里面使用到一个灵活的jsoneditor,通过调研发现vuejs并没有直接的组件可以用,但是发现javascript有一个很好用的叫做jsoneditor的组件,那么我们如何在一个vue.js的工程里面加入这个jsoneditor?
这里就会包括很多要解决的问题了,下面的内容将一一道来。
伴随着移动互联的大潮,当今越来越多的网站已经从网页模式进化到了 Webapp 模式。它们运行在现代的高级浏览器里,使用 HTML5、 CSS3、 ES6 等更新的技术来开发丰富的功能,网页已经不仅仅是完成浏览的基本需求,并且webapp通常是一个单页面应用,每一个视图通过异步的方式加载,这导致页面初始化和使用过程中会加载越来越多的 JavaScript 代码,这给前端开发的流程和资源组织带来了巨大的挑战。
前端开发和其他开发工作的主要区别,首先是前端是基于多语言、多层次的编码和组织工作,其次前端产品的交付是基于浏览器,这些资源是通过增量加载的方式运行到浏览器端,如何在开发环境组织好这些碎片化的代码和资源,并且保证他们在浏览器端快速、优雅的加载和更新,就需要一个模块化系统,这个理想中的模块化系统是前端工程师多年来一直探索的难题。
模块系统主要解决模块的定义、依赖和导出,先来看看已经存在的模块系统。
<script>标签
<script src="module1.js"></script>
<script src="module2.js"></script>
<script src="libraryA.js"></script>
这是最原始的 JavaScript 文件加载方式,如果把每一个文件看做是一个模块,那么他们的接口通常是暴露在全局作用域下,也就是定义在 window 对象中。
CommonJS
服务器端的 Node.js 遵循 CommonJS规范,该规范的核心思想是允许模块通过 require 方法来同步加载所要依赖的其他模块,然后通过 exports 或 module.exports 来导出需要暴露的接口。
require("module");
require("../file.js");
exports.doStuff = function() {};
module.exports = someValue;
上面的代码很好理解,但是看起来似乎能解决的问题并不多。那么期望的模块系统是什么样子的呢?
webpack 就是一个很好的模块化系统。
require("./style.css");
require("./style.less");
require("./template.jade");
require("./image.png");
如何做到让 require 能加载各种资源呢?在编译的时候,要对整个代码进行静态分析,分析出各个模块的类型和它们依赖关系,然后将不同类型的模块提交给适配的加载器来处理。比如一个用 LESS 写的样式模块,可以先用 LESS 加载器将它转成一个CSS 模块,在通过 CSS 模块把他插入到页面的 <style>
标签中执行。
Webpack 是一个模块打包器。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。Webpack 本身只能处理原生的 JavaScript 模块,但是 loader 转换器可以将各种类型的资源转换成 JavaScript 模块。这样,任何资源都可以成为 Webpack 可以处理的模块。
通过NODE_ENV可以来设置环境变量(默认值为development)。
一般我们通过检查这个值来分别对开发环境和生产环境下做不同的处理。可以在命令行中通过下面的方式设置这个值:
linux & mac: export NODE_ENV=production
windows: set NODE_ENV=production
比方说如果代码中要对生产环境下做一些处理,可以这样写:
if (process.env.NODE_ENV === ‘production‘) {
// just for production code
}
webpack 和 Express 实现前后端热更新开发,
Webpack dev server 是一个轻量的node.js express服务器,实现了 webpack 编译代码实时输出更新。在前后端分离的前端项目开发中经常用到。不过这篇文章应该不会讲到它。
“webpack-dev-middleware”: “^1.6.1”,
Webpack hot middleware 它通过订阅 Webpack 的编译更新,之后通过执行 webpack 的 HMR api 将这些代码模块的更新推送给浏览器端。
为了提供诸如图像、CSS 文件和 JavaScript 文件之类的静态文件,请使用 Express 中的 express.static
内置中间件函数。
express.static
是一个内置的中间件
app.use(express.static(‘public‘));
现在,可以装入位于 public 目录中的文件:
http://localhost:3000/images/kitten.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
http://localhost:3000/images/bg.png
http://localhost:3000/hello.html
Express 相对于静态目录查找文件,因此静态目录的名称不是此 URL 的一部分。
app.use(express.static(‘public‘));
app.use(express.static(‘files‘));
要为 express.static 函数提供的文件创建虚拟路径前缀(路径并不实际存在于文件系统中),请为静态目录指定安装路径,如下所示:
app.use(‘/static‘, express.static(‘public‘));
现在,可以装入具有 /static 路径前缀的 public 目录中的文件。
http://localhost:3000/static/images/kitten.jpg
http://localhost:3000/static/css/style.css
http://localhost:3000/static/js/app.js
http://localhost:3000/static/images/bg.png
http://localhost:3000/static/hello.html
Node.js path 模块提供了一些用于处理文件路径的小工具,我们可以通过以下方式引入该模块:
var path = require("path")
path.join([path1][, path2][, …])
用于连接路径。该方法的主要用途在于,会正确使用当前系统的路径分隔符,Unix系统是”/”,Windows系统是”\”。
webpack 2.3.3
Usage: https://webpack.js.org/api/cli/
Usage without config file: webpack <entry> [<entry>] <output>
Usage with config file: webpack
Config options:
--config Path to the config file
[string] [default: webpack.config.js or webpackfile.js]
--env Environment passed to the config, when it is a function
Basic options:
--entry The entry point [string]
--watch, -w Watch the filesystem for changes [boolean]
--debug Switch loaders to debug mode [boolean]
--devtool Enable devtool for better debugging experience (Example:
所以webpack的主要作用就是将入口文件最后变为出口文件,我觉得可能相当于make吧
Loader 可以理解为是模块和资源的转换器,它本身是一个函数,接受源文件作为参数,返回转换的结果。这样,我们就可以通过 require 来加载任何类型的模块或文件,比如 CoffeeScript、 JSX、 LESS 或图片。
Loader 本身也是运行在 node.js 环境中的 JavaScript 模块,它通常会返回一个函数。大多数情况下,我们通过 npm 来管理 loader,但是你也可以在项目中自己写 loader 模块。
通常在webpack.config.js的module.exports中导出的对象中:
比如css loader
module: {
loaders: [
{test: /\.css$/, loader: ‘style-loader!css-loader‘}
]
}
Adds CSS to the DOM by injecting a
<style>
tag
npm install style-loader –save-dev
style-loader的用法如何?
It’s recommended to combine it with the css-loader: require(“style-loader!css-loader!./file.css”).
add rules in file.css to document
The css-loader interprets @import and url() like import/require() and will resolve them.
Loader 可以通过管道方式链式调用,每个 loader 可以把资源转换成任意格式并传递给下一个 loader ,但是最后一个 loader 必须返回 JavaScript。
loader 一般以 xxx-loader 的方式命名,xxx 代表了这个 loader 要做的转换功能,比如 json-loader。
Loader 可以在 require() 引用模块的时候添加,也可以在 webpack 全局配置中进行绑定,还可以通过命令行的方式使用。加载 CSS 需要 css-loader 和 style-loader,他们做两件不同的事情,css-loader会遍历 CSS 文件,然后找到 url() 表达式然后处理他们,style-loader 会把原来的 CSS 代码插入页面中的一个 style 标签中。
require(“!style-loader!css-loader!./style.css”)
因为本文要将的是vue.js,所以下面还会仔细分析vue-loader。
在webpack中加入:
{
test: /\.vue$/,
loader: ‘vue‘
},
而vue-loader的定义:
module.exports = function (content) {
this.cacheable()
var isServer = this.target === ‘node‘
var isProduction = this.minimize || process.env.NODE_ENV === ‘production‘
var loaderContext = this
var query = loaderUtils.getOptions(this) || {}
var options = this.options.__vueOptions__ = Object.assign({}, this.options.vue, this.vue, query)
var rawRequest = getRawRequest(this, options.excludedPreLoaders)
var filePath = this.resourcePath
var fileName = path.basename(filePath)
var context = (this._compiler && this._compiler.context) || this.options.context || process.cwd()
var moduleId = ‘data-v-‘ + genId(filePath, context, options.hashKey)
var cssLoaderOptions = ‘‘
if (!isProduction && this.sourceMap && options.cssSourceMap !== false) {
cssLoaderOptions += ‘?sourceMap‘
}
‘‘‘
// final export
if (options.esModule) {
output += ‘\nexports.__esModule = true;\nexports["default"] = Component.exports\n‘
} else {
output += ‘\nmodule.exports = Component.exports\n‘
}
} else {
// inject-loader support
output =
‘\n/* dependency injection */\n‘ +
‘module.exports = function (injections) {\n‘ + output + ‘\n‘ +
‘\nreturn Component.exports\n}‘
}
// done
return output
}
除此之外,还需要了解的两个loader分别是url-loader和babel-loader.
url-loader的实现源码如下:
var limit = (this.options && this.options.url && this.options.url.dataUrlLimit) || 0;
if(query.limit) {
limit = parseInt(query.limit, 10);
}
var mimetype = query.mimetype || query.minetype || mime.lookup(this.resourcePath);
if(limit <= 0 || content.length < limit) {
return "module.exports = " + JSON.stringify("data:" + (mimetype ? mimetype + ";" : "") + "base64," + content.toString("base64"));
} else {
var fileLoader = require("file-loader");
return fileLoader.call(this, content);
}
}
module.exports.raw = true;
作为url-loader的package.json的文件中,就已经有这些依赖了:
"dependencies": {
"loader-utils": "^1.0.2",
"mime": "1.3.x"
},
"peerDependencies": {
"file-loader": "*"
},
而file-loader的源码是像这样:
var publicPath = "__webpack_public_path__ + " + JSON.stringify(url);
if (config.publicPath !== false) {
// support functions as publicPath to generate them dynamically
publicPath = JSON.stringify(
typeof config.publicPath === "function"
? config.publicPath(url)
: config.publicPath + url
);
}
if (query.emitFile === undefined || query.emitFile) {
this.emitFile(outputPath, content);
}
return "**module.exports** = " + publicPath + ";";
var url = require(“file-loader!./file.png”);
// => emits file.png as file in the output directory and returns the
public url //
=> returns i. e. “/public-path/0dcbbaa701328a3c262cfd45869e351f.png”
The url loader works like the file loader, but can return a Data Url if the file is smaller than a byte limit.The limit can be specified with a query parameter. (Defaults to no limit,没有限制最好了,最大的文件也会被潜入到网页中)
If the file is greater than the limit (in bytes) the file-loader is used and all query parameters (url查询参数)are passed to it.
网页优化的一大首要任务是减少HTTP 请求 (http request) 的次数,例如通过合并多个JS文件,合并CSS样式文件。除此之外,还有一个data URL 的密技,让我们直接把图像的内容崁入网页里面,这个密技的官方名称是 data URI scheme
(哈哈,如果用url-loader的话,我的那个文件请求就能得到正确的格式)(在本地内存中加载)
不然就会报错(变成了相关的请求报错,因为其实就是本地文件而已)
This package allows transpiling JavaScript files using Babel and webpack.
babel
This package allows transpiling JavaScript files using Babel and webpack.Babel是一个广泛使用的转码器,可以将ES6代码转为ES5代码,从而在现有环境执行。你可以现在就用ES6编写程序,而不用担心现有环境是否支持
markdown-highlight-loader;
安装
$ npm i -S markdown-highlight-loader
使用npm 安装,出入的参数是i 和-S i代表可能是install -S代表的应该是save…
用法其实很简单:
/*
include highlight.js theme styles, for example in "vendor" chunk:
entry: {
vendor: [
…
‘highlight.js/styles/railscasts.css‘
],
…
}
*/
module: {
loaders: [ {
test: /\.md$/,
loader: ‘html!markdown-highlight‘
// loader: ‘html!markdown-highlight?+breaks&-smartLists‘
} ]
hightlight的作用,使得代码高亮
更加简单的,如果不需要代码高亮的,直接使用markdown就好了:
{
module: {
rules: [{
test: /\.md$/,
use: [
{
loader: "html-loader"
},
{
loader: "markdown-loader",
options: {
/* your options here */
}
}
]
}]
}
}
Webpack 还有一个功能丰富的插件系统。大多数内容功能都是基于这个插件系统运行的,还可以开发和使用开源的 Webpack 插件,来满足各式各样的需求。
插件可以完成更多loader不能完成的功能。
插件的会用一般是在webpack的配置信息plugins选项中指定。
我们利用一个最简单的 BannerPlugin 内置插件来实践插件的配置和运行,这个插件的作用是给输出的文件头部添加注释信息。
var webpack = require(‘webpack‘)
module.exports = {
entry: ‘./entry.js‘,
output: {
path: __dirname,
filename: ‘bundle.js‘
},
module: {
loaders: [
{test: /\.css$/, loader: ‘style-loader!css-loader‘}
]
},
plugins: [
new webpack.BannerPlugin(‘This file is created by zhaoda‘)
]
}
再比如第三方插件extract-text-webpack-plugin:Extract text from bundle into a file.
for webpack 2
npm install –save-dev extract-text-webpack-plugin
for webpack 1
npm install –save-dev extract-text-webpack-plugin@1.0.1
const ExtractTextPlugin = require(“extract-text-webpack-plugin”);
module.exports = {
module: {
rules: [
{
test: /.css$/,
use: ExtractTextPlugin.extract({
fallback: “style-loader”,
use: “css-loader”
})
}
]
},
plugins: [
new ExtractTextPlugin(“styles.css”),
]
}这个插件的作用是什么呢?它会将所有通过require("style.css")s
的entry块放到一个单一的css文件中去,使得你的styles不再嵌入到JS文件中,如果你的所有的css量很大,这会更快(因为css bundle是并行的导入到js bundle中去的)
module.id 模块的识别符,通常是带有绝对路径的模块文件名。
module.filename 模块的文件名,带有绝对路径。
module.loaded 返回一个布尔值,表示模块是否已经完成加载。
module.parent 返回一个对象,表示调用该模块的模块。
module.children 返回一个数组,表示该模块要用到的其他模块。
**module.exports 表示模块对外输出的值。**
export default{}
对于只导出一部分的值来说 命名导出的方式很有用。。。在导入时候,可以使用相同的名称来引用对应导出的值。<script src="1.js"></script>
<script src="2.js"></script>
–save
当你为你的模块安装一个依赖模块时,正常情况下你得先安装他们(在模块根目录下npm install
module-name),然后连同版本号手动将他们添加到模块配置文件package.json中的依赖里(dependencies)。-save和save-dev可以省掉你手动修改package.json文件的步骤。 npm install module-name -save 自动把模块和版本号添加到dependencies部分 npm install module-name -save-dev 自动把模块和版本号添加到devdependencies部分
package.json
dependencies部分:字段指定了项目运行所依赖的模块
devdependencies部分:字段指定了项目开发所依赖的模块
If someone is planning on downloading and using your module in their program, then they probably don’t want or need to download and build the external test or documentation framework that you use.In this case, it’s best to map these additional items in a devDependencies object.
如果有人想下载并使用你的模块,但是他们可能不想或者不需要下载或安装额外的文档框架。就最好使用devDependencies 这个对象。
These things will be installed when doing npm link or npm install from the root of a package, and can be managed like any other npm configuration param. See npm-config for more on the topic.
For build steps that are not platform-specific, such as compiling CoffeeScript or other languages to JavaScript, use the prepare script to do this, and make the required package a devDependency.
这写东西会在安装的时候就用npm安装到package的root下面。
这两者的区别?
npm install 在安装 npm 包时,有两种命令参数可以把它们的信息写入 package.json 文件:
–save
–save-dev
但它的文档里1,只提到一个小区别,–save 会把依赖包名称添加到 package.json 文件 dependencies 键下,–save-dev 则添加到 package.json 文件 devDependencies 键下。
。它们真正的区别是,devDependencies 下列出的模块,是我们开发时用的,比如 grunt-contrib-uglify,我们用它混淆 js 文件,它们不会被部署到生产环境。dependencies 下的模块,则是我们生产环境中需要的依赖。
dependencies配置的依赖是在正常运行(一般为生产环境)该包时必须要的依赖项
什么意思?很简单,就是假设你的包被别人依赖了,那么别人在安装你的包时会自动安装你的包里的dependencies中配置的这些依赖包,也就是说你的包没有这些包就不能正常使用。
devDependencies配置的依赖是你在开发你的包时安装的一些在生产环境非必要的依赖项。
那什么是生产环境非必要的依赖项?比如说:你想使用mocha来测试你的包,那么就可以安装mocha到devDependencies,而不是dependencies,因为他不是生产环境所必须的。依赖你的包的人,是想依赖你的核心代码,而不是需要使用你包里的mocha
Less 是一门 CSS 预处理语言,它扩充了 CSS 语言,增加了诸如变量、混合(mixin)、函数等功能,让 CSS 更易维护、方便制作主题、扩充。
stylus 是一个CSS的预处理框架,2010年产生,来自Node.js社区,主要用来给Node项目进行CSS预处理支持,所以 Stylus 是一种新型语言,可以创建健壮的、动态的、富有表现力的CSS。比较年轻,其本质上做的事情与 SASS/LESS 等类似,应该是有很多借鉴,所以近似脚本的方式去写CSS代码。Stylus默认使用 .styl 的作为文件扩展名,支持多样性的CSS语法。
全局安装:
npm install stylus -g
比如&就是一个非常灵活的用法:
ul
li a
display: block
color: blue
padding: 5px
html.ie &
padding: 6px
&:hover
color: red
编译为css:
ul li a {
display: block;
color: #00f;
padding: 5px;
}
html.ie ul li a {
padding: 6px;
}
ul li a:hover {
color: #f00;
}
下面具体一点:
就CSS本身而言,对于大多数Web前端从业人员来说就不是问题。学过CSS的人都知道,它不是一种编程语言。你可以用它开发网页样式,但是没法用它编程。换句话说,CSS基本上是设计师的工具,不是程序员的工具。在程序员的眼里,CSS是很头痛的事情,它并不像其它程序语言,比如说PHP、Javascript等等,有自己的变量、常量、条件语句以及一些编程语法,只是一行行单纯的属性描述,写起来相当的费事,而且代码难易组织和维护。
很自然的,有人就开始在想,能不能给CSS像其他程序语言一样,加入一些编程元素,让CSS能像其他程序语言一样可以做一些预定的处理。这样一来,就有了“CSS预处器(CSS
Preprocessor)”。
一、什么是CSS预处器
CSS预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为CSS增加了一些编程的特性,将CSS作为目标生成文件,然后开发者就只要使用这种语言进行编码工作。通俗的说,CSS预处理器用一种专门的编程语言,进行Web页面样式设计,然后再编译成正常的CSS文件,以供项目使用。CSS预处理器为CSS增加一些编程的特性,无需考虑浏览器的兼容性问题,例如你可以在CSS中使用变量、简单的逻辑程序、函数等等在编程语言中的一些基本特性,可以让你的CSS更加简洁、适应性更强、可读性更佳,更易于代码的维护等诸多好处。
CSS预处理器技术已经非常的成熟,而且也涌现出了很多种不同的CSS预处理器语言,比如说:Sass(SCSS)、LESS、Stylus、Turbine、Swithch CSS、CSS Cacheer、DT CSS等。如此之多的CSS预处理器,那么“我应该选择哪种CSS预处理器?”也相应成了最近网上的一大热门话题,在Linkedin、Twitter、CSS-Trick、知呼以及各大技术论坛上,很多人为此争论不休。相比过计我们对是否应该使用CSS预处理器的话题而言,这已经是很大的进步了。
到目前为止,在众多优秀的CSS预处理器语言中就属Sass、LESS和Stylus最优秀,讨论的也多,对比的也多。本文将分别从他们产生的背景、安装、使用语法、异同等几个对比之处向你介绍这三款CSS预处理器语言。相信前端开发工程师会做出自己的选择——我要选择哪款CSS预处理器。
less是2009年的一个开源项目,LESS提供了多种方式能平滑的将写好的代码转化成标准的CSS代码,在很多流行的框架和工具中已经能经常看到LESS的身影了(例如Twitter的Bootstrap框架就使用了LESS著作权归作者所有。
Stylus,2010年产生,来自于Node.js社区,主要用来给Node项目进行CSS预处理支持,在此社区之内有一定支持者,在广泛的意义上人气还完全不如Sass和LESS。
[Stylus]被称为是一种革命性的新语言,提供一个高效、动态、和使用表达方式来生成CSS,以供浏览器使用。Stylus同时支持缩进和CSS常规样式书写规则。
Sass、LESS和Stylus源文件(除了LESS源文件在客户端下运行之外)都不能直接被浏览器直接识别,这样一来,要正常的使用这些源文件,就需要将其源文件转译成浏览器可以识别的CSS样式文件,这也是使用CSS预处理器很关键的一步,如果这一步不知道如何操作,那么意味着写出来的代码不可用著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
原文: https://www.w3cplus.com/css/css-preprocessor-sass-vs-less-stylus-2.html ? w3cplus.com
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
小区插曲:
早在90年代中期到后期起草的 CSS1规范中就介绍过!important,它能够帮助开发者和用户在修改样式表的时候轻松覆盖原本的权重。著作权归作者所有。
样式的应用依赖具体的情况,一个更加具体的选择器往往会比一个笼统选择器获得更大的权重。
样式的应用依赖样式出现的顺序(即,后面的会覆盖前面的)
从这个提纲中,你可能已经明白!important会如何改变权重以及它在层叠中扮演一个什么样的角色。接下来让我们看一下!important更多的细节。
举一个例子就可以很好的说明了:
语法和描述
!important为开发者提供了一个增加样式权重的方法。应当注意的是!important是对整条样式的声明,包括这个样式的属性和属性值(感谢Brad Czerniak指出其中的差别)。这里有个简单的代码示例可以清晰地说明!important是如何应用于原本的样式中的:
#example {
font-size: 14px !important;
}
#container #example {
font-size: 10px;
}
在上面的代码示例中,由于使用了!important,id为“example”的元素字号将被设置为14px。
如果不使用!important,第二个样式声明的代码块很自然地比第一个的权重要大,原因有二:在样式表中第二个代码块要比第一个出现的晚(即,它位列第二);第二个代码块有更大的权重(是由两个id,#container #example组合而成,而不是只有一个id,#example。但是因为第一个代码块里面包含了!important,所以对于字号设置来说它有更大的权重。
体(@media)
@media工作原理和在常规CSS中一样,但是,要使用Stylus的块状符号。
@media print
#header
#footer
display none
生成为:
@media print {
#header,
#footer {
display: none;
}
}
那么在css中这个@media到底是什么呢?
width 媒体属性描述了输出设备渲染区域(如可视区域的宽度或打印机纸盒的宽度)的宽度。
jade语法:
Tags
默认,每行开始的第一个单词代表一个标签,可以是自定义的标签:
jade:
h1 h1 tag
custom custom tag
img(src=”/images/logo.png”, alt=”“)
使用缩进能进行标签嵌套:
jade:
ul
li Item A
a(href="javascript:;") a link
li Item B
li Item C
属性必须用括号包起来,多个属性用逗号分隔,class 和 id,可以直接用 (.) 和 (#) 而不需要放到括号内;
div.container.flow#container Content
a(class="btn", href="javascript:;", title="submit") Button
html:
<div id="container" class="container flow">Content</div><a href="javascript:;" title="submit" class="btn">Button</a>
对于 class 和 id, 还可以省略 tag 而直接用,最终会自动生成一个 div:
jade:
.content content
#content.content.box content
html:
<div class="content">content</div>
<div id="content" class="content box">content</div>
_.defaultsDeep({ ‘a‘: { ‘b‘: 2 } }, { ‘a‘: { ‘b‘: 1, ‘c‘: 3 } });
// => { ‘a‘: { ‘b‘: 2, ‘c‘: 3 } }
vuej指令是vue编程中非常灵活的一个因素所在。
v-if指令可以完全根据表达式的值在DOM中生成或移除一个元素。
如果v-if表达式赋值为false,那么对应的元素就会从DOM中移除;否则,对应元素的一个克隆将被重新插入DOM中
<div id="example-2">
<p v-if="greeting">Hello!</p>
</div>
<script type="text/javascript">
var exampleVM2 = new Vue({
el: ‘#example-2‘,
data: {
greeting: true
}
})
</script>
上面这种写法可能是最最正宗的写法,设定一个el ,创建一个vue对象。
v-show
v-show指令是根据表达式的值来显示或者隐藏HTML元素。当v-show赋值为false时,元素被隐藏。查看DOM时,会发现元素上多了一个内联样式style=”display:none”。
一般来说,v-if有更高的切换消耗,而v-show有更高的初始渲染消耗(可能稍微改变的开销并不大了)。因此,如果需要频繁的切换,则使用v-show较好;如果在运行时条件不大可能改变,则使用v-if较好。
input、select、text、checkbox、radio
等表单控件元素上创建双向数据绑定的。根据控件类型v-model**自动选取正确的方法更新元素**。使用$index来获得相应的数组索引。
v-text指令可以更新元素的textContent.
v-html指令更新元素的innerHTML。
v-bind指令用于响应更新HTML特性,将一个或者多个attribute,或者一个组件prop动态绑定到表达式..
a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>
在绑定prop时,prop必须在子组件中声明。可以用修饰符指定不同的绑定类型。修饰符为:
.sync——双向绑定,只能用于prop绑定。
.once——单次绑定,只能用于prop绑定
v-on指令用于绑定事件监听器。事件类型由参数指定。
如果访问原始DOM事件,可以使用$event传入方法。
```
<button v-on:click="doThis(‘hello‘,$event)"></button> <!--缩写-->
<!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
```
那么什么是单击事件冒泡呢?
在一个对象上触发某类事件(比如单击onclick事件),如果此对象定义了此事件的处理程序,那么此事件就会调用这个处理程序,如果没有定义此事件处理程序或者事件返回true,那么这个事件会向这个对象的父级对象传播,从里到外,直至它被处理(父级对象所有同类事件都将被激活),或者它到达了对象层次的最顶层,即document对象(有些浏览器是window)
可以用 Vue.directive(id, definition) 方法注册一个全局自定义指令,它接收两个参数指令 ID 与定义对象。也可以用组件的 directives 选项注册一个局部自定义指令,例子:
<div id="demo" v-demo:hello.a.b="msg"></div>
Vue.directive(‘demo‘, {
bind: function () {
console.log(‘demo bound!‘)
},
update: function (value) {,
this.el.innerHTML =
‘name - ‘ + this.name + ‘<br>‘ +
‘expression - ‘ + this.expression + ‘<br>‘ +
‘argument - ‘ + this.arg + ‘<br>‘ +
‘modifiers - ‘ + JSON.stringify(this.modifiers) + ‘<br>‘ +
‘value - ‘ + value
}
})
var demo = new Vue({
el: ‘#demo‘,
data: {
msg: ‘hello!‘
}
})
这下可以回到我在此文开头的时候抛出来的问题了:
一个项目里面使用到一个灵活的jsoneditor,通过调研发现vuejs并没有直接的组件可以用,但是发现javascript有一个很好用的叫做jsoneditor的组件,那么我们如何在一个vue.js的工程里面加入这个jsoneditor?
虽然我首先调研得到的可用的组件是vue-json-tree-view,用法
npm install --save vue-json-tree-view
import TreeView from "vue-json-tree-view"
Vue.use(TreeView)
但是这个组件的功能还是不够完善。
顺便提一句:
Vue.use(plugin)用于安装vuejs的插件,use是Vue提供的一个全局的api,另外类似的api还有set,directive,filter等。
set:
参数:
{Object} object
{string} key
{any} value
返回值: 设置的值.
用法:
设置对象的属性。如果对象是响应式的,确保属性被创建后也是响应式的,同时触发视图更新。这个方法主要用于避开 Vue 不能检测属性被添加的限制。
注意对象不能是 Vue 实例,或者 Vue 实例的根数据对象
这是和vue的相应式原理对应的一个api。
受现代 JavaScript 的限制(以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。
Vue 不允许在已经创建的实例上动态
Vue.set(vm.someObject, ‘b’, 2)
您还可以使用 vm.
有时你想向已有对象上添加一些属性,例如使用 Object.assign() 或 _.extend() 方法来添加属性。但是,添加到对象上的新属性不会触发更新。在这种情况下可以创建一个新的对象,让它包含原对象的属性和新的属性:
// 代替 Object.assign(this.someObject, { a: 1, b: 2 })
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
- Vue 异步执行 DOM 更新
/**
* A watcher parses an expression, collects dependencies,
* and fires callback when the expression value changes.
* This is used for both the $watch() api and directives.
*
* @param {Vue} vm
* @param {String|Function} expOrFn
* @param {Function} cb
* @param {Object} options
* - {Array} filters
* - {Boolean} twoWay
* - {Boolean} deep
* - {Boolean} user
* - {Boolean} sync
* - {Boolean} lazy
* - {Function} [preProcess]
* - {Function} [postProcess]
* @constructor
*/
watcher是用来调动callback函数的(当检测到监测的表达式的值发生变化的时候),可以选择的监控的options参数有:
twoWay
deep
lazy等
就同前面那样描述到的,这个对于$watch() 和指令来说,同样是生效的。
响应式原理就是因为指令和数据有绑定watcher对象。把一个普通的js对象传给Vue实例的data,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter.用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的
.
当只需要 update 函数时,可以传入一个函数替代定义对象:
Vue.directive(‘my-directive‘, function (value) {
// 这个函数用作 update()
})
在github上面有jsoneditor的使用方法:
var container = document.getElementById("jsoneditor");
var options = {};
var editor = new JSONEditor(container, options);
// set json
var json = {
"Array": [1, 2, 3],
"Boolean": true,
"Null": null,
"Number": 123,
"Object": {"a": "b", "c": "d"},
"String": "Hello World"
};
editor.set(json);
但是当我在vue.js中想要引入jsoneditor却很为难。就像vue.js是数据响应式那样,vue.js并没有操作dom的能力。所以要怎么办呢?
使用自定义指令可以。它有操作dom的能力!可以使用this.el来表示上面html中的container。
import Vue from ‘vue‘
import JSONEditor from "jsoneditor"
export default {
update: function(value){
console.log("arg:",this.arg)
var options ={mode: this.arg ,search:true}
var editor = new JSONEditor(**this.el**, options);
editor.set(value.data);
}
}
这样创建的指令jsoneditor就可以被用于vue的元素中,比如div(v-jsoneditor)。
这样,基本功能就完成了
editor.set(json);
editor.expandAll();
还有collapse等用法。
schema
遇到了一个问题,我觉得可能需要深入了解下dom的事件:
比如input click
Ajv: Another JSON Schema Validator
The fastest JSON Schema validator for node.js and browser.
那么怎么利用ajv编程呢?
比如:
支持type参数,properties参数等。
var schema = {
"title": "Example Schema",
// "type": "obje",
"properties": {
"type": { "enum": value.schema },
"动作": {"enum": value.schema2 },
‘opAction‘: {"enum":value.ops},
// ‘constraints‘:{
// ‘动作‘: {"enum":value.ops},
// }
},
type keyword requires that the data is of certain type (or some of types). Its value can be a string (the allowed type) or an array of strings (multiple allowed types).
也就是说type可以写一个,也可以写一组。
Type can be: number, integer, string, boolean, array, object or null.
schema: { "type": ["number", "string"] }
valid: 1, 1.5, "abc", "1"
invalid: [], {}, null, true
All examples above are JSON schemas that only require data to be of certain type to be valid.
而嵌套的:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "TextLinks",
"description": "文字链接",
"type": "array",
"items": {
"type": "object",
"properties": {
"text": {
"type": "string",
"title": "文字"
},
"href": {
"type": "string",
"title": "链接地址(URL)"
}
}
}
}
所以其实也没有那么难的。
一个从css的优先级入手
另一方面从semantic ui的css定义入手。。
<td> 标签定义 HTML 表格中的标准单元格。
HTML 表格有两类单元格:
表头单元 - 包含头部信息(由 th 元素创建)
标准单元 - 包含数据(由 td 元素创建)
td 元素中的文本一般显示为正常字体且左对齐。
而在semantic ui中:
.ui.table td > .ui.ribbon.label {
left: calc( -0.78571429em - 1.2em );
}
.ui.table td > .ui[class*="right ribbon"].label {
left: calc(100% + 0.78571429em + 1.2em );
padding-left: 0.833em;
}
.ui.table {
width: 100%;
background: #FFFFFF;
margin: 1em 0em;
border: 1px solid rgba(34, 36, 38, 0.15);
box-shadow: none;
border-radius: 0.28571429rem;
text-align: left;
color: rgba(0, 0, 0, 0.87);
border-collapse: separate;
border-spacing: 0px;
}
另外,transition是用来做过度效果的:
<!DOCTYPE html>
<html>
<head>
<style>
div
{
width:100px;
height:100px;
background:blue;
transition:width 2s;
-moz-transition:width 2s; /* Firefox 4 */
-webkit-transition:width 2s; /* Safari and Chrome */
-o-transition:width 2s; /* Opera */
}
div:hover
{
width:300px;
}
</style>
</head>
<body>
<div></div>
<p>请把鼠标指针移动到蓝色的 div 元素上,就可以看到过渡效果。</p>
<p><b>注释:</b>本例在 Internet Explorer 中无效。</p>
</body>
</html>
然后:
关于head的一些属性
/* Table Content */
.ui.table th,
.ui.table td {
-webkit-transition: background 0.1s ease, color 0.1s ease;
transition: background 0.1s ease, color 0.1s ease;
}
/* Headers */
.ui.table thead {
box-shadow: none;
}
.ui.table thead th {
cursor: auto;
background: #F9FAFB;
text-align: inherit;
color: rgba(0, 0, 0, 0.87);
padding: 0.92857143em 0.78571429em;
vertical-align: inherit;
font-style: none;
font-weight: bold;
text-transform: none;
border-bottom: 1px solid rgba(34, 36, 38, 0.1);
border-left: none;
}
.ui.table thead tr > th:first-child {
border-left: none;
}
.ui.table thead tr:first-child > th:first-child {
border-radius: 0.28571429rem 0em 0em 0em;
}
.ui.table thead tr:first-child > th:last-child {
border-radius: 0em 0.28571429rem 0em 0em;
}
.ui.table thead tr:first-child > th:only-child {
border-radius: 0.28571429rem 0.28571429rem 0em 0em;
}
那么关于body的以一些属性呢:
/* Table Row */
.ui.table tr td {
border-top: 1px solid rgba(34, 36, 38, 0.1);
}
.ui.table tr:first-child td {
border-top: none;
}
/* Table Cells */
.ui.table td {
padding: 0.78571429em 0.78571429em;
text-align: inherit;
}
padding表示元素的内边距,感觉这个padding的值还比较重要,,
另外还需要关注的一个值是:
margin用于设置外边框:
<html>
<head>
<style type="text/css">
p.margin {margin: 2cm 4cm 3cm 4cm}
</style>
</head>
<body>
<p>这个段落没有指定外边距。</p>
<p class="margin">这个段落带有指定的外边距。这个段落带有指定的外边距。这个段落带有指定的外边距。这个段落带有指定的外边距。这个段落带有指定的外边距。</p>
<p>这个段落没有指定外边距。</p>
</body>
</html>
semantic ui的 .filed是设置了下边框的。
.ui.form .field {
clear: both;
margin: 0em 0em 1em;
}
.ui.form .field > label {
display: block;
margin: 0em 0em 0.28571429rem 0em;
color: rgba(0, 0, 0, 0.87);
font-size: 0.92857143em;
font-weight: bold;
text-transform: none;
}
所以也会导致有一些不正常的地方在下边框的地方。
这个问题可以慢慢解决。
先总结一个关于css优先级的汇总:
重样式(Multiple Styles):如果外部样式、内部样式和内联样式同时应用于同一个元素,就是使多重样式的情况。
一般情况下,优先级如下:
(外部样式)External style sheet <(内部样式)Internal style sheet <(内联样式)Inline style
解释:
1. 内联样式表的权值最高 1000;
2. ID 选择器的权值为 100
3. Class 类选择器的权值为 10
4. HTML 标签选择器的权值为 1
<html>
<head>
<style type="text/css">
#redP p {
/* 权值 = 100+1=101 */
color:#F00; /* 红色 */
}
#redP .red em {
/* 权值 = 100+10+1=111 */
color:#00F; /* 蓝色 */
}
#redP p span em {
/* 权值 = 100+1+1+1=103 */
color:#FF0;/*黄色*/
}
</style>
</head>
<body>
<div id="redP">
<p class="red">red
<span><em>em red</em></span>
</p>
<p>red</p>
</div>
</body>
</html>
semantic UI是github上面的一个开源项目,
semantic ui的特点: 50多个UI 元素(element) 3000多个CSS变量 3 Levels of variable
inheritance(3层的变量继承?)(变量继承,这个还需要花点时间去学习) Built with EM values for
responsive design(EM值?) Flexbox friendly (灵活的布局)
比如button
field inputs这些 做出的内容确实就非常漂亮 还有icons
标签:property eid 映射 border end require children 文件名 edit
原文地址:http://blog.csdn.net/yin_wuzhe/article/details/68935816