- 发布:2021-09-01 11:16
- 更新:2021-12-08 18:51
- 阅读:553
产品分类: uniapp/App
PC开发环境操作系统: Windows
PC开发环境操作系统版本号: win10
HBuilderX类型: 正式
HBuilderX版本号: 3.2.3
手机系统: 全部
页面类型: nvue
打包方式: 离线
项目创建方式: HBuilderX
测试过的手机:
示例代码:
page/index/index.vue 首页代码
<template>
<view>
</view>
</template>
<script>
export default {
}
</script>
<style>
</style>
page/index/bottombar/subNvue.nvue subNvue代码
<template>
<div class="page">
<span class="text">绿色为subNvue区域</span>
<input type="text" placeholder="请输入" @focus="focus()" @blur="blur()" />
</div>
</template>
<script>
export default {
data() {
return {};
},
onLoad() {},
methods: {
focus() {
uni.getSubNVueById("bottombar").setStyle({ height: "500px" })
},
blur() {
uni.getSubNVueById("bottombar").setStyle({ height: "200px" })
}
}
}
</script>
<style lang="scss">
.page {
background-color: #4CD964;
}
</style>
pages.json 配置文件
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app",
"app-plus": {
"subNVues": [{
"id": "bottombar", // 唯一标识
"path": "pages/index/bottombar/bottombar", // 页面路径
/*"type": "popup", 这里不需要*/
"style": {
"position": "dock",
"dock": "bottom",
"bottom:": "100px",
"width": "100%",
"height": "200px"
}
}]
}
}
}, {
"path": "pages/test/test",
"style": {
"navigationBarTitleText": "test"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
}
}
page/index/index.vue 首页代码
<template>
<view>
</view>
</template>
<script>
export default {
}
</script>
<style>
</style>
page/index/bottombar/subNvue.nvue subNvue代码
<template>
<div class="page">
<span class="text">绿色为subNvue区域</span>
<input type="text" placeholder="请输入" @focus="focus()" @blur="blur()" />
</div>
</template>
<script>
export default {
data() {
return {};
},
onLoad() {},
methods: {
focus() {
uni.getSubNVueById("bottombar").setStyle({ height: "500px" })
},
blur() {
uni.getSubNVueById("bottombar").setStyle({ height: "200px" })
}
}
}
</script>
<style lang="scss">
.page {
background-color: #4CD964;
}
</style>
pages.json 配置文件
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app",
"app-plus": {
"subNVues": [{
"id": "bottombar", // 唯一标识
"path": "pages/index/bottombar/bottombar", // 页面路径
/*"type": "popup", 这里不需要*/
"style": {
"position": "dock",
"dock": "bottom",
"bottom:": "100px",
"width": "100%",
"height": "200px"
}
}]
}
}
}, {
"path": "pages/test/test",
"style": {
"navigationBarTitleText": "test"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
}
}
操作步骤:
点击输入框弹出输入法,触发 focus 事件,focus 事件设置 subNvue 高度
input 失去焦点时,还原 subNvue 高度
page/index/bottombar/subNvue.nvue subNvue代码
<template>
<div class="page">
<span class="text">绿色为subNvue区域</span>
<input type="text" placeholder="请输入" @focus="focus()" @blur="blur()" />
</div>
</template>
<script>
export default {
data() {
return {};
},
onLoad() {},
methods: {
focus() {
uni.getSubNVueById("bottombar").setStyle({ height: "500px" })
},
blur() {
uni.getSubNVueById("bottombar").setStyle({ height: "200px" })
}
}
}
</script>
<style lang="scss">
.page {
background-color: #4CD964;
}
</style>
点击输入框弹出输入法,触发 focus 事件,focus 事件设置 subNvue 高度
input 失去焦点时,还原 subNvue 高度
page/index/bottombar/subNvue.nvue subNvue代码
<template>
<div class="page">
<span class="text">绿色为subNvue区域</span>
<input type="text" placeholder="请输入" @focus="focus()" @blur="blur()" />
</div>
</template>
<script>
export default {
data() {
return {};
},
onLoad() {},
methods: {
focus() {
uni.getSubNVueById("bottombar").setStyle({ height: "500px" })
},
blur() {
uni.getSubNVueById("bottombar").setStyle({ height: "200px" })
}
}
}
</script>
<style lang="scss">
.page {
background-color: #4CD964;
}
</style>
预期结果:
subNvue 高度正常调整
subNvue 高度正常调整
实际结果:
subNvue调整时,里面的 文本 <span>和 输入框 <input > 都消失了
subNvue调整时,里面的 文本 <span>和 输入框 <input > 都消失了
bug描述:
在andoroid app 中,subNvue 原生子窗体中的 input 标签的 cursor-spacing 属性无法使用,即输入法弹出时,输入法无法正常顶起 input 输入框,导致输入框被遮挡。
故采取手动调整 subNvue 高度的策略,方法如下:监听 input 获得焦点事件 focus,调整 subNvue 高度,监听 input 失去焦点事件 blur,还原subNvue高度。但是调用 subNvue 的 setStyle 方法调整 height 高度时,subNvue 的内容被遮挡住了。
另外,当通过输入法返回触发 input 失去焦点 blur 事件,和通过点击主页面(非subNvue)触发 input 失去焦点 blur 事件。页面被遮挡的表现形式也不同。
我的思路,用 uni.preload 加载一个页面, 页面里面通过 uni.$on 和 uni.$emit 做数据事件通信。可以规避你这个问题,使用起来和 subnvue 没大区别 。我 app 里面做评论组件的时候,就是这个思路,点击的时候,唤起已经 preload 的页面,把数据传递过去,这种思路可以实现全局弹窗、全局组件等,可以通过 v-if 和 uni.$emit 传递类型控制要显示的组件
-
3***@qq.com (作者)
用subNvue的起因是,要做一个自定义tabbar,但是页面包含video,<video>是原生的,层级太高,无法直接覆盖,使用<cover-video>达不到效果,只能使用subNvue达到目的。
2021-09-03 10:52
-
回复 3***@qq.com: 你在自定义tabbar 里面还加了 input 或 textarea ?感觉怪怪的输入框的顶起,如果adjust-size设置无效的话,考虑用 uni.onKeyboardHeight 监听键盘高度,别用 textarea 上的那个高度事件,实际测试2个事件差500ms 左右
2021-09-03 11:02
-
3***@qq.com (作者)
回复 青阳_1900: 就算不监视focus、blur事件,不调用 subNvue 的 .setStyle 方法,如果通过点击pages/index/index.vue 页面的任何地方(注意不是subNvue 子窗体) ,subNvue 子窗体内的内容都会被遮挡。
2021-09-03 14:19
<script>
import Vue from 'vue'
export default Vue.extend({
mpType: 'app',
onLaunch() {
uni.preloadPage({ url: '/pages/popup/index' })
}
})
</script>
<template>
<view style="flex:1">
<!-- 弹窗-绑定手机号 -->
<pop-bind v-if="type === 'bind'" />
<!-- 弹窗-登录 -->
<pop-login v-if="type === 'login'" />
<!-- 弹窗-分享 -->
<pop-share v-if="type === 'share'" :options="opts" />
<!-- 弹窗-用户协议 -->
<pop-privacy v-if="type === 'privacy'" :options="opts" />
<!-- 弹窗-幕布广告 -->
<pop-curtain v-if="type === 'curtain'" :options="opts" />
<!-- 弹窗-全屏广告 -->
<pop-splash v-if="type === 'splash'" :options="opts" />
<!-- 弹窗-公共组件 -->
<pop-modal v-if="type === 'modal'" :options="opts" />
<!-- 弹窗-评论组件 -->
<pop-comment v-if="type === 'comment@create'" :options="opts" />
</view>
</template>
<script>
export default {
data() {
return {
type: '',
opts: {},
}
},
onLoad() {
// 非纯nvue项目,在使用 preload 后会导致 this.$scope.eventChannel.on 会报错
// https://ask.dcloud.net.cn/question/126452
uni.$on('popup@show', ({ type, opts }) => {
this.type = type
this.opts = opts
})
uni.$on('popup@hide', (callback) => {
uni.hideKeyboard()
this.type = ''
this.opts = {}
uni.navigateBack()
setTimeout(() => {
callback && callback()
}, 50) // 避免关闭中执行
})
},
onUnload() {
uni.$off('popup@show')
uni.$off('popup@hide')
},
onBackPress({ from }) {
if (from !== 'navigateBack') return true // 阻止返回
},
}
</script>
3***@qq.com (作者)
管理员能看一下吗