整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Node实战篇:Express-jade模板引擎(七

Node实战篇:Express-jade模板引擎(七)

ade(Pug) — Node Template Engine,一个高性能的模板引擎,为 Node 而做,用 JavaScript 实现。

Node.js 的 Express.js 框架默认用的就是 Jade(更名为Pug)。

第一部分 背景

随着 web 发展,前端应用变得越来越复杂,基于后端的 javascript(Node.js) 也开始崭露头角,此时 javascript 被寄予了更大的期望,与此同时 javascript MVC 思想也开始流行起来。

为了使用户界面业务数据分离,就产生了『模板引擎』这个概念。模板引擎有很多, 比较有名的有jade(express默认)、ejs、hbs(ghost默认)、doT、swig等等。『模板引擎』:

1. 模板是什么?模板就是一个模子。供你套数据,并且依据不同数据去走不同的逻辑。
2. 引擎是什么?引擎就是个处理器(编译、运行),最后输出个结果(HTML代码)的东西。

第二部分 安装配置

2.1 安装:

npm install pug-cli -g
jade --helpUsage: jade [options] [dir|file ...]
 Options:
 -h, --help output usage information / 输出使用信息
 -V, --version output the version number / 输出版本号信息
 -O, --obj <str> javascript options object / 传输到 jade 文件中的数据对象
 -o, --out <dir> output the compiled html to <dir> / 输出编译后的 HTML 到 <dir>
 -p, --path <path> filename used to resolve includes / 在处理 stdio 时,查找包含文件时的查找路径
 -P, --pretty compile pretty html output / 格式化编译 html 文件
 -c, --client compile function for client-side runtime.js / 编译浏览器端可用的 runtime.js
 -n, --name <str> The name of the compiled template (requires --client) / 编译模板的名字
 -D, --no-debug compile without debugging (smaller functions) / 关闭编译的调试选项(函数会更小)
 -w, --watch watch files for changes and automatically re-render / 监听文件改变并自动刷新编译结果
 --name-after-file Name the template after the last section of the file path (requires --client and overriden by --name)
 --doctype <str> Specify the doctype on the command line (useful if it is not specified by the template) / 在命令行中指定文档类型(如果在模板中没有被指定)
 Examples: # 编译整个目录
 $ jade templates # 生成 {foo,bar}.html
 $ jade {foo,bar}.jade # 在标准IO下使用jade
 $ jade < my.jade > my.html # 在标准IO下使用jade
 $ echo 'h1 Jade!' | jade # foo, bar 目录渲染到 /tmp
 $ jade foo bar --out /tmp

2.2 实例 编写与运行

第一步: 打开sublime 创建studyJade.jade 保存到桌面上

doctype html
html
 head
 title jade
 body
 p studyjade
 div hello jade

第二步: 打开终端执行 $ jade studyJade.jade -P(大写P: 格式化编译 html 文件), 然后桌面上会出现对应的 studyJade.html文件;

<!DOCTYPE html><html>
 <head>
 <title>jade</title>
 </head>
 <body>
 <p>studyjade</p>
 <div>hello jade</div>
 </body></html>

如此反复即可达到预期效果, 但是, 如果有热跟新该多好, 面包和牛奶都会有的 !热更新

第一步: 同上第一步;

第二步: 终端$ jade index.jade -P -w, 终端会显示

$ jade /Users/51testing/Desktop/studyJade.jade -P -w
 watching /Users/51testing/Desktop/studyJade.jade
 rendered /Users/51testing/Desktop/studyJade.html

第三步: 将桌面上的两个文件(.html/.jade)拖进sublime, 使用快捷键option+command+2双屏幕展示,一侧更改并<common+s保存>,另一侧就可看到及时效果, 因为jade语法对于空格非常敏感.

第三部分 语法及使用

3.1 语法

(1)标签、属性、注释

(2)读取数据的值(转义、非转义)

3.2 逻辑

(1)条件语句(if、unless、case)

(2)循环(each、for)

(3) 过滤器

 :sass 需要安装 sass.js
 :less 需要安装 less.js
 :markdown 需要安装 markdown-js 或 node-discount
 :cdata
 :coffeescript 需要安装 coffee-script

3.3 继承和包含

(1)模板继承

(2)包含

在父模板中,用关键字“block”定义可在子模板中替换的块,每个“block”有一个名字,在子模板中,同样用关键字“block”跟上该名字定义需在该“block”中填充的内容。

Jade支持多重继承,即子模板也可以是其它模板的父模板。

3.4 jade 官网给的实例

API

var jade=require('jade'); 
// compile 编译var fn=jade.compile('string of jade', options);var html=fn(locals); 
// render 渲染var html=jade.render('string of jade', merge(options, locals)); 
// renderFile 渲染文件
var html=jade.renderFile('filename.jade', merge(options, locals));

关注我们

如果需要源码可以关注“IT实战联盟”并留言(源码名称+邮箱),小萌看到后会联系作者发送到邮箱,也可以加入交流群和作者互撩哦~~~!

CSDN现场报道】2015年11月19-21日,由CSDN重磅打造的“2015 中国软件开发者大会”(以下简称SDCC 2015)在北京朗丽兹西山花园酒店隆重召开。今年是第七届,大会为期三天,除了阵容强大的全体大会外,主办方还精心筹备了九大技术专场论坛,包括:架构实践论坛、前端开发论坛、数据库实战论坛、研发管理论坛、安全技术论坛、算法实战论坛、编程语言论坛、产品与设计论坛、微信开发论坛。此外,还有五场特色活动及展览展示。

图:前端开发论坛现场座无虚席

SDCC2015第二天前端开发论坛,在w3ctech发起人周裕波的主持人下正式开始。他表示几年前,前端开发还不温不火,而近两年却成了火爆技术。该论坛将围绕前端开发框架、前端工程化、Web组件化、数据可视化这几大热点展开,邀请来自Facebook、百度、腾讯、美团、Strikingly等公司的前端专家进行分享。

w3ctech发起人周裕波

Facebook前端工程师ShihChi Huang(黄士旗):Why React matters/scale

Facebook前端工程师ShihChi Huang(黄士旗)

Facebook前端工程师ShihChi Huang(黄士旗)在主题演讲《Why React matters/scale》中分享了React核心技术要点。“Learn Once Write Anywhere”是React的核心思想,JavaScript、UI是它的两个重要特性。Do One Thing and Do It Well、Write Programs to Work Together、Handle Text Streams等技术特性是其吸引大量开发者使用的重要原因 。

Strikingly.com CTO、联合创始人郭达峰:React.js in Strikingly

Strikingly.com CTO、联合创始人郭达峰

Strikingly.com CTO、联合创始人郭达峰在主题演讲中从第三方库整合、Lazy Load Component、Container Component、Global State Object四个方面,分享了Strikingly在React上的开发实践经验、技巧。他直接现场编码演示了jQuery sortable使用React进行封装的过程,并表示大家可以放心地在React里使用第三方库。

Lazy Loading Component可很好改善Bundle 大小,可以使用Webpack的Code Splitting、动态请求Lazy Load笨重组件、使用bundle-loader发送单独请求,该技术在SPA应用开发中很有用。Container Component可以赋予子对象行为(Bahavioural Container)、布局(UI Layout Container)或数据(Data Container);针对Global State Object,郭达峰表示所有状态存在于一个Global State Object中,Flux store仅仅是该对象不同部分的视图,所有的改变都可以应用于同一个对象上,使App状态序列化成为可能,调试更容易。据悉,Strikingly是国内使用React重写的最大应用之一。

美团技术终端组高级工程师吕伟:前端分布式编译系统的设计

美团技术终端组高级工程师吕伟

美团技术终端组高级工程师吕伟在主题演讲中介绍了前端分布式编译系统的设计原理,他表示该系统最终目的是取代Webpack和Browserify,即使单机编译也能利用多核加快编译速度,它将用于美团的CI系统和上线系统。其将在正式投产后完全开源。

饿了么资深前端架构师兼大前端团队负责人林建锋:ELE.ME是如何运行的

饿了么资深前端架构师兼大前端团队负责人林建锋

饿了么资深前端架构师兼大前端团队负责人林建锋在主题演讲中基于饿了么的开发方式、开发与发布过程,讲解了ELE.ME是如何运行的。在开发方式上,他表示专业的人应该做专业的事,前后端应做到真正分离,后端应更专注数据的存储、缓存且一次输出,而前端应该侧重于展现、多客户端处理、数据自由。

在开发与发布上,更希望使用一个命令行搞定工作环境的搭建,饿了么使用“$ make dev”来实现这一点。JS框架选用的是Vanilla JS和Angular JS,使用Babel/browserfy进行编译。在HTML领域,采用Jade,CSS方面则使用CSSNext/Sass。下图显示了饿了么的开发与发布方式。

百度EFE团队资深工程师、百度ECharts产品工程师乔刚:前端数据可视化实践

百度EFE团队资深工程师,百度ECharts产品工程师乔刚

百度EFE团队资深工程师,百度ECharts产品工程师乔刚在《前端数据可视化实践》的主题演讲中,分享了如何将数据转为可视化元素向人展示。他表示数据分析之前,将其进行可视化展示十分重要,否则数据分析易产生错误。

数据类别千差万别,需要对他们进行可视编码,即将数据映射为标记(图行元素)和视觉通道。视觉通道是一个很重要概念,它将数据转化成人类可以理解的、相对应的数据,如颜色、亮度、饱和度、透明度、色调、尺寸等。他强调应避免将重要的信息放在形状上。

交互也是数据可视化的重要部分,应遵循的可视化设计原则有总览为先;缩放过滤;按需查看细节。在一般开发过程中应避免复杂动画,而在数据可视化,动画可以带来便利,它可以表达 数据/图形元素在变化中的联系,助于理解。最后,先分享了百度所做的各种数据可视化案例,包括点数据、线数据、场●向量、时间数据高维数据等。

百姓网资深前端工程师贺师俊:如何制定和实施ES6+代码风格和质量标准

百姓网资深前端工程师贺师俊

针对大家都认为重要的Coding Style,百姓网资深前端工程师贺师俊表示它其实并没那么重要。代码逻辑、模块划分、架构设计等等都较Coding Style更重要。但本演讲还要向大家强调一下Coding Style,其原因是,随着个人作坊转向团队协作、一次性项目更需长期演化、持续维护,如果没有好的编码意识和习惯,将会使开发过程越来越痛苦。

ES6的发布将带来Coding Style的巨大升级。他推荐了一些可使用工具,如果jslint、jshint、jsdc、eslint, 并重点讲解了ESLint,它添加了很ES6编码规则,具有可插拔架构、高度可配置、预置大量规则、可共享复用等特点。他以airbnb代码风格为例介绍了ESLint的这些特点。

腾讯互联网增值业务前端团队负责人钟鹏飞:Hybrid模式的深度融合——腾讯手机QQ H5优化与监控自动化建设

腾讯互联网增值业务前端团队负责人钟鹏飞

腾讯互联网增值业务前端团队负责人钟鹏飞在《Hybrid模式的深度融合-腾讯手机QQ H5优化与监控自动化建设》主题演讲中分享了Hybird模式下的测速监控体系、Hybird模式下的站点性能优化、前端持续集成与监控自动化三部分。

Hybird模式下的站点性能优化,除了相对常规的优化措施外,他还分享了四大核心优化方案,包括Webview并行初始化,Webview预创建,分散I/O、离线包管理优化,Webview和页面并行加载。前端持续集成与监控自动化方面,介绍上QT4A自动化测试平台的工作方式,并分享了手机QQ 监控自动化建设概念图,及更具体的持续集成和监控自动化体系架构图。

更多精彩内容,请关注新浪微博:@CSDN、图文直播专题:2015中国软件开发者大会。

于公司的前端开始转向 Vue.JS,最近开始使用这个框架进行开发,遇到一些问题记录下来,以备后用。 主要写一些 官方手册 上没有写,但是实际开发中会遇到的问题,需要一定知识基础。

涉及技术栈

  • CLI: Vue-CLI
  • UI: Element
  • HTML: Pug(Jade)
  • CSS: Less
  • JavaScript: ES6

polyfill 与 transform-runtime

首先,vue-cli 为我们自动添加了 babel-plugin-transform-runtime 这个插件,该插件多数情况下都运作正常,可以转换大部分ES6语法。 但是,存在如下两个问题:

1、异步加载组件时,会产生 polyfill 代码冗余 2、不支持对全局函数与实例方法的polyfill 两个问题的原因均归因于 babel-plugin-transform-runtime 采用了沙箱机制来编译我们的代码(即:不修改宿主环境的内置对象)。

由于异步组件最终会被编译为一个单独的文件,所以即使多个组件中使用了同一个新特性(例如:Object.keys()),那么在每个编译后的文件中都会有一份该新特性的 polyfill 拷贝。如果项目较小可以考虑不使用异步加载,但是首屏的压力会比较大。 不支持全局函数(如:Promise、Set、Map),Set 跟 Map 这两种数据结构应该大家用的也不多,影响较小。但是 Promise 影响可能就比较大了。 不支持实例方法(如:'abc'.include('b')、['1', '2', '3'].find((n)=> n < 2) 等等),这个限制几乎废掉了大部分字符串和一半左右数组的新特性。

一般情况下 babel-plugin-transform-runtime 能满足大部分的需求,当不满足需求时,推荐使用完整的 babel-polyfill。

替换 babel-polyfill 首先,从项目中移除 babel-plugin-transform-runtime 卸载该依赖:

npm un babel-plugin-transform-runtime -D

修改 babel 配置文件

// .babelrc
{
 //...
 "plugins": [
 // - "transform-runtime"
 ]
 //...
}

然后,安装 babel-polyfill 依赖:

npm i babel-polyfill -D

最后,在入口文件中导入

// src/main.js
import 'babel-polyfill'

ES6 import 引用问题

在 ES6 中,模块系统的导入与导出采用的是引用导出与导入(非简单数据类型),也就是说,如果在一个模块中定义了一个对象并导出,在其他模块中导入使用时,导入的其实是一个变量引用(指针),如果修改了对象中的属性,会影响到其他模块的使用。 通常情况下,系统体量不大时,我们可以使用 JSON.parse(JSON.stringify(str)) 简单粗暴地来生成一个全新的深度拷贝的 数据对象。不过当组件较多、数据对象复用程度较高时,很明显会产生性能问题,这时我们可以考虑使用 Immutable.js。

鉴于这个原因,进行复杂数据类型的导出时,需要注意多个组件导入同一个数据对象时修改数据后可能产生的问题。 此外,模块定义变量或函数时即便使用 let 而不是 const,在导入使用时都会变成只读,不能重新赋值,效果等同于用 const 声明。

在 Vue 中使用 Pug 与 Less

安装依赖

Vue 中使用 vue-loader 根据 lang 属性自动判断所需要的 loader,所以不用额外配置 Loader,但是需要手动安装相关依赖:

npm i pug -D
npm i less-loader -D

还是相当方便的,不用手动修改 webpack 的配置文件添加 loader 就可以使用了

使用 pug 还是 pug-loader?sass 两种语法的 loader 如何设置? --- 请参考 预处理器 · vue-loader

使用

<!-- xxx.vue -->
<style lang="less">
 .action {
 color: #ddd;
 ul {
 overflow: hidden;//前端全栈开发交流圈:866109386
 li { //针对1-5年前端开发人员 
 float: left; //突破技术,提升思维。欢迎大家进入。
 }
 }
 }
</style>
<template lang="pug">
 .action(v-if='hasRight')
 ul
 li 编辑
 li 删除
</template>
<script>
 export default {
 data () {
 return {
 hasRight: true
 }
 }
 }
</script>

定义全局函数或变量

许多时候我们需要定义一些全局函数或变量,来处理一些频繁的操作(这里拿 AJAX 的异常处理举例说明)。但是在 Vue 中,每一个单文件组件都有一个独立的上下文(this)。通常在异常处理中,需要在视图上有所体现,这个时候我们就需要访问 this 对象,但是全局函数的上下文通常是 window,这时候就需要一些特殊处理了。

简单粗暴型

最简单的方法就是直接在 window 对象上定义一个全局方法,在组件内使用的时候用 bind、call 或 apply 来改变上下文。 定义一个全局异常处理方法:

// errHandler.js
window.errHandler=function () { // 不能使用箭头函数
 if (err.code && err.code !==200) {
 this.$store.commit('err', true)
 } else {
 // ...
 }
}

在入口文件中导入:

// src/main.js
import 'errHandler.js'
  在组件中使用:
// xxx.vue
export default {
 created () {
 this.errHandler=window.errHandler.bind(this)
 },
 method: {
 getXXX () {
 this.$http.get('xxx/xx').then(({ body: result })=> {
 if (result.code===200) {
 // ...
 } else {
 this.errHandler(result)
 }
 }).catch(this.errHandler)
 }
 }
}

优雅安全型

在大型多人协作的项目中,污染 window 对象还是不太妥当的。特别是一些比较有个人特色的全局方法(可能在你写的组件中几乎处处用到,但是对于其他人来说可能并不需要)。这时候推荐写一个模块,更优雅安全,也比较自然,唯一不足之处就是每个需要使用该函数或方法的组件都需要进行导入。 使用方法与前一种大同小异,就不多作介绍了。 ̄

自定义路径别名

可能有些人注意到了,在 vue-cli 生成的模板中在导入组件时使用了这样的语法:

import Index from '@/components/Index'

这个 @ 是什么东西?后来改配置文件的时候发现这个是 webpack 的配置选项之一:路径别名。 我们也可以在基础配置文件中添加自己的路径别名,比如下面这个就把 ~ 设置为路径 src/components 的别名:

// build/webpack.base.js
{
 resolve: {
 extensions: ['.js', '.vue', '.json'],
 alias: {
 'vue$': 'vue/dist/vue.esm.js',
 '@': resolve('src'),
 '~': resolve('src/components')
 }
 }
}

然后我们导入组件的时候就可以这样写:

// import YourComponent from 'YourComponent'
// import YourComponent from './YourComponent'
// import YourComponent from '../YourComponent'
// import YourComponent from '/src/components/YourComponent'
import YourComponent from '~/YourComponent'

既解决了路径过长的麻烦,又解决了相对路径的烦恼,方便很多吧!

CSS 作用域与模块

组件内样式

通常,组件中 标签里的样式是全局的,在使用第三方 UI 库(如:Element)时,全局样式很可能影响 UI 库的样式。我们可以通过添加 scoped 属性来使 style 中的样式只作用于当前组件:

<style lang="less" scoped>
 @import 'other.less';
 .title {
 font-size: 1.2rem;
 }
</style>

在有 scoped 属性的 style 标签内导入其他样式,同样会受限于作用域,变为组件内样式。复用程度较高的样式不建议这样使用。 另,在组件内样式中应避免使用元素选择器,原因在于元素选择器与属性选择器组合时,性能会大大降低。 --- 两种组合选择器的测试:classes selector,elements selector

导入样式

相对于 style 使用 scoped 属性时的组件内样式,有时候我们也需要添加一些全局样式。当然我们可以用没有 scoped 属性的 style 来写全局样式。但是相比较,更推荐下面这种写法:

/* 单独的全局样式文件 */
/* style-global.less */
body {
 font-size: 10px;
}
.title {
 font-size: 1.4rem;
 font-weight: bolder;
}

然后在入口文件中导入全局样式:

// src/main.js
import 'style-global.less'

获取表单控件值

通常我们可以直接使用 v-model 将表单控件与数据进行绑定,但是有时候我们也会需要在用户输入的时候获取当前值(比如:实时验证当前输入控件内容的有效性)。

这时我们可以使用 @input 或 @change 事件绑定我们自己的处理函数,并传入 $event 对象以获取当前控件的输入值:

<input type='text' @change='change($event)'>
change (e) {
 let curVal=e.target.value
 if (/^\d+$/.test(curVal)) {
 this.num=+curVal
 } else {
 console.error('%s is not a number!', curVal)
 }
}

当然,如果 UI 框架采用 Element 会更简单,它的事件回调会直接传入当前值。

v-for 的使用 tips

v-for 指令很强大,它不仅可以用来遍历数组、对象,甚至可以遍历一个数字或字符串。

基本语法就不讲了,这里讲个小 tips:

索引值

在使用 v-for 根据对象或数组生成 DOM 时,有时候需要知道当前的索引。我们可以这样:

<ul>
 <li v-for='(item, key) in items' :key='key'> {{ key }} - {{ item }}
</ul>

但是,在遍历数字的时候需要注意,数字的 value 是从 1 开始,而 key 是从 0 开始:

<ul>
 <li v-for='(v, k) in 3' :key='k'> {{ k }}-{{ v }} 
 <!-- output to be 0-1, 1-2, 2-3 -->
</ul>

2.2.0+ 的版本里,当在组件中使用 v-for 时,key 现在是必须的。

模板的唯一根节点

与 JSX 相同,组件中的模板只能有一个根节点,即下面这种写法是 错误 的:

<template>
 <h1>Title</h1>
 <article>Balabala...</article>
</template>

我们需要用一个块级元素把他包裹起来:

<template>
 <div>
 <h1>Title</h1>
 <article>Balabala...</article>
 </div>
</template>

项目路径配置

由于 vue-cli 配置的项目提供了一个内置的静态服务器,在开发阶段基本不会有什么问题。但是,当我们把代码放到服务器上时,经常会遇到静态资源引用错误,导致界面一片空白的问题。

这是由于 vue-cli 默认配置的 webpack 是以站点根目录引用的文件,然而有时候我们可能需要把项目部署到子目录中。

我们可以通过 config/index.js 来修改文件引用的相对路径:

 build.assetsSubDirectory: 'static'
 build.assetsPublicPath: '/'
 dev.assetsSubDirectory: 'static'
 dev.assetsPublicPath: '/'

我们可以看到导出对象中 build 与 dev 均有 assetsSubDirectory、assetsPublicPath 这两个属性。

其中 assetsSubDirectory 指静态资源文件夹,也就是打包后的 js、css、图片等文件所放置的文件夹,这个默认一般不会有问题。

assetsPublicPath 指静态资源的引用路径,默认配置为 /,即网站根目录,与 assetsSubDirectory 组合起来就是完整的静态资源引用路径 /static。

写到这里解决方法已经很明显了,只要把根目录改为相对目录就好了:

 build.assetsSubDirectory: 'static'
 build.assetsPublicPath: './'

没错!就是一个 . 的问题。

出处:https://blog.csdn.net/q3254421/article/details/83273410