• 下载
  • 说明
  • 快速上手
  • 运行示例
  • 基础用法
  • 路由
  • 页面组件间通讯
  • 组合开发
  • 醉芋头 JTaro

    An H5 SPA framework for Vue.js 2.0

    相关视频教程

    JTaro Tutorial:https://github.com/chjtx/JTaro-Tutorial

    依赖

    下载 download

    本地

    jtaro.0.6.2.js

    jtaro.0.6.2.min.js

    CDN

    <script src='https://unpkg.com/jtaro/dist/jtaro.js'></script>
    <script src='https://unpkg.com/jtaro/dist/jtaro.min.js'></script>
    

    NPM

    npm install jtaro
    

    说明 brief

    能解决什么问题

    快速上手 quick start

    1、 创建index.html文件并在head里引入Vue、JRoll

    <!-- 国外网址,访问较慢,建议下载到本地 -->
    <script src='https://unpkg.com/vue/dist/vue.js'></script>
    <script src='https://unpkg.com/jroll/src/jroll.js'></script>
    

    2、 在body里创建id为jtaro_app的div,并在其后引入JTaro

    注意:压缩版 jtaro.min.js 去除了所有开发相关代码,开发过程中请使用未经压缩的 jtaro.js

    <div id="jtaro_app"></div>
    <script src='https://unpkg.com/jtaro/src/jtaro.js'></script>
    

    3、 在div#jtaro_app之后编写Vue组件,并执行Vue.use(JTaro)启动应用

    注意:务必确保首页组件在Vue.use(JTaro)之前注册

    <script>
    Vue.component('home', {
      template: '<div id="home">Hello JTaro!</div>'
    })
    
    Vue.use(JTaro)
    </script>
    

    4、 将index.html文件拖到浏览器访问

    要了解更多请查看示例

    运行示例 run demo

    git clone https://github.com/chjtx/JTaro.git
    
    cd JTaro
    
    npm install
    
    npm run dev
    

    npm install下载太慢?那就直接clone之后将index.html拖到浏览器即可。不要用cnpm,会导致很多依赖缺失

    基础用法 basic usage

    启动 Vue.use(JTaro)

    Vue.use(JTaro)
    
    // or 传入选项参数
    Vue.use(JTaro, {
      el: '#jtaro_app',
      default: 'home',
      distance: 0.3,
      duration: 200,
      JRoll: window.JRoll
    })
    
    选项 默认值 说明
    el '#jtaro_app' 给Vue挂载的元素
    default 'home' 默认首页
    distance 0.1 页面折叠距离倍数,以屏幕宽度为1,取值范围为0 <= distance <= 1
    duration 200 页面切换过渡时间
    JRoll window.JRoll 用于异步引入JRoll,不能确保JRoll和JTaro顺序时使用

    跳转 this.go

    Vue.component('home', {
      methods: {
        goPage: function () {
          // 跳到page页
          this.go('page')
    
          // or 返回上一页
          this.go(-1)
    
          // or Url带参跳到page页
          this.go('page?a=1&b=2')
    
          // or 键值对带参跳到page页
          this.go('page', {a: 1, b: 2})
        }
      }
    })
    
    Vue.component('page', {
      afterEnter: function (params) {
        console.log(params)
      }
    })
    

    路由 route

    路由说明

    路由钩子

    beforeEnter

    进入该路由(页面滑入)之前执行

    Vue.component('home', {
      beforeEnter: function () {
        // 不!能!获取页面组件实例 `this`
        // 因为当钩子执行时,组件实例还没被创建
        return true
      }
    })
    
    // or
    Vue.component('home', {
      beforeEnter: function (cb) {
        // 不!能!获取页面组件实例 `this`
        // 因为当钩子执行时,组件实例还没被创建
        setTimeout(function () {
          cb()
        }, 3000)
      }
    })
    

    beforeEnter会阻断路由,可执行同步或异步代码,因此需要return true或者执行回调cb()继续执行后面的代码,同步使用return true,异步或需要使用页面组件实例this时请用cb()

    beforeEnter不能获取页面组件实例this,因为当勾子执行时,组件实例还没被创建,可将方法传进cb(),实例创建后会立即执行该方法

    Vue.component('home', {
      beforeEnter: function (cb) {
        console.log(this) // JTaro
        /** v0.5.x */
        // cb(function (vm) {
        //   console.log(this) // <home>组件实例`this`
        //   console.log(vm)   // <home>组件实例`this`
        // })
    
        /** v0.6.0 之后vm改为params */
        cb(function (params) {
          console.log(this) // <home>组件实例`this`
          console.log(params)   // 上一个页面使用this.go传过来的参数
        })
      }
    })
    

    afterEnter

    进入该路由(页面已滑入,不含动画过程)后执行

    Vue.component('home', {
      afterEnter: function (params) {
        // 这里获取上一个页面使用this.go携带的参数
        console.log(params)
      }
    })
    

    afterEnter 不会阻断路由执行

    beforeLeave

    离开该路由(页面滑出)之前执行

    /** v0.6.0以前的旧用法 */
    Vue.component('home', {
      beforeLeave: function (cb) {
        // setTimeout(function () {
        //   // ...
        //   cb()
        // }, 1000)
      }
    })
    
    /** v0.6.1 新用法*/
    Vue.component('home', {
      beforeLeave: function (resolve, reject) {
        if (confirm('您有数据尚未保存,确实要离开吗?')) {
          resolve()
        } else {
          reject()
        }
      }
    })
    

    beforeLeave 和 beforeEnter 一样都会阻断路由执行,因此需要return true或者执行回调cb()来继续执行后面的代码。不同的是beforeLeave能够获取到this,因而在cb()里传入function是无效的。

    v0.6.1版本改进了beforeLeave的用法,resolve 和 reject 必须执行一个。执行 resolve() 将顺利跳转到下一页面,执行 reject() 将终止跳转到下一页面并回退到当前路由。

    四个钩子执行顺序 beforeEnter -> (mounted) -> afterEnter -> beforeLeave

    注意:

    1. mounted为Vue原有生命周期钩子,首次访问页面时会执行该钩子,此后JTaro将缓存该页面,不会再执行该钩子
    2. beforeEnter、afterEnter、beforeLeave在每次路由变更都会执行

    钩子使用技巧

    全局路由钩子

    添加全局路由钩子 add

    JTaro.beforeEnter.add('hook', function () { ... })
    JTaro.afterEnter.add('hook', function () { ... })
    JTaro.beforeLeave.add('hook', function () { ... })
    

    JTaro.[globalHook].add(name, method)

    移除全局路由钩子 remove

    JTaro.beforeEnter.remove('hook')
    JTaro.afterEnter.remove('hook')
    JTaro.beforeLeave.remove('hook')
    

    手动执行全局路由钩子 run

    JTaro.beforeEnter.run()
    JTaro.afterEnter.run()
    JTaro.beforeLeave.run()
    

    注意:run方法一般不需要我们手动调用,JTaro会在适当的时候自动调用

    页面组件间通讯 communication

    /* postMessage(<msg>, <name>)
     * @param msg 消息内容
     * @param name Vue组件名称
     */
    Vue.component('about', {
      mounted: function () {
        //向home页面发送modifyTitle消息通知home页面修改标题
        this.postMessage('modifyTitle', 'home')
      }
    })
    
    Vue.component('home', {
      onMessage: function (event) {
        console.log(event) // {message: 'modifyTitle', origin: 'about'}
      }
    })
    

    注意:只有页面组件(与路由对应的组件)才可以使用postMessage和onMessage,

    Q & A

    问:为什么不提供获取页面实例的方法?例如getPageByName('home')获取home页面,然后可以在其它页面操作home页面,用this.postMessage有什么好处?

    答:为了方便维护,每处修改都有据可寻,因此建议每个页面组件只操作自身的数据,如果需要操作其它页面的数据,只需要向目标页面发送消息,让目标页面去处理。这也是页面组件通讯的必要性

    优化 该优化已转交 JTaro UI 库处理

    JTaro嵌入了微型加速点击代码,效果类似于fastclick.js,用于解决IOS8以下苹果机和旧安卓系统的点击300ms延迟问题。

    该优化只针对普通的div/span/a等非控件元素起作用,忽略AUDIO|BUTTON|VIDEO|SELECT|INPUT|TEXTAREA等多媒体或表单元素

    配合 JTaro Module 使用

    开发模式

    JTaro Module 是开发JTaro应用时用于管理模块的插件,上线时可删除

    【步骤一】安装使用

    需要 nodejs 6 以上版本,若未安装,请访问http://nodejs.cn/

    创建一个空文件夹,然后在命令行里cd到该文件夹,初始化工程,然后安装JTaro、JTaro Module、JTaro Bundle

    # 初始化
    npm init
    
    # 输入项目名称
    name: (jtaro-demo) jtaro-demo
    
    # 以下选项一路回车即可
    version: (1.0.0)
    description:
    entry point: (index.js)
    test command:
    git repository:
    keywords:
    author:
    license: (ISC)
    
    # 输入yes结束
    Is this ok? (yes) yes
    
    # 安装JTaro
    npm i -D jtaro jtaro-module jtaro-bundle
    

    【步骤二】创建index.html

    index.html

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>Hello JTaro</title>
        <script src="./node_modules/jtaro-module/src/client.js"></script>
        <script src="./node_modules/jroll/src/jroll.js"></script>
        <script src="./node_modules/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="jtaro_app"></div>
        <script src="./node_modules/jtaro/dist/jtaro.js"></script>
        <script>
            Vue.use(JTaro, {
                default: 'pages/home'
            })
        </script>
    </body>
    </html>
    

    【步骤三】创建首页home

    新建一个文件夹,名字随意,例如命名为pages,将来上线可将pages文件夹打包成一个pages.js文件

    pages文件夹与index.html同级,在pages文件夹里新建home.js、home.html

    home.js的内容就是一个Vue组件,JTaro以页面组件为单元进行开发

    home.js

    import html from './home.html' //该路径是相对于home.js的,不能忽略./,否则在rollup.js打包时会出错
    
    export default {
      template: html,
      data: function () {
        return {
          title: 'Hello JTaro'
        }
      }
    }
    

    home.html

    <style>
        this {
            padding-top: 50px;
            text-align: center;
            font-size: 42px;
        }
    </style>
    <div>
        {{title}}
    </div>
    

    【步骤四】跑起node服务

    在命令行运行

    node ./node_modules/jtaro-module/src/server.js
    

    在浏览器上运行localhost:3000/,能够看到Hello JTaro文字表示成功了

    上线模式

    JTaro Bundle 是部署JTaro应用时用于将零散的开发代码合并压缩的插件

    【步骤一】创建www/index_template.html

    在工程文件夹(即是与index.html同级)新建一个www文件夹,用于存放上线代码,在www文件夹下新建index_template.html

    注意:上线方可使用压缩版 jtaro.min.js

    www/index_template.html

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>Hello JTaro</title>
        <script src="./node_modules/jroll/build/jroll.min.js"></script>
        <script src="./node_modules/vue/dist/vue.min.js"></script>
    </head>
    <body>
        <div id="jtaro_app"></div>
        <script src="./node_modules/jtaro/dist/jtaro.min.js"></script>
        <script src="./pages.js"></script>
        <script>
            Vue.use(JTaro, {
                default: 'pages/home'
            })
        </script>
    </body>
    </html>
    

    这个要上线的index.html(根据index_template.html自动生成)与开发的index.html区别在于

    【步骤二】打包

    在工程文件夹新建一个build.js

    build.js

    var jtaroBundle = require('jtaro-bundle')
    
    jtaroBundle.bundle({
      origin: 'index.html',
      target: 'www/index_template.html'
    })
    

    在命令行运行

    node build.js
    

    JTaro Bundle 会自动根据www/index_template.html里的内容去查找相对index.html的文件并拷贝,如果该文件不存在,则查找对应名称的文件夹,如果文件夹存在,即尝试将该文件夹里的文件打包成一个与文件夹同名的js文件

    将会看到www文件夹下多了pages.js、index.html和node_modules/文件夹,然后将www/indwx.html拖到浏览器访问,能看到与开发环境一致的效果表明成功了

    JTaro完成了哪些功能?