安装

  • Xcode
  • Safari Technology Preview

步骤

  1. 打开iOS模拟器:Xcode/Open Developer Tool/Simulator
  2. 把下载的app安装包拖拽到模拟器中,随后app就安装成功了
  3. 打开Safari Technology Preview,找到Develope/Simulator,点进去就可以显示对应的开发者工具
  4. 卸载app,跟平时手机上卸载时一样的,鼠标长按可以卸载了

到此为止,我们就可以在开发者工具里,观察调试我们开发的h5页面了,是不是很简单,而不用去通过Fiddler或者Charles这样的工具。

首先下载vue2的模板:vue-webpack-boilerplate

快速起步

cnpm install -g vue-cli
vue init webpack my-project
cd my-project
cnpm install 
npm run dev

到这里,我们就已经拿到了一个完整的vue项目文件了,包含了构建工具webpack,还有测试的框架,在此基础上,做相关的开发。

由于要用到scss去编译css文件,所以我们需要安装依赖包

cnpm install node-sass sass-loader

需要在build/webpack.base.conf.js找到module.rules对象,添加额外的配置,如下:

{
    test: /\.scss$/,
    include: [resolve('src'), resolve('test')],
    exclude: [/node_modules\/(?!(ng2-.+|ngx-.+))/],
    use: ExtractTextPlugin.extract({
        use: ['css-loader', 'sass-loader'],
        fallback: 'style-loader'
    })
}

创建一个 Vue 的根实例

// index.html
<div id="app">
  <router-view></router-view>
</div>
// main.js
import Vue from 'vue'
import router from './router'
new Vue({
  el: '#app',
  router
})

全局注册过滤器

import filters from './filters';
Object.keys(filters).forEach(k => Vue.filter(k, filters[k]));

全局注册路由器

// router.js
import Vue from 'vue'
import Router from 'vue-router'
import Index from '../views/index';
Vue.use(Router)
export default new Router({
  routes: [
    {
      path: '/',
      name: 'Index',
      component: Index
    }
  ]
})

保留上一页的状态

运用sessionStorage临时存储数据,结合route的进出回调方法传递的参数做出判断,并及时地维护sessionStorage里的存放的数据和滚动的距离。

mounted() {
    // 如果sessionStorage有存储数据,则直接渲染之前的数据
    if (window.sessionStorage.topics) {
        this.topics = JSON.parse(window.sessionStorage.topics);
        this.$nextTick(() => $(window).scrollTop(window.sessionStorage.scrollTop));
    } else {
        // load data
    }
},
beforeRouteLeave(to, from, next) {
    // 保留上一页的状态
    if (to.name === 'topic') {
        // 当前页的数据
        window.sessionStorage.topics = JSON.stringify(this.topics);
        // 当前滚动条位置
        window.sessionStorage.scrollTop = $(window).scrollTop();
    }
    next();
},
beforeRouteEnter(to, from, next) {
    if (from.name !== 'topic') {
        // 如果不是返回目标页面,就移除之前记录的数据集
        window.sessionStorage.removeItem('topics');
        window.sessionStorage.removeItem('scrollTop');
    }
    next();
}

// 无限加载

The animation-fill-mode property defines what values are applied by the animation outside the time it is executing.

动画有是三个状态,动画等待(animation-delay)、动画进行、动画结束。为了能够定义动画等待、动画结束时该呈现什么样式,包括默认样式、初始样式0%|from、结束样式100%|to。所以引入了animation-fill-mode:none | forwards | backwards | both

采用遍历表单输入框的方式由上向下逐个校验,而不是先得到每个文本框的jQuery对象,再去单个进行检验,这样多了命名,以及后续维护的难度。

var title = {
  name: "姓名",
  mobile: "联系电话",
  email: "联系邮箱",
  code: "验证码"
};
$(".submit").on("click", function() {
  if (verifyForm()) {
    // ...
    $(this).attr({ "disabled": "disabled" });
  }
});
// 表单验证
function verifyForm() {
  var result = 1;
  // 遍历文本输入框校验输入是否为空、格式是否正确
  $("input").each(function(index, ele) {
    var val = ele.value.trim(),
      name = ele.name;
    if (!val) {
      alert(title[name] + "不能为空");
      result = 0;
    } else {
      if (ele.name == "mobile") {
        if (!(/^1[34578]\d{9}$/.test(val)) || !/^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}$/.test(val)) {
          alert("联系电话有误,请重填");
          result = 0;
        }
      }
      if (ele.name == "email") {
        if (!(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/.test(val))) {
          alert("邮箱格式有误,请重填");
          result = 0;
        }
      }
    }
  })
  return result;
};

微信静默授权的条件:关注公众号、已做过授权

公司项目:云学堂合作人

问题:

首先我们在公众号管理员的后台菜单栏里,绑定一个授权引导页,如果其中的回调地址中带有angular路由中的#,页面将不会实现重定向,一直停留在授权引导页。但是这个带有#的授权引导页,如果在公众号以外的地方,就不会出现静默授权,带#的回调地址是可以实现重定向的。

方法:

