我在 Vue.js 应用程序上工作,其中一个组件的代码如下所示:
<template lang="pug">
div
b-container(v-if='displayRouletteControls')
b-row
b-col(:cols='1').d-flex.align-items-center.justify-content-center.cursor-pointer
img(src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='%232E86C1' class='bi bi-chevron-left' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3E%3C/svg%3E" @click='onPrevious()')
b-col(:cols='10')
b-carousel(
id='categoryRoulette'
no-animation
:interval='0'
ref='myCarousel'
)
b-carousel-slide
template(v-slot:img)
b-card-group(deck)
b-card(
v-for="(item, index) in subArrayValues" :key="index"
:img-src="item.image ? item.image : '../assets/images/blank.png'"
img-alt='Image'
img-top
tag='article'
)
b-card-text.d-flex.justify-content-center.align-items-center
h5
a(href="#") {{ item.title }}
b-col(:cols='1').d-flex.align-items-center.justify-content-center.cursor-pointer
img(src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='%232E86C1' class='bi bi-chevron-right' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E" @click='onNext()')
b-container(v-else)
b-row
b-col
b-carousel(
id='categoryRoulette'
:controls='displayRouletteControls'
no-animation
:interval='0'
)
b-carousel-slide(
v-for="category in catalog"
:key="category.permalink"
)
template(v-slot:img)
b-card(
:img-src="category.image ? category.image : '../assets/images/blank.png'"
img-alt='Image'
img-top
tag='article'
)
b-card-text.d-flex.justify-content-center.align-items-center
h5
a(href="#") {{ category.title }}
</template>
<script lang="ts">
import Vue from 'vue'
import { Category } from 'types'
import { RouletteData } from '../types/roulette'
import testData from '../data/testData.json'
function* subArrayGenerator(inputArray: Array<Category>, subArrayLength = 3) {
let prev = false
for (let i = 0; i < inputArray.length; ) {
if (prev) {
const diff = i - (subArrayLength - 3) * 2
i = diff < 0 ? inputArray.length + diff : diff
}
const subArray = []
for (let j = 0; j < subArrayLength; j++) {
subArray.push(inputArray[i])
i = i < inputArray.length - 1 ? i + 1 : 0
}
prev = (yield subArray) === false
}
}
export default Vue.extend({
data: (): RouletteData => ({
catalog: [],
displayRouletteControls: true,
subArrayIterator: {},
subArrayValues: {},
}),
mounted() {
this.$nextTick(() => {
window.addEventListener('resize', this.onResizeRoulette)
this.onResizeRoulette()
})
this.catalog = testData.catalog
this.subArrayIterator = subArrayGenerator(this.catalog)
this.subArrayValues = this.subArrayIterator.next().value
},
beforeDestroy() {
window.removeEventListener('resize', this.onResizeRoulette)
},
methods: {
onPrevious() {
this.subArrayValues = this.subArrayIterator.next(false).value
},
onNext() {
this.subArrayValues = this.subArrayIterator.next().value
},
onResizeRoulette() {
if (window.innerWidth >= 992) {
this.displayRouletteControls = true
} else {
this.displayRouletteControls = false
}
},
},
})
</script>
<style lang="sass">
.cursor-pointer
cursor: pointer
.set-top-margin
margin-top: 40px
#categoryRoulette
margin-bottom: 40px
margin-top: 40px
.carousel-control-prev-icon
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%232E86C1' class='bi bi-chevron-left' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3E%3C/svg%3E") !important
height: 100px !important
margin-left: calc(100% - 320px)
width: 100px !important
.carousel-control-next-icon
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%232E86C1' class='bi bi-chevron-right' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E") !important
height: 100px !important
margin-right: calc(100% - 320px)
width: 100px !important
</style>
代码运行良好,但在 VS Code 中 next() 方法用红线标出。
更糟糕的事情发生在 GitLab CI/CD 工作中。
我对 TypeScript 的了解不多,但假设类型存在一些问题。
该组件的界面如下所示:
import { Category } from './index'
export interface RouletteData {
catalog: Array<Category>
displayRouletteControls: boolean
subArrayIterator: {}
subArrayValues: {}
}
我该如何解决这个问题?
更新:
我已经按照您的建议进行了更改,并得到了以下内容:
Category 界面如下所示:
export interface Category {
title: string
permalink: string
hasChildren: boolean
cover: string
subcatalog?: Category[]
image: string
}
答案 0 :(得分:1)
您可以更改接口 RoutletteData
以添加有关 Next()
函数的信息。目前,它说 subArrayIterator
是一个对象,但没有指定关于它的其他类型信息。
export interface RouletteData {
catalog: Array<Category>
displayRouletteControls: boolean
subArrayIterator: {
next?(someBool?: boolean): {
value: {}
}
},
subArrayValues: {}
}
在上面,我们为 next()
属性定义了一个 subArrayIterator
函数。分解,定义如下:
next
这是函数名。
?
表示 next
是可选的 - 这允许您的 data()
保持原样,它不在 {{1} 上声明 next()
函数},它只是一个空对象。
subArrayIterator
这是 someBool?: boolean
函数的可选参数,布尔类型。 next
只是一个描述性名称,如果您知道布尔值表示什么,请给它一个更好的名称。
someBool
这是函数的返回类型。您的代码对 : { value: {} }
的结果调用 .value
,因此您希望它具有 .next()
属性。我们不知道它的类型,但因为它被分配给 value
,所以它必须与它兼容 - 我们暂时将其保留为空对象。