uni-app ios端vue组件不可使用

发布于 1周前 作者 itying888 来自 Uni-App

uni-app ios端vue组件不可使用

示例代码:

<template>
<view class="keyboard">
<button @click="appendValue(1)">1</button>
<button @click="appendValue(2)">2</button>
<button @click="appendValue(3)">3</button>
<button class="delete-btn" @click="deleteLast">⌫</button>  
<button @click="appendValue(4)">4</button>  
<button @click="appendValue(5)">5</button>  
<button @click="appendValue(6)">6</button>  
<button class="transfer-btn" v-if="!inputValue " disabled>付款</button>  
<button class="transfer-btn" @click="makeTransfer" v-else>付款</button>  

<button @click="appendValue(7)">7</button>  
<button @click="appendValue(8)">8</button>  
<button @click="appendValue(9)">9</button>  

<button @click="appendValue(0)" class="zero-btn">0</button>  
<button @click="appendValue('.')">.</button>  
</view>  
</template>  

<script setup>
import {
ref,
defineProps,
defineEmits,
watch
} from 'vue' // 导入 watch  

// 接收父组件传递的 modelValue 值  
const props = defineProps({  
modelValue: {  
type: String,  
default: ''  
}  
})  

const emit = defineEmits(['update:modelValue', 'transfer'])  

// 用于绑定的金额值  
const inputValue = ref(props.modelValue)  

// 监听 inputValue 的变化,更新父组件的 modelValue  
watch(inputValue, (newValue) => {  
emit('update:modelValue', newValue)  
})  

// 防抖后的appendValue函数
const appendValue = debounce((value) => {
uni.vibrateShort({
success: function() {
// 判断小数点后面是否有两位数字,如果有两位就不能再输入了
let index = inputValue.value.indexOf('.');  

// 1. 输入第一个为小数点时,返回 0.  
if (value.toString() === '.' && inputValue.value === '') {  
inputValue.value = '0.';  
return;  
}  

// 2. 输入的值为小数点且已有小数点时,不进行操作  
if (value.toString() === '.' && inputValue.value.includes('.')) {  
return;  
}  

// 3. 输入的值如果是数字并且第一个是0,且第二个不是小数点,覆盖0  
if (inputValue.value.startsWith('0') && inputValue.value.length === 1 && value !== '0' && value !== '.') {  
inputValue.value = value.toString();  
return;  
}  

// 4. 如果金额长度超过7位,则不再添加  
if (inputValue.value.length >= 7 && !inputValue.value.includes('.')) {  
return;  
}  

// 5. 当存在小数点时,限制小数点后面只能有两位  
if (inputValue.value.includes('.') && inputValue.value.length - index - 1 >= 2) {  
return;  
}  

// 6. 更新金额  
inputValue.value += value;  
}
}, 50); // 防抖延迟时间设置为50ms  

// 防抖函数,传入需要防抖的函数和延迟时间
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer); // 清除上一个定时器
timer = setTimeout(() => {
fn(...args);  // 延迟执行函数
}, delay);
};
}

// 删除最后一个字符  
const deleteLast = () => {  

uni.vibrateShort({  
success: function() {  
inputValue.value = inputValue.value.slice(0, -1)  
}
})  

}  

// 转账操作  
const makeTransfer = () => {  
uni.vibrateShort({  
success: function() {  
if (inputValue.value.length >= 7 && !inputValue.value.includes('.')) {  
uni.showToast({  
title: '单笔金额超出限制',  
icon: 'error'  
})  
return  
}  
if (inputValue.value.length > 9 && inputValue.value.includes('.')) {  
uni.showToast({  
title: '单笔金额超出限制',  
icon: 'error'  
})  
return  
}  
if (+inputValue.value < 0.01) {  
uni.showToast({  
title: '金额不能小于0.01元',  
icon: 'error'  
})  
return  
}  

// uni.showToast({  
//  title: '付款成功' + inputValue.value+'元',  
//  icon: 'success'  
// })  

// 发出转账事件,并传递输入的金额给父组件  
emit('transfer', inputValue.value)  

inputValue.value = '' // 清空输入框  

}
})  

}  
</script>  

<style scoped>
.keyboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 5px;
background-color: #f8f8f8;
height: 100%;
}