想办法去掉回调地址里的#。由于我们用的angular的框架,#是用来区分路径是由angular还是webserver来管理。 为了实现#不出现回调地址里,又能实现页面的重定向。最终的解决方案是:与后台运维人员的沟通,通过配置ngix服务,实现在用户访问h5.partner.yxt.com/my会自动请求h5.partner.yxt.com/#/my。这样在回调地址中就不会出现#,也能访问到由angular管理的路由。

参考资料:http://blog.fens.me/angularjs-url/

微信页面的缓存

由于缓存的问题,导致每次的版本更新,用户看到的还是旧的程序,只有清理手机缓存,这是件很糟糕的事,我们希望用户访问的永远是即时最新的程序。

通过对他们的路径加带有带有版本号的后缀,如?v=1001,实现浏览器重新去请求。其中css和js的版本更新很简单,但是html,这个不太一样,我们都知道angular是单页应用,它管理的视图,都是异步加载的分部视图。所以我们需要到路由管理的route.js里去控制,在每个templateUrl的参数里加上带有版本好的后缀。

// index.html
<html data-ver='1001'>
// common.js
var  APP_VERSION = angular.element(document.getElementByTagName(‘html’).attr(‘data-ver’)
// route.js
.state("signIn", {
  url: "/signIn",
  views: {
    "main": {
      templateUrl: "./views/user/signIn.html?v=" + APP_VERSION,
      controller: "UserSignInCtrl"
    }
  }
})

网页性能

  • 减小静态资源的大小
  • 减少B/S之间的往返http请求
  • 合理的利用缓存

利用构建工具Grunt对静态资源进行合并压缩:*.min.js、*.min.css。引用的框架资源可以通过CDN,或者下载到本地,在首页引用压缩版静态资源,不需要额外地压缩合并,这样每次发布,不会去更新这样框架的资源,只需要更新业务的代码,这样可以实现项目代码的最小更新。

定义

Node.js是一个基于Chrome JavaScript运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞I/O 模型而得以轻量和高效,非常适合在分布式设备上运行的数据密集型的实时应用。

MongoDB是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

环境安装:基于Mac OS X系统

nodejs的安装非常简单,去官网下载安装文件进行安装即可,同时自带了npm(node package manager)工具。

mongodb的安装稍微有点复杂,需要用到homebrew。homebrew 简称brew,是Mac OS X上的软件包管理工具,以最简单和灵活的方式,在 Mac OS X 安装 linux 工具包。

第一次安装homebrew,打开终端,输入以下命令

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

如果以前安装过homebrew,记得更新homebrew

brew update

安装mongodb

brew install mongodb

创建数据存放目录

mkdir -p /data/db

运行mongodb

mongod

出现异常:文件夹目录拒绝访问,权限不够。

2015-12-05T10:12:49.585+0800 I STORAGE  [initandlisten] exception in initAndListen: 98 Unable to create/open lock file: /data/db/mongod.lock errno:13 Permission denied Is a mongod instance already running?, terminating
 2015-12-05T10:12:49.586+0800 I CONTROL  [initandlisten] dbexit:  rc: 100

解决方法:需要手动将文件夹的权限设置为读和写。选中文件夹data、db,快捷键command+opition+i,弹出文件夹的简介,修改其中everyone的权限为读和写。

启动mongodb后台管理

mongo

出现异常:不能连接mongodb,连接失败。

MongoDB shell version: 3.0.7
connecting to: test
2015-12-05T11:24:01.021+0800 W NETWORK  Failed to connect to 127.0.0.1:27017, reason: errno:61 Connection refused
2015-12-05T11:24:01.025+0800 E QUERY    Error: couldn't connect to server 127.0.0.1:27017 (127.0.0.1), connection attempt failed
    at connect (src/mongo/shell/mongo.js:179:14)
    at (connect):1:6 at src/mongo/shell/mongo.js:179
exception: connect failed

原因:Mac OS X系统没有自启动mongodb服务。

brew services start mongodb

国内的问答社区,解决不了问题。只能访问:来自stackoverflow的问答。缺点是:国内的访问速度有点慢,甚至打不开。

如何在windows中添加mongodb服务

mongod --dbpath "C:\data\db" --logpath "C:\data\log\MongoDB.log" --install --serviceName "MongoDB"

nodejs如何访问mongodb数据库?

首先得通过npm安装mongoose模块。

$npm install mongoose

mongoose是为nodejs而生的mongodb对象建模工具,可以定义一些Schema(定义每个doc里的字段名、类型、初始值、验证条件等),增删改查等,功能比较强大。

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var Cat = mongoose.model('Cat', {
    name: String
});
var kitty = new Cat({
    name: 'Zildjian'
});
kitty.save(function(err) {
    if (err) // ...
    console.log('meow');
});

如上面的示例,运用.save的方法,就可以将kitty的数据保存到本地test的数据表。

项目开发
后端框架
前后端交互
路由
配置文件

Grunt:JavaScript 世界的构建工具。对于需要反复重复的任务,例如压缩(minification)、编译、单元测试、linting等,自动化工具可以减轻你的劳动,简化你的工作。

运行Grunt构建工具需要依赖以下两个文件:

  • package.json
  • Gruntfile.js。
// 初始化生成package.json
npm init
// 安装grunt至package.json中的devDependencies内
npm install grunt --save-dev
// 安装需要支持的第三方grunt插件
npm install grunt-contrib-uglify grunt-contrib-concat
// 新建Gruntfile.js
touch Gruntfile.js

如果在npm install安装过程中,如果安装过程一直在等待,那就是访问国外网站不稳定的问题,可以使用国内淘宝NPM镜像!

//使用淘宝定制的 cnpm  命令行工具代替默认的 npm:
npm install -g cnpm --registry=https://registry.npm.taobao.org

常用的插件:

  • 实现监控:grunt-contrib-watch
  • 语法检查:grunt-contrib-jshint
  • 压缩:grunt-contrib-uglify
  • 合并:grunt-contrib-concat
  • 编译less:grunt-contrib-less
  • 编译jade:grunt-contrib-jade
  • 同时运行多个任务:grunt-contrib-concurrent

Gruntfile文件的组成部分:

  1. “wrapper”函数:module.exports=function(grunt){}
  2. 项目与任务配置:grunt.initConfig
  3. 加载grunt插件和任务:grunt.loadNpmTasks
  4. 自定义任务

下面我们来配置一个实时编译jade和less的Gruntfile文件,代码如下:

module.exports = function(grunt) {
  // 项目与任务配置
  grunt.initConfig({
    watch: {
      html: {
        files: ['main.jade'],
        tasks: ['jade'],
        options: {
          livereload: true
        }
      },
      css: {
        files: ['less/main.less'],
        tasks: ['less'],
        options: {
          livereload: true
        }
      },
      less:{
          files: ['less/*.less']
      }
    },
    less: {
      development: {
        options: {
          compress: false,
          optimization: 2
        },
        files: {
          'css/main.css': 'less/main.less'
        }
      }
    },
    jade: {
      development: {
        options: {
          pretty: true
        },
        files: {
          'main.html': 'main.jade'
        }
      }
    },    
    concurrent: {
      tasks: ['watch', 'jade', 'less'],
      options: {
        logConcurrentOutput: true
      }
    }
  })
  // 加载grunt插件和任务
  grunt.loadNpmTasks('grunt-contrib-watch')  
  grunt.loadNpmTasks('grunt-contrib-jade')
  grunt.loadNpmTasks('grunt-contrib-less')
  grunt.loadNpmTasks('grunt-concurrent')
  // 注册自定义的grunt任务
  grunt.registerTask('default', ['concurrent'])
}

小结:把机械化重复性的工作,交给机器去做。使用自动化工具可以减轻你的劳动,简化你的工作。

Git:是一个开源的分布式版本控制系统,用以有效、高速的处理从很小到非常大的项目版本管理。分布式相比于集中式的最大区别在于开发者可以提交到本地,每个开发者通过克隆(git clone),在本地机器上拷贝一个完整的Git仓库。

基本的Git工作流程

  1. 在工作目录中修改文件
  2. 暂存文件,将文件的快照放入暂存区域
  3. 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录

常用的指令

// 克隆现有的仓库
git clone
// 初始化仓库
git init
// 检查当前文件状态
git status
// 暂存已修改的文件
git add
// 查看已暂存和未暂存的修改
git diff
// 提交更新
git commit -m
// 跳过使用暂存区域
git commit -a -m
// 查看提交历史
git log
// 远程更新
git push

把项目搬进GitHub

首先在github官网新增一个仓库,仓库名如:xiangrenya.com。

git clone https://github.com/leon0407/xiangrenya.com.git
git init
git add .
git commit -m 'first commit'
git push

小结:遇到命令不清楚的时候,可以使用git help,查看相关帮助,一般都能解决问题。

Jade是一个高性能的模板引擎,它深受Haml影响,它是用javascript实现的,并且可以供node使用。

打开命令行工具,安装jade:

npm install  -g jade

如何编译jade文件?首先得指向当前的工作目录

jade  -P -w main.jade

-P:不压缩html,默认是-p,表示压缩html;-w:实时编译jade。

1、由于jade的直观、简约、高效,让UI布局的工作变得不再繁琐。结构逐级向内嵌套,层次分明,增强了结构的可读性,相比于html,维护jade代码变得更加容易。

.page-header
    .page-center
        a
            img.logo(src='css/images/logo.png')
        .page-search
            i.icon-search
            input.search-input(type='text')
            input.btn-search.btn-search-text(type='button',value='搜索')

2、通过extends的方法,可以建立网站模板,甚至嵌套子模板都是可以的,非常方便的管理页面。

// layout.jade 
doctype html
html
    head
        meta(charset='utf-8')
        title my title
        block styles
    body
        header
            //- do something
        block content        
        footer
            //- do something
        block scripts
// about.jade
extends ./layout.jade
block styles
    link(rel="stylesheet", href="css/main.css")
block content
    p 正文...
block scripts
    script(type='text/javascript',src='js/jquery.min.js')
    script.
        alert("hello");