For those native functions that do not depend on UI interaction, nvue encapsulates them into modules, which is a method of calling native capabilities through javascript.
uni.requireNativePlugin// Usage mode
// PluginName is the native plugin name.
const PluginName = uni.requireNativePlugin(PluginName);
Third-party native plug-ins that support native cloud packaging in the project nativeplugins directory and plug-in market. It is also very convenient for you to transplant the existing native modules to nvue platform. Usage: can only be used in manifest.json->App native plug-in configuration-> select local plug-in or cloud plug-in-> package the custom base. See details
nvue also supports js API interface of uni-app. Unless otherwise specified, it means that both vue file and nvue file support it. See details.
The uni-app API that is not supported in nvue, See details
Weex provide the ability of loading custom through DOM.addRule. Developers can load iconfont and custom font by specifying the font-family. Developers may use the following code snippet to load their font:
<template>
<view>
<text class="my-iconfont"></text>
</view>
</template>
<script>
export default{
beforeCreate() {
const domModule = uni.requireNativePlugin('dom')
domModule.addRule('fontFace', {
'fontFamily': "myIconfont",
'src': "url('http://at.alicdn.com/t/font_2234252_v3hj1klw6k9.ttf')"
});
}
}
</script>
<style>
.my-iconfont {
font-family:myIconfont;
font-size:60rpx;
color: #00AAFF;
}
</style>
addRule(type, contentObject)
http. Read from http, e.g. url('http://at.alicdn.com/t/font_1469606063_76593.ttf')https. Read from https, e.g. url('https://at.alicdn.com/t/font_1469606063_76593.ttf')local, Android ONLY. Read from assets directory e.g. url('local://foo.ttf'), the foo.ttf is in your android assets directory.file. Read from a local file, e.g. url('file://storage/emulated/0/Android/data/com.alibaba.weex/cache/http:__at.alicdncom_t_font_1469606063_76593.ttf')data. Read from a base64 data source, e.g. url('data:font/truetype;charset=utf-8;base64,AAEAAAALAIAAAwAwR1NVQrD+....'), the above data field is only a part of the actual data.Notice
You can name
fontFamilyinaddRuleas you wish in your page, any string is OK. But this is not the real font-family name of the font file. The real name or system name for the font is stored in binrary data of ttf file. You must ensure that the real font-family name of font file is unique. Or your font may not be successfully registered to device and your text may display as a '?'. Specially, if you are using http://www.iconfont.cn/ to build your iconfont. Make sure that you set a unique enough font-family name for your font in project settings. CallingaddRuleinbeforeCreateis recommended.
Scroll the scrollable component to the referenced component. This API should only be used in the children components of a scrollable component, such as in a <scroller> or <list> component.
scrollToElement(ref, options)
offset, an space on top of the ref component, which is also scrolling down to the visual viewport. Default is 0.animated, a boolean indicates whether a scroll animation should be played. If set to false, the ref component will jump into the view without any transition animation. Default is true. <template>
<view class="wrapper">
<scroller class="scroller">
<view class="row" v-for="(name, index) in rows" :ref="'item'+index">
<text class="text" :ref="'text'+index">{{name}}</text>
</view>
</scroller>
<view class="group">
<text @click="goto10" class="button">Go to 10</text>
<text @click="goto20" class="button">Go to 20</text>
</view>
</view>
</template>
<script>
const dom = uni.requireNativePlugin('dom')
export default {
data() {
return {
rows: []
}
},
created() {
for (let i = 0; i < 30; i++) {
this.rows.push('row ' + i)
}
},
methods: {
goto10(count) {
const el = this.$refs.item10[0]
dom.scrollToElement(el, {})
},
goto20(count) {
const el = this.$refs.item20[0]
dom.scrollToElement(el, {
offset: 0
})
}
}
}
</script>
<style scoped>
.scroller {
width:700rpx;
height:500px;
border-width: 3px;
border-style: solid;
border-color: rgb(162, 217, 192);
margin:0 25rpx;
}
.row {
height: 100rpx;
flex-direction: column;
justify-content: center;
padding-left: 30rpx;
border-bottom-width: 2px;
border-bottom-style: solid;
border-bottom-color: #DDDDDD;
}
.text {
font-size: 45rpx;
color: #666666;
}
.group {
flex-direction: row;
justify-content: center;
margin-top: 60rpx;
}
.button {
width: 200rpx;
padding-top: 20rpx;
padding-bottom: 20rpx;
font-size: 40rpx;
margin-left: 30rpx;
margin-right: 30rpx;
text-align: center;
color: #41B883;
border-width: 2px;
border-style: solid;
border-color: rgb(162, 217, 192);
background-color: rgba(162, 217, 192, 0.2);
}
</style>
You can get the bounding rect of the referenced component using this API.
getComponentRect(ref, callback)
An example callback result should be like:
{
result: true,
size: {
bottom: 60,
height: 15,
left: 0,
right: 353,
top: 45,
width: 353
}
}
This method needs to be called after the node rendering to obtain the correct information, it can be called in mounted or updated after updating data
If you want to get the bounding rect of outside viewport of the weex container, you can specify the
refas a literal string'viewport', likegetComponentRect('viewport', callback).
The animation module is used to perform animation on components. JS-Animation can perform a series of simple transformations (position, size, rotation, background color, and opacity) on the component with Javascript.
For example, if you have a image component, you can move, rotate, grow, or shrink it by animation.
<template>
<view class="box">
<view ref="test" @click="move" class="box-item"></view>
</view>
</template>
<script>
const animation = uni.requireNativePlugin('animation')
export default {
methods: {
move() {
var testEl = this.$refs.test;
animation.transition(testEl, {
styles: {
backgroundColor: '#007AFF',
transform: 'translate(100px, 80px)',
transformOrigin: 'center center'
},
duration: 800, //ms
timingFunction: 'ease',
delay: 0 //ms
},()=>{
uni.showToast({
title: 'finished',
icon:'none'
});
})
}
}
}
</script>
<style scoped>
.box{
width:750rpx;
height:750rpx;
}
.box-item{
width: 250rpx;
height: 250rpx;
background-color: #00aaff;
}
</style>
ref for an element is test, you can start an animation with this.$refs.test.The following table lists all legal parameters of options:
| Property | Describe |
|---|---|
| styles | specifies the names and values of styles to which a transition effect should be applied. |
| duration | specifies the duration of animation execution, the default value is 0, meaning that the component get the desired property immediately. |
| delay | specifies the waiting time before the animation starts. The default value is 0. |
| needLayout | Specifies whether the change to layout(width/height/etc..) is persistence and takes affect after the animation. Default value is false |
| timingFunction | describes how the intermediate values are calculated for the CSS properties being affected by the animation effect. default value is linear |
The supported styles are listed below:
| Property | Describe |
|---|---|
| width | Indicate the width value applied to the component after the animation is executed. Set needLayout to true if you need to influence the layout. The default value is computed width. |
| height | Indicate the height value applied to the component after the animation is executed. Set needLayout to true if you need to influence the layout. The default value is computed width. |
| backgroundColor | The background color applied to the component after the animation is executed, the default value is computed backgroundColor. |
| opacity | Indicate the opacity value applied to the component after the animation is executed, the default value is computed opacity. |
| transformOrigin | transformOrigin defines the central point of the change process, such as transformOrigin: x-axis y-axis parameter x-axis can be left, center, right, length or percentage, and parameter y-axis can be top, center, bottom, length or percentage. The default value is center center. |
| transform | The transformation type of transform may include rotate, translate, scale and other attributes. The default value is null. See details below |
transform
| Property | Describe |
|---|---|
| translate/translateX/translateY | Specify the location to which the element is to be moved. In length or percentage, and the default value is 0. |
| rotate/rotateX/rotateY | v0.16+ specifies the angle at which the element will be rotated. In degree, and the default value is 0 |
| scale/scaleX/scaleY | Enlarge or reduce the element in proportion. In number, and the default value is 1 |
| perspective | v0.16+ the distance from the observer to the z=0 plane, which is valid in Android 4.1 and above. In number, and the default value is positive infinity. |
timingFunction
| Property | Describe |
|---|---|
| linear | The animation speed is the same from beginning to end |
| ease-in | Animation speed from slow to fast |
| ease-out | Animation speed from fast to slow |
| ease-in-out | The animation first accelerates to the middle point and then decelerates to the end point |
| cubic-bezier(x1, y1, x2, y2) | Define the change process in cubic Bessel function, and the parameter value of the function must be between 0 and 1. For more information about cubic bezier, please refer to cubic-bezier and Bézier curve. |
Notes
result, is Successand Fail, Android can not support until now.If you need to use CSS animation, please refer to transition and transform.
uni-app is the separation of the logical layer and the view layer. At this point, two layers of communication costs will be incurred. Dragging elements in the view layer, for example, might not be a smooth experience due to communication loss if events are constantly received in the logic layer.
BindingX (opens new window) is a pre-description interaction syntax provided by weex. Analyze the BindingX rule by native, and handle the interaction and dynamic effect of the view layer according to this rule. No more real-time de-js logic layer running and communicating.
BindingX is similar to an enhanced version of css, with high running performance, but not as much programming flexibility as js.
uni-app has built-in BindingX, which can be used in nvue to complete complex animation effects.
From HBuilderX 2.3.4+, the uni-app compilation mode can directly reference the uni.requireNativePlugin('bindingx') module, and the weex mode also needs to use npm to reference.
For the BindingX demo example, please refer to the related examples of vue in the BindingX example, and copy the vue code in the experimental field to the nvue file.
origin in expression for now <template>
<div class="container">
<div ref="b1" class="btn" style="background-color:#6A1B9A" @click="clickBtn">
<text class="text">A</text>
</div>
<div ref="b2" class="btn" style="background-color:#0277BD" @click="clickBtn">
<text class="text">B</text>
</div>
<div ref="b3" class="btn" style="background-color:#FF9800" @click="clickBtn">
<text class="text">C</text>
</div>
<div ref="main_btn" class="btn" @click="clickBtn">
<image class="image" ref="main_image" src="https://gw.alicdn.com/tfs/TB1PZ25antYBeNjy1XdXXXXyVXa-128-128.png" />
</div>
</div>
</template>
<script>
const Binding = uni.requireNativePlugin('bindingx');
module.exports = {
data() {
return {
isExpanded: false
}
},
methods: {
getEl: function(el) {
if (typeof el === 'string' || typeof el === 'number') return el;
if (WXEnvironment) {
return el.ref;
} else {
return el instanceof HTMLElement ? el : el.$el;
}
},
collapse: function() {
let main_btn = this.getEl(this.$refs.main_btn);
let main_image = this.getEl(this.$refs.main_image);
let b1 = this.getEl(this.$refs.b1);
let b2 = this.getEl(this.$refs.b2);
let b3 = this.getEl(this.$refs.b3);
let main_binding = Binding.bind({
eventType: 'timing',
exitExpression: 't>800',
props: [{
element: main_image,
property: 'transform.rotateZ',
expression: 'easeOutQuint(t,45,0-45,800)'
}, {
element: main_btn,
property: 'background-color',
expression: "evaluateColor('#607D8B','#ff0000',min(t,800)/800)"
}]
}, function(res) {
if (res.state === 'exit') {
Binding.unbind({
token: main_binding.token,
eventType: 'timing'
})
}
});
let btn_binding = Binding.bind({
eventType: 'timing',
exitExpression: 't>800',
props: [{
element: b1,
property: 'transform.translateY',
expression: "easeOutQuint(t,-150,150,800)"
}, {
element: b2,
property: 'transform.translateY',
expression: "t<=100?0:easeOutQuint(t-100,-300,300,700)"
}, {
element: b3,
property: 'transform.translateY',
expression: "t<=200?0:easeOutQuint(t-200,-450,450,600)"
}]
}, function(res) {
if (res.state === 'exit') {
Binding.unbind({
token: btn_binding.token,
eventType: 'timing'
})
}
})
},
expand: function() {
let main_btn = this.getEl(this.$refs.main_btn);
let main_image = this.getEl(this.$refs.main_image);
let b1 = this.getEl(this.$refs.b1);
let b2 = this.getEl(this.$refs.b2);
let b3 = this.getEl(this.$refs.b3);
let main_binding = Binding.bind({
eventType: 'timing',
exitExpression: 't>100',
props: [{
element: main_image,
property: 'transform.rotateZ',
expression: 'linear(t,0,45,100)'
}, {
element: main_btn,
property: 'background-color',
expression: "evaluateColor('#ff0000','#607D8B',min(t,100)/100)"
}]
}, function(res) {
if (res.state === 'exit') {
Binding.unbind({
token: main_binding.token,
eventType: 'timing'
})
}
});
let btn_binding = Binding.bind({
eventType: 'timing',
exitExpression: 't>800',
props: [{
element: b1,
property: 'transform.translateY',
expression: "easeOutBounce(t,0,0-150,800)"
}, {
element: b2,
property: 'transform.translateY',
expression: "t<=100?0:easeOutBounce(t-100,0,0-300,700)"
}, {
element: b3,
property: 'transform.translateY',
expression: "t<=200?0:easeOutBounce(t-200,0,0-450,600)"
}]
}, function(res) {
if (res.state === 'exit') {
Binding.unbind({
token: btn_binding.token,
eventType: 'timing'
})
}
})
},
clickBtn: function(e) {
if (this.isExpanded) {
this.collapse();
} else {
this.expand();
}
this.isExpanded = !this.isExpanded;
}
}
}
</script>
<style>
.container {
flex: 1;
}
.image {
width: 60px;
height: 60px;
}
.text {
color: #ffffff;
font-size: 30px;
}
.btn {
width: 100px;
height: 100px;
background-color: #ff0000;
align-items: center;
justify-content: center;
position: absolute;
border-radius: 50px;
bottom: 25px;
right: 25px;
}
</style>
In uni-app, nvue and vue pages can be mixed and used.
It is recommended to use uni.$on, uni.$emit for page communication. The old communication method is no longer recommended.
//Page for receiving information
// $on(eventName, callback)
uni.$on('page-popup', (data) => {
console.log('title: ' + data.title)
console.log('content: ' + data.content)
})
//Page for sending information
// $emit(eventName, data)
uni.$emit('page-popup', {
title: 'I am title',
content: 'I am content'
});
Note when using this page to communicate: use uni.$off to remove the event listener before unloading the page. Reference (opens new window)
//test.nvue
<template>
<view @click="test">
<text>Click the page to send data</text>
</view>
</template>
<script>
export default {
methods: {
test(e) {
uni.postMessage({test: "Data",value:"Data"});
}
}
}
</script>
//App.vue
<script>
export default {
onUniNViewMessage:function(e){
console.log("App.vue receive data")
console.log(JSON.stringify(e.data))
},
onLaunch: function() {
console.log('App Launch');
}
}
</script>
In addition communication events, variables and storage can also be shared between vue and nvue pages. The scheme of sharing variables and data provided by uni-app is as follows:
vuex. This is vue's official state management tool.Note: Direct introduction of
storeis not supported, you can use auxiliary methods such asmapState,mapGetters,mapMutationsor usethis.$store
uni.storage for storage. This storage is persistent. For example, the login status can be saved here.globalData mechanism is universal at all ends. Define globalData in the App.vue file as follows: <script>
export default {
globalData: {
text: 'text'
},
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
globalData in js is as follows: getApp().globalData.text = 'test'globalData to the page, you can perform variable reassignment during the onShow declaration cycle of the page.nvue supports most uni-app APIs. The following only lists the APIs that are not currently supported.
| API | Describe | Solution |
|---|---|---|
| uni.createAnimation() | Create an animation instance | animation |
| API | Describe | Solution |
|---|---|---|
| uni.pageScrollTo() | Scroll the page to the target location | scrollToElement |
| API | Describe |
|---|---|
| uni.createIntersectionObserver() | Create and return an example of the IntersectionObserver object |
For the usage of canvas API, please refer to canvas document (opens new window).