button {
font-size: 20px;
border: none;
background-color: #ffffff;
color: #000000;
width: 100%;
}

button:active {
background-color: #e0e0e0;
}

.delete-btn {
background-color: #fff;
font-weight: bold;
}

.transfer-btn {
background-color: #1678ff;
color: #ffffff;
grid-row: span 3; /* 占3行 */
height: 170px;
line-height: 170px;
}

.zero-btn {
grid-column: span 2; /* 占两列 */
}
</style>

操作步骤:

<template>
<view class="keyboard">
<button @click="appendValue(1)">1</button>
<button @click="appendValue(2)">2</button>
<button @click="appendValue(3)">3</button>
<button class="delete-btn" @click="deleteLast">⌫</button>  
<button @click="appendValue(4)">4</button>  
<button @click="appendValue(5)">5</button>  
<button @click="appendValue(6)">6</button>  
<button class="transfer-btn" v-if="!inputValue " disabled>付款</button>  
<button class="transfer-btn" @click="makeTransfer" v-else>付款</button>  

<button @click="appendValue(7)">7</button>  
<button @click="appendValue(8)">8</button>  
<button @click="appendValue(9)">9</button>  

<button @click="appendValue(0)" class="zero-btn">0</button>  
<button @click="appendValue('.')">.</button>  
</view>  
</template>  

<script setup>
import {
ref,
defineProps,
defineEmits,
watch
} from 'vue' // 导入 watch  

// 接收父组件传递的 modelValue 值  
const props = defineProps({  
modelValue: {  
type: String,  
default: ''  
}  
})  

const emit = defineEmits(['update:modelValue', 'transfer'])  

// 用于绑定的金额值  
const inputValue = ref(props.modelValue)  

// 监听 inputValue 的变化,更新父组件的 modelValue  
watch(inputValue, (newValue) => {  
emit('update:modelValue', newValue)  
})  

// 防抖后的appendValue函数
const appendValue = debounce((value) => {
uni.vibrateShort({
success: function() {
// 判断小数点后面是否有两位数字,如果有两位就不能再输入了
let index = inputValue.value.indexOf('.');  

// 1. 输入第一个为小数点时,返回 0.  
if (value.toString() === '.' && inputValue.value === '') {  
inputValue.value = '0.';  
return;  
}  

// 2. 输入的值为小数点且已有小数点时,不进行操作  
if (value.toString() === '.' && inputValue.value.includes('.')) {  
return;  
}  

// 3. 输入的值如果是数字并且第一个是0,且第二个不是小数点,覆盖0  
if (inputValue.value.startsWith('0') && inputValue.value.length === 1 && value !== '0' && value !== '.') {  
inputValue.value = value.toString();  
return;  
}  

// 4. 如果金额长度超过7位,则不再添加  
if (inputValue.value.length >= 7 && !inputValue.value.includes('.')) {  
return;  
}  

// 5. 当存在小数点时,限制小数点后面只能有两位  
if (inputValue.value.includes('.') && inputValue.value.length - index - 1 >= 2) {  
return;  
}  

// 6. 更新金额  
inputValue.value += value;  
}
}, 50); // 防抖延迟时间设置为50ms  

// 防抖函数,传入需要防抖的函数和延迟时间
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer); // 清除上一个定时器
timer = setTimeout(() => {
fn(...args);  // 延迟执行函数
}, delay);
};
}

// 删除最后一个字符  
const deleteLast = () => {  

uni.vibrateShort({  
success: function() {  
inputValue.value = inputValue.value.slice(0, -1)  
}
})  

}  

// 转账操作  
const makeTransfer = () => {  
uni.vibrateShort({  
success: function() {  
if (inputValue.value.length >= 7 && !inputValue.value.includes('.')) {  
uni.showToast({  
title: '单笔金额超出限制',  
icon: 'error'  
})  
return  
}  
if (inputValue.value.length > 9 && inputValue.value.includes('.')) {  
uni.showToast({  
title: '单笔金额超出限制',  
icon: 'error'  
})  
return  
}  
if (+inputValue.value < 0.01) {  
uni.showToast({  
title: '金额不能小于0.01元',  
icon: 'error'  
})  
return  
}  

// uni.showToast({  
//  title: '付款成功' + inputValue.value+'元',  
//  icon: 'success'  
// })  

// 发出转账事件,并传递输入的金额给父组件  
emit('transfer', inputValue.value)  

inputValue.value = '' // 清空输入框  

}
})  

}  
</script>  

