uni-app 关于 nvue 开发

1. 前言

在前面小节的学习中,我们都知道 uni-app 框架是基于 vue 的前端解决方案,大部分的开发需求在 vue 页面基本都可以实现。

但是还有部分功能需要结合 nvue 页面才能实现,比如 <map> 组件在 vue 页面中层级是最高的。用人话说,就是不能在 <map> 组件上添加任何的标签,那我想要将标签显示在页面地图上怎么办呢?

这就需要用 nvue 页面来开发 <map> 组件了,这节课主要讲解如何在 uni-app 框架中使用 nvue 进行开发。

2. nvue 介绍

2.1 nvue 是什么?

nvue 是 native vue 的缩写,可以理解为 uni-app 的一种渲染方式。在 App 端,如果是 vue页面,使用的是小程序方式的 webview 渲染,如果是 nvue 页面,则使用 weex 方式的原生渲染。

使用 weex 方式的原生渲染,其实就是在 weex 的基础上封装了 uni-app 框架的 API,提供了App 端的原生渲染能力。nvue 常用于在 App 端给一些使用 vue 页面表现不佳的场景作为强化补充。

有很多同学之前没有接触过 weex,我们先来了解一下。

2.2 weex 是什么?

weex 也是比较流行的一个 Web 开发框架,也可以提供跨平台开发方案,实现一份代码同时在移动端、Web端同时运行的效果。但是 weex 有一个很大的问题就是它只是一个高性能的渲染器,没有足够的API能力。

nvue 就解决了 weex 的这个问题,weex 支持的东西,在 nvue 里大多都是支持的,并且 nvue 提供了丰富的插件生态,让前端工程师可以直接开发完整 App。

2.3 vue、nvue 页面可以共存吗?

一个项目中可以同时存在 vue 和 nvue 页面。比如项目首页使用的是nvue 页面,而二级页则使用 vue 页面。

如果一个页面路由下出现同名的 vue 和 nvue 文件,App 端会使用 nvue 页面,非 App 端会使用 vue 页面。

nvue 页面的组件和 JavaScript 的写法与 vue 页面是一样的,但是 css写法有一些区别,nvue 页面的 css 均采用 flex 布局,不支持其他布局方式。具体区别下面我们来详细讲解。

3. vue 和 nvue 的开发区别

在 HBuilderX 编辑器中进行页面创建时,可以选择创建为 vue 页面还是 nvue页面。vue 页面与 nvue 页面虽然可以在同一个 uni-app 项目中共存,但是这两种页面的开发还是有区别的,我们进行项目开发的时候需要注意一下。

3.1 nvue 的 css 写法受限

虽然 nvue 也可以多端编译,但是在 nvue 页面编写 css 没有在 vue 页面方便。nvue 页面的 css 写法是受限的。来看一下在 nvue 页面下,正确和错误的 css 写法实例:

3.1.1 border 不支持简写,在 nvue 中需要拆分

/* 错误写法 */
.class {
   border: 1px black solid;
}

/* 正确写法 */
.class {
   border-width: 1px;
   border-style: solid;
   border-color: black;
}

3.1.2 选择器只能选择单类

比如我们给下面的 HTML 代码添加样式。

<div class='imooc'>
  <text class=’imooc-text’>慕课网</text>
</div>

我们要给 <div> 的下一级 <text> 添加样式,不能直接 .imooc>text 这样写,需要给 <text> 单独添加一个样式属性,单独给这个属性定义样式。下面来演示一下在 nvue 页面添加样式的正确和错误的写法。

/* 错误写法 */
.imooc>text {
background-color: green;
border-width: 1px;
   border-style: solid;
   border-color: black;
}

/* 正确写法 */
.imooc {
   border-width: 1px;
   border-style: solid;
   border-color: black;
}
.imooc-text {
background-color: green;
}

3.1.3 引入样式文件

在 nvue 页面不能直接使用 import 引入样式文件。并且在 App.vue 文件中中定义的全局样式不会在 nvue 页面生效,nvue 页面的全局样式需要我们手动引入。

/* 错误写法 */
<style>  
  @import "@/main.css"; 
</style>

/* 正确写法 */
<style src="@/main.css">
</style>

3.1.4 不支持预编译语言

在 nvue 页面不支持使用 scss、less 等预编译语言。

/* 错误写法 */
<style lang="scss"> 
</style>

3.1.5 引入字体文件

在 nvue 中,不能在 <style> 标签中直接引入字体文件,需要用 weex 来加载字体。
实例:

const domModule = weex.requireModule('dom');
domModule.addRule('fontFace', {
    'fontFamily': "iconfont",
    'src': "url('./font.ttf')"
});

4. nvue 和 vue 相互通讯

如果使用 vue 就能实现项目需求,并且对项目性能没有很高的要求,我们尽量只使用 vue 来进行开发,不建议使用 nvue 来开发项目。因为 nvue 除了 css 写法受限之外,在 vue 和 nvue 页面混用的项目中,通讯也是一个大问题。

下面来看看在 vue 和 nvue 页面混用的项目中,nvue 和 vue 如何相互通讯。

4.1 nvue 向 vue 传值

在 nvue中使用 uni.postMessage(data) 发送数据,参数 data 只能是 json 数据,json 数据的值只支持字符串。在vue中使用 onUniNViewMessage 函数监听数据。

实例:
在 nvue 页面定义方法,使用 uni.postMessage(data) 发送数据。

<script>
export default {
methods: {
postMessage(item){
        uni.postMessage({
name:’慕课网’,
data:item
})
}
}
  }
</script>

在 vue 页面接收数据,对 nvue 页面发送的数据进行监听。

<script>
export default {
onUniNViewMessage:(e) => {
      const data = e.data
  uni.$emit(‘data’,data)
}
  }
</script>

4.2 vue 向 nvue 传值

方法一:使用 storage 缓存的方式进行参数传递。

在 vue 页面中打开 nvue 页面,并且通过 setStorageSync 方法将数据保存到缓存中。

<script>
export default {
methods: {
postMessage(item){
uni.setStorageSync('storageData', 'imooc');
uni.navigateTo({
          url:"/pages/nvue/nvue"
})
      }
}
  }
</script>

在 nvue 页面获得缓存中的数据。

<script>
  export default {
    created() {
      uni.getStorage({
        key:'storageData',
        success: (res) => {
          console.log("传递过来数据是:" + res.data)
        }
      })
    }
}
</script>

方法二:使用 globalData 全局数据的方式进行参数传递。

在 vue 页面中定义全局数据。

<script>
  export default {
//全局数据
globalData: {
domain: 'https://www.imooc.com'
}
  }
</script>

在 nvue 页面获取全局数据。

<script>
export default{
onLoad() {
//获取全局变量
console.log(getApp().globalData.domain)
}
}
</script>

5. 小结

使用 nvue 页面进行开发时,有个常见的错误是 Uncaught Error,这种错误一般是因为没有创建 vue 页面。uni-app 项目中必须要有一个 vue 页面,新建一个 vue 页面再重新编译项目就不会有问题了。

本节课程我们需要掌握的重点如下:

  • 了解 nvue、weex是什么;
  • 掌握 vue 和 nvue 页面开发区别,主要是 css 写法受限的问题;
  • 掌握 vue 和 nvue 页面之间如何相互通讯。