返回介绍

在 Weex 中使用 Vue.js

发布于 2019-12-31 14:29:15 字数 25969 浏览 2144 评论 0 收藏 0

  • 只含有运行时的构建版本

    如果你熟悉 Vue.js,你应该知道 Vue.js 有两种构建版本: 运行时 + 编译器只包含运行时。它们之间的区别在于编译器是否需要能够在运行时编译 template 选项。由于运行时构建版本比完整版本的构建版本轻约 30%(Vue 官方估算),为了更好的性能和更小的代码体积,Weex 集成的是运行时版本的 Vue。

    具体来说,差异如下:

    平台的差异

    Vue.js 最初是为 Web 平台设计的。虽然可以基于Weex开发原生应用程序,但是仍然存在许多

    与 Web 平台的主要差异是: 执行环境、DOM、样式和事件。

    执行环境

    Weex 主要用于编写多页的应用程序,每个页面都对应了原生开发中的 View 或者 Activity,并且保持自己的上下文。即使 Weex 的所有页面都使用的都是同一个 Javascript 引擎的实例(virtual machine),每个页面是执行环境也是互相隔离的(基于 Sandbox 技术)。

    使用 BroadcastChannel 可以实现跨页通信。

    具体来讲,每个页面的 Vue 变量都是不同的实例,即使是写在 Vue 上的“全局”配置(Vue.config.xxx)也只会影响 Weex 上的单个页面。

    在此基础上,一些 Vue 的 SPA (单页面应用)技术,如 Vuexvue-router 也将单页内生效。更通俗地说,“页面”概念在 SPA 技术中是虚拟的,但在 Weex 上却是真实的。即便如此,Vuex 和 vue-router 都是独立的库,都有自己的概念和使用场景,仍然可以在 Weex 里使用 Vuex 和 vue-router

    DOM

    因为在 Android 和 iOS 上没有 DOM(Document Object Model),如果你要手动操作和生成 DOM 元素的话可能会遇到一些兼容性问题。在你使用现代前端框架的情况下,操作数据与组件而不是生成的元素是一个比较好的做法。

    一些与 DOM 相关的特性,比如 v-htmlvm.$eltemplate 选项,在不同的平台上可能无法获得相同的反应。

    准确来说,vm.$el属性类型在web环境下是HTMLElement,但是在移动端并没有这个类型。实际上,它是一个由 Weex 文档对象模型 定义的特殊数据结构。

    样式

    样式表和 CSS 规则是由 Weex js 框架和原生渲染引擎管理的。要实现完整的 CSS 对象模型(CSSOM:CSS Object Model)并支持所有的 CSS 规则是非常困难的,而且没有这个必要。

    出于性能考虑,Weex 目前只支持单个类选择器,并且只支持 CSS 规则的子集。详情请参阅 通用样式文本样式

    在 Weex 里, 每一个 Vue 组件的样式都是 scoped

    事件

    目前在 Weex 里不支持事件冒泡和捕获,因此 Weex 原生组件不支持事件修饰符,例如.prevent.capture.stop.self

    此外,按键修饰符以及系统修饰键 例如 .enter.tab.ctrl.shift 在移动端基本没有意义,在 Weex 中也不支持。

    Web 渲染器

    如果你想在网络上呈现你的页面,你需要 vue-render-for-apache-weex 来实现它。

    WARNING

    vue-render-for-apache-weex 是三方插件,不由 Apache Weex 开发或维护。

    vue-render-for-apache-weex是 Vue DSL 的 Web 渲染器, 它在 Web 上实现了 Weex 的内置组件和内置模块。详情请参阅这里

    单文件组件

    Vue 中的单文件组件(即*.vue文件)是一种特殊的文件格式,扩展名为.vue。这个模板会在构建时编译到render函数里。

    此外,所有的编辑器里都支持一个好的语法高亮插件

    在 Weex 中使用单个文件组件语法是一种很好的做法。

    TIP

    在 Weex 中使用 Vue 的单个文件组件语法是一种最佳实践。

    因为针对 Weex 的 Web 平台的编译工具并不一样,如果你直接写的 render 函数,则绕过了 weex-loader 编译模板的过程,这样的话你需要自行处理平台差异的细节。

    编译目标

    因为平台的差异以及为了提高网络性能,*.vue文件需要用两种不同的方式来编译:

    • 对于 Web 平台来说,你可以用任何正式的方式来编译源文件,例如 使用 Webpack + vue-loader 或者 Browserify + vueify 来编译*.vue文件。
    • 对于安卓与 iOS 平台来说, 你需要使用 weex-loader 来编译*.vue文件。

    不同的平台使用不同的bundles,可以充分利用平台原有的特性,减少构建时的兼容性代码。但是源代码仍然是一样的,唯一的区别是编译它的方法。

    使用weex-loader

    weex-loader 是一个 webpack 的 loader,它能把*.vue文件转化为简单的javascript 模块用于安卓以及 iOS 平台。所有的特性和配置都是跟 vue-loader 一样的。

    需要注意的是,如果 Webpack 的 entry 配置项是一个 *.vue 文件的话,你仍需要传递一个额外的 entry 参数作为标记。

    const webpackConfig = {
      // Add the entry parameter for the .vue file
      entry: './path/to/App.vue?entry=true'
    
      /* ... */
    
      use: {
        loaders: [{
          // matches the .vue file path which contains the entry parameter
          test: /\.vue(\?^^]+)?$/,
          loaders: ['weex-loader']
        }]
      }
    }
    

    如果你现在用的是.js文件做入口文件,你不需要写那些额外的参数。 推荐 webpack 配置的入口文件使用 javascript 文件。

    {
      entry: './path/to/entry.js'
    }
    

    TIP

    无论什么情况下都使用 javascript 文件作为入口文件。

    使用weex-loader单文件编译示例

    1. 执行npm init
    2. 修改package.json文件,向其中添加:
      "dependencies": {
        "babel-loader": "^8.0.6",
        "weex-loader": "^0.7.12",
        "webpack": "^2.2.1"
      },
      "scripts": {
        "build": "webpack --config webpack.config.js"
      },
    
    1. 创建webpack.config.js,按照你的需要更改。
    const webpack = require('webpack');
    const path = require('path');
    
    module.exports = {
      entry: '<your-input-file>',
      output: {
        path: path.resolve(__dirname, './'),
        filename: <your-output-file>
      },
      module: {
    	    rules: [
    	      {
    	        test: /\.vue(\?[^?]+)?$/,
    	        loaders: ['weex-loader']
    	      },
    	      {
    	        test: /\.js$/,
    	        loaders: ['babel-loader']
    	      }
    	    ]
    	  },
    	plugins: [
    		new webpack.BannerPlugin({
    			raw: true ,
    			banner: '// { "framework": "Vue" }\n'
    		})
    	]
    }
    
    1. 执行npm run build
    2. 完成。

    使用weex compile编译

    1. 安装weex-clinpm install weex-toolkit -g
    2. 执行weex compile [资源文件] [产物地址]命令
    3. 完成。

    支持的功能

    全局配置

    Vue “全局”配置只会影响 Weex 上的单一页面,配置不会在不同的 Weex 页面之间共享。

    Vue 全局配置是否支持说明
    Vue.config.silent支持-
    Vue.config.optionMergeStrategies支持-
    Vue.config.devtools不支持只在 Web 环境下支持
    Vue.config.errorHandler支持-
    Vue.config.warnHandler支持-
    Vue.config.ignoredElements支持不推荐
    Vue.config.keyCodes不支持在移动端无用
    Vue.config.performance不支持devtools 一样
    Vue.config.productionTip支持-

    全局 API

    Vue 全局 API是否支持说明
    Vue.extend支持-
    Vue.nextTick支持-
    Vue.set支持-
    Vue.delete支持-
    Vue.directive支持-
    Vue.filter支持-
    Vue.component支持-
    Vue.use支持-
    Vue.mixin支持-
    Vue.version支持-
    Vue.compile不支持Weex 用的是 只包含运行时构建

    选项

    Vue 选项是否支持说明
    data支持-
    props支持-
    propsData支持-
    computed支持-
    methods支持-
    watch支持-
    el支持在移动端el的值是无意义的
    template不支持Weex 用的是 只包含运行时构建
    render支持不推荐
    renderError支持-
    directives支持-
    filters支持-
    components支持-
    parent支持不推荐
    mixins支持-
    extends支持-
    provide/inject支持不推荐
    name支持-
    delimiters支持不推荐
    functional支持-
    model支持-
    inheritAttrs支持-
    comments不支持-

    生命周期钩子

    Vue 组件的实例生命周期钩子将在特定的阶段发出,详情请参考 Vue 组件的生命周期图示

    Vue 生命周期钩子是否支持说明
    beforeCreate支持-
    created支持-
    beforeMount支持-
    mounted支持和 Web 端不完全一样(下文有详解)
    beforeUpdate支持-
    updated支持-
    activated不支持不支持<keep-alive>
    deactivated不支持不支持<keep-alive>
    beforeDestroy支持-
    destroyed支持-
    errorCaptured支持在 Vue 2.5.0+, Weex SDK 0.18+ 中新增

    关于 "mounted" 生命周期

    和浏览不同的是,Weex 的渲染流程是异步的,而且渲染出来的结果都是原生系统中的 View,这些数据都无法被 javascript 直接获取到。因此在 Weex 上,Vue 的 mounted 生命周期在当前组件的 virtual-dom (Vue 里的 VNode) 构建完成后就会触发,此时相应的原生视图未必已经渲染完成。

    实例属性

    Vue 实例属性是否支持说明
    vm.$data支持-
    vm.$props支持-
    vm.$el支持移动端没有HTMLElement
    vm.$options支持-
    vm.$parent支持-
    vm.$root支持-
    vm.$children支持-
    vm.$slots支持-
    vm.$scopedSlots支持-
    vm.$refs支持-
    vm.$isServer支持永远是false
    vm.$attrs支持-
    vm.$listeners支持-

    实例方法

    Vue 实例方法是否支持说明
    vm.$watch()支持-
    vm.$set()支持-
    vm.$delete()支持-
    vm.$on()支持-
    vm.$once()支持-
    vm.$off()支持-
    vm.$emit()支持-
    vm.$mount()不支持你不需要手动安装 Vue 实例
    vm.$forceUpdate()支持-
    vm.$nextTick()支持-
    vm.$destroy()支持-

    模板指令

    Vue 指令是否支持说明
    v-text支持-
    v-html不支持Weex 中没有 HTML 解析器,这不是很好的实现
    v-show不支持不支持 display: none;
    v-if支持-
    v-else支持-
    v-else-if支持-
    v-for支持-
    v-on支持不支持事件修饰符
    v-bind支持-
    v-model支持-
    v-pre支持-
    v-cloak不支持只支持单类名选择器
    v-once支持-

    特殊属性

    Vue 特殊属性是否支持说明
    key支持-
    ref支持-
    slot支持-
    slot-scope支持在 Vue 2.5.0+, Weex SDK 0.18+ 中新增
    scope支持不推荐
    is支持-

    内置组件

    Vue 内置组件是否支持说明
    component支持-
    transition不支持在移动端 enterleave 的概念可能有点不同, 并且 Weex 不支持display: none;
    transition-group不支持transition 一样
    keep-alive不支持移动端的原生组件不能被前端缓存
    slot支持-

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文