<style scoped>
.keyboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 5px;
background-color: #f8f8f8;
height: 100%;
}

button {
font-size: 20px;
border: none;
background-color: #ffffff;
color: #000000;
width: 100%;
}

button:active {
background-color: #e0e0e0;
}

.delete-btn {
background-color: #fff;
font-weight: bold;
}

.transfer-btn {
background-color: #1678ff;
color: #ffffff;
grid-row: span 3; /* 占3行 */
height: 170px;
line-height: 170px;
}

.zero-btn {
grid-column: span 2; /* 占两列 */
}
</style>

预期结果:

<template>
<view class="keyboard">
<button @click="appendValue(1)">1</button>
<button @click="appendValue(2)">2</button>
<button @click="appendValue(3)">3</button>
<button class="delete-btn" @click="deleteLast">⌫</button>  
<button @click="appendValue(4)">4</button>  
<button @click="appendValue(5)">5</button>  
<button @click="appendValue(6)">6</button>  
<button class="transfer-btn" v-if="!inputValue " disabled>付款</button>  
<button class="transfer-btn" @click="makeTransfer" v-else>付款</button>  

<button @click="appendValue(7)">7</button>  
<button @click="appendValue(8)">8</button>  
<button @click="appendValue(9)">9</button>  

<button @click="appendValue(0)" class="zero-btn">0</button>  
<button @click="appendValue('.')">.</button>  
</view>  
</template>  

<script setup>
import {
ref,
defineProps,
defineEmits,
watch
} from 'vue' // 导入 watch  

// 接收父组件传递的 modelValue 值  
const props = defineProps({  
modelValue: {  
type: String,  
default: ''  
}  
})  

const emit = defineEmits(['update:modelValue', 'transfer'])  

// 用于绑定的金额值  
const inputValue = ref(props.modelValue)  

// 监听 inputValue 的变化,更新父组件的 modelValue  
watch(inputValue, (newValue) => {  
emit('update:modelValue', newValue)  
})  

// 防抖后的appendValue函数
const appendValue = debounce((value) => {
uni.vibrateShort({
success: function() {
// 判断小数点后面是否有两位数字,如果有两位就不能再输入了
let index = inputValue.value.indexOf('.');  

// 1. 输入第一个为小数点时,返回 0.  
if (value.toString() === '.' && inputValue.value === '') {  
inputValue.value = '0.';  
return;  
}  

// 2. 输入的值为小数点且已有小数点时,不进行操作  
if (value.toString() === '.' && inputValue.value.includes('.')) {  
return;  
}  

// 3. 输入的值如果是数字并且第一个是0,且第二个不是小数点,覆盖0  
if (inputValue.value.startsWith('0') && inputValue.value.length === 1 && value !== '0' && value !== '.') {  
inputValue.value = value.toString();  
return;  
}  

// 4. 如果金额长度超过7位,则不再添加  
if (inputValue.value.length >= 7 && !inputValue.value.includes('.')) {  
return;  
}  

// 5. 当存在小数点时,限制小数点后面只能有两位  
if (inputValue.value.includes('.') && inputValue.value.length - index - 1 >= 2) {  
return;  
}  

// 6. 更新金额  
inputValue.value += value;  
}
}, 50); // 防抖延迟时间设置为50ms  

// 防抖函数,传入需要防抖的函数和延迟时间
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer); // 清除上一个定时器
timer = setTimeout(() => {
fn(...args);  // 延迟执行函数
}, delay);
};
}

// 删除最后一个字符  
const deleteLast = () => {  

uni.vibrateShort({  
success: function() {  
inputValue.value = inputValue.value.slice(0, -1)  
}
})  

}  

// 转账操作  
const makeTransfer = () => {  
uni.vibrateShort({  
success: function() {  
if (inputValue.value.length >= 7 && !inputValue.value.includes('.')) {  
uni.showToast({  
title: '单笔金额超出限制',  
icon: 'error'  
})  
return  
}  
if (inputValue.value.length > 9 && inputValue.value.includes('.')) {  
uni.showToast({  
title: '单笔金额超出限制',  
icon: 'error'  
})  
return  
}  
if (+inputValue.value < 0.01) {  
uni.showToast({  
title: '金额不能小于0.01元',  
icon: 'error'  
})  
return  
}  

// uni.showToast({  
//  title: '付款成功' + inputValue.value+'元',  
//  icon: 'success'  
// })  

// 发出转账事件,并传递输入的金额给父组件  
emit('transfer', inputValue.value)  

inputValue.value = '' // 清空输入框  

}
})  

}  
</script>  

<style scoped>
.keyboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 5px;
background-color: #f8f8f8;
height: 100%;
}

button {
font-size: 20px;
border: none;
background-color: #ffffff;
color: #000000;
width: 100%;
}

button:active {
background-color: #e0e0e0;
}

.delete-btn {
background-color: #fff;
font-weight: bold;
}

.transfer-btn {
background-color: #1678ff;
color: #ffffff;
grid-row: span 3; /* 占3行 */
height: 170px;
line-height: 170px;
}

.zero-btn {
grid-column: span 2; /* 占两列 */
}
</style>

实际结果:

<template>
<view class="keyboard">
<button @click="appendValue(1)">1</button>
<button @click="appendValue(2)">2</button>
<button @click="appendValue(3)">3</button>
<button class="delete-btn" @click="deleteLast">⌫</button>  
<button @click="appendValue(4)">4</button>  
<button @click="appendValue(5)">5</button>  
<button @click="appendValue(6)">6</button>  
<button class="transfer-btn" v-if="!inputValue " disabled>付款</button>  
<button class="transfer-btn" @click="makeTransfer" v-else>付款</button>  

<button @click="appendValue(7)">7</button>  
<button @click="appendValue(8)">8</button>  
<button @click="appendValue(9)">9</button>  

<button @click="appendValue(0)" class="zero-btn">0</button>  
<button @click="appendValue('.')">.</button>  
</view>  
</template>  

<script setup>
import {
ref,
defineProps,
defineEmits,
watch
} from 'vue' // 导入 watch  

// 接收父组件传递的 modelValue 值  
const props = defineProps({  
modelValue: {  
type: String,  
default: ''  
}  
})  

const emit = defineEmits(['update:modelValue', 'transfer'])  

// 用于绑定的金额值  
const inputValue = ref(props.modelValue)  

// 监听 inputValue 的变化,更新父组件的 modelValue  
watch(inputValue, (newValue) => {  
emit('update:modelValue', newValue)  
})  

// 防抖后的appendValue函数
const appendValue = debounce((value) => {
uni.vibrateShort({
success: function() {
// 判断小数点后面是否有两位数字,如果有两位就不能再输入了
let index = inputValue.value.indexOf('.');  

// 1. 输入第一个为小数点时,返回 0.  
if (value.toString() === '.' && inputValue.value === '') {  
inputValue.value = '0.';  
return;  
}  

// 2. 输入的值为小数点且已有小数点时,不进行操作  
if (value.toString() === '.' && inputValue.value.includes('.')) {  
return;  
}  

// 3. 输入的值如果是数字并且第一个是0,且第二个不是小数点,覆盖0  
if (inputValue.value.startsWith('0') && inputValue.value.length === 1 && value !== '0' && value !== '.') {  
inputValue.value = value.toString();  
return;  
}  

// 4. 如果金额长度超过7位,则不再添加  
if (inputValue.value.length >= 7 && !inputValue.value.includes('.')) {  
return;  
}  

// 5. 当存在小数点时,限制小数点后面只能有两位  
if (inputValue.value.includes('.') && inputValue.value.length - index - 1 >= 2) {  
return;  
}  

// 6. 更新金额  
inputValue.value += value;  
}
}, 50); // 防抖延迟时间设置为50ms  

// 防抖函数,传入需要防抖的函数和延迟时间
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer); // 清除上一个定时器
timer = setTimeout(() => {
fn(...args);  // 延迟执行函数
}, delay);
};
}

// 删除最后一个字符  
const deleteLast = () => {  

uni.vibrateShort({  
success: function() {  
inputValue.value = inputValue.value.slice(0, -1)  
}
})  

}  

// 转账操作  
const makeTransfer = () => {  
uni.vibrateShort({  
success: function() {  
if (inputValue.value.length >= 7 && !inputValue.value.includes('.')) {  
uni.showToast({  
title: '单笔金额超出限制',  
icon: 'error'  
})  
return  
}  
if (inputValue.value.length > 9 && inputValue.value.includes('.')) {  
uni.showToast({  
title: '单笔金额超出限制',  
icon: 'error'  
})  
return  
}  
if (+inputValue.value < 0.01) {  
uni.showToast({  
title: '金额不能小于0.01元',  
icon: 'error'  
})  
return  
}  

// uni.showToast({  
//  title: '付款成功' + inputValue.value+'元',  
//  icon: 'success'  
// })  

// 发出转账事件,并传递输入的金额给父组件  
emit('transfer', inputValue.value)  

inputValue.value = '' // 清空输入框  

}
})  

}  
</script>  

<style scoped>
.keyboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 5px;
background-color: #f8f8f8;
height: 100%;
}

button {
font-size: 20px;
border: none;
background-color: #ffffff;
color: #000000;
width: 100%;
}

button:active {
background-color: #e0e0e0;
}

.delete-btn {
background-color: #fff;
font-weight: bold;
}

.transfer-btn {
background-color: #1678ff;
color: #ffffff;
grid-row: span 3; /* 占3行 */
height: 170px;
line-height: 170px;
}

.zero-btn {
grid-column: span 2; /* 占两列 */
}
</style>

bug描述:

ios端组件不可使用 数字区组件使用watch监听,用defineEmits函数传递参数到 index.vue,使用v-model接收 点击下方数字区组件,对应value,没有展示在付款框内


1 回复

在处理 uni-app 在 iOS 端 Vue 组件不可用的问题时,首先需要确保你的项目配置正确,并且代码遵循了 uni-app 和 Vue 的最佳实践。以下是一些可能的解决方案和代码示例,这些示例旨在帮助你诊断和解决问题。

1. 确保组件正确注册和使用

确保你的 Vue 组件已经在页面中正确注册并使用。以下是一个基本的组件注册和使用示例:

<!-- MyComponent.vue -->
<template>
  <view>Hello, I am a component!</view>
</template>

<script>
export default {
  name: 'MyComponent'
}
</script>

<!-- Index.vue -->
<template>
  <view>
    <my-component></my-component>
  </view>
</template>

<script>
import MyComponent from '@/components/MyComponent.vue';

export default {
  components: {
    MyComponent
  }
}
</script>

2. 检查条件渲染和动态组件

如果你使用了条件渲染或动态组件,请确保条件逻辑正确无误。

<template>
  <view>
    <component :is="currentComponent"></component>
  </view>
</template>

<script>
export default {
  data() {
    return {
      currentComponent: 'MyComponent'
    };
  },
  components: {
    MyComponent: () => import('@/components/MyComponent.vue')
  }
}
</script>

3. 确认样式隔离

uni-app 中,组件的样式默认是隔离的。如果组件样式没有正确应用,可能是因为样式隔离问题。尝试使用 ::v-deep 穿透组件样式隔离。

<style scoped>
::v-deep .my-class {
  color: red;
}
</style>

4. 检查平台特定代码

如果你的组件中有平台特定的代码,确保这些代码在 iOS 上也是有效的。使用 uni.getSystemInfoSync().platform 来判断平台。

if (uni.getSystemInfoSync().platform === 'ios') {
  // iOS 特定代码
}

5. 使用条件编译

如果某些功能仅在特定平台上可用,可以使用条件编译来确保代码不会在不支持的平台上执行。

<!-- #ifdef IOS -->
<ios-specific-component></ios-specific-component>
<!-- #endif -->

结论

以上是一些解决 uni-app 在 iOS 端 Vue 组件不可用的基本方法。如果问题仍然存在,建议检查控制台日志以获取更多错误信息,或者查阅 uni-app 和 Vue 的官方文档以获取更多关于平台兼容性和最佳实践的信息。

回到顶部