提交 4acfe5e6 编写于 作者: DCloud-WZF's avatar DCloud-WZF 💬

refactor(directive): v-for

上级 e6488b1f
...@@ -171,6 +171,18 @@ ...@@ -171,6 +171,18 @@
"navigationBarTitleText": "v-if 组合式 API" "navigationBarTitleText": "v-if 组合式 API"
} }
}, },
{
"path": "pages/directive/v-for/v-for-options",
"style": {
"navigationBarTitleText": "v-for 选项式 API"
}
},
{
"path": "pages/directive/v-for/v-for-composition",
"style": {
"navigationBarTitleText": "v-for 组合式 API"
}
},
{ {
"path": "pages/directive/v-bind/v-bind", "path": "pages/directive/v-bind/v-bind",
...@@ -228,36 +240,6 @@ ...@@ -228,36 +240,6 @@
} }
}, },
// #endif // #endif
{
"path": "pages/directive/v-for/v-for",
"style": {
"navigationBarTitleText": "v-for"
}
},
{
"path": "pages/directive/v-for/v-for-item-click",
"style": {
"navigationBarTitleText": "v-for-item-click"
}
},
{
"path": "pages/directive/v-for/v-for-item-v-if",
"style": {
"navigationBarTitleText": "v-for-item-v-if"
}
},
{
"path": "pages/directive/v-for/v-for-item-v-show",
"style": {
"navigationBarTitleText": "v-for-item-v-show"
}
},
{
"path": "pages/directive/v-for/v-for-v-for",
"style": {
"navigationBarTitleText": "v-for-v-for"
}
},
{ {
"path": "pages/directive/v-model/v-model", "path": "pages/directive/v-model/v-model",
"style": { "style": {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<view class="content"> <view class="content">
<child> <child>
<template v-slot:header="slotProps"> <template v-slot:header="slotProps">
<view class="header">{{ slotProps['msg'] }}</view> <view class="header">{{ slotProps.msg }}</view>
</template> </template>
<template v-slot:default="{ msg }"> <template v-slot:default="{ msg }">
<view class="main">{{ msg }}</view> <view class="main">{{ msg }}</view>
......
<template>
<!-- #ifdef APP -->
<scroll-view style="flex: 1">
<!-- #endif -->
<view class="page">
<text class="bold mb-10">v-for number</text>
<view class="mb-10" v-for="item in 3" :key="item">
<text :id="`number-${item}`">{{ item }}</text>
</view>
<view class="bold mb-10">v-for object</view>
<view
v-for="(value, key) in object"
:key="key"
class="mb-10 flex justify-between flex-row">
<text :id="key">{{ key }}</text>
<text :id="value">{{ value }}</text>
</view>
<view class="bold mb-10">v-for & v-if list items</view>
<view id="v-for-v-if-list-items" v-for="item in listItems" :key="item.name">
<template v-if="item.show">
<view class="mb-10 flex justify-between flex-row">
<text :id="item.name">{{ item.name }}</text>
<text @click="item.count++" :id="`v-if-${item.name}-count`">{{
item.count
}}</text>
</view>
<template v-for="child in item.items">
<view
v-if="child.show"
:key="child.name"
class="mb-10 flex justify-between flex-row">
<text :id="child.name">{{ child.name }}</text>
<text @click="child.count++" :id="`v-if-${child.name}-count`">{{
child.count
}}</text>
</view>
</template>
</template>
</view>
<view class="bold mb-10">v-for & v-show list items</view>
<view
id="v-for-v-if-list-items"
v-for="item in listItems"
:key="item.name"
v-show="item.show">
<view class="mb-10 flex justify-between flex-row">
<text :id="item.name">{{ item.name }}</text>
<text @click="item.count++" :id="`v-show-${item.name}-count`">{{
item.count
}}</text>
</view>
<view
v-for="child in item.items"
v-show="child.show"
:key="child.name"
class="mb-10 flex justify-between flex-row">
<text :id="child.name">{{ child.name }}</text>
<text @click="child.count++" :id="`v-show-${child.name}-count`">{{
child.count
}}</text>
</view>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script setup lang="uts">
type VForObject = {
key1 : string
key2 : string
key3 : string
}
type ListItem = {
name: string
count : number
show: boolean
items?: ListItem[]
}
const object = reactive({ key1: 'value1', key2: 'value2', key3: 'value3' } as VForObject)
const listItems = ref([
{ name: '1',
count: 0,
show: true,
items:[
{ name: '1-1', count: 0, show: false },
{ name: '1-2', count: 0, show: true },
]
},
{ name: '2',
count: 0,
show: true,
items:[
{ name: '2-1', count: 0, show: true },
{ name: '2-2', count: 0, show: false },
]
},
{ name: '3',
count: 0,
show: false,
items:[
{ name: '3-1', count: 0, show: true },
{ name: '3-2', count: 0, show: true },
]
},
] as ListItem[])
</script>
const PAGE_PATH = '/pages/directive/v-for/v-for-item-click'
describe('v-for-item-click', () => {
let page
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
await page.waitFor(500)
})
it('list-item-click-count1', async () => {
await clickItem(page, 1)
})
it('list-item-click-count2', async () => {
await clickItem(page, 2)
})
it('list-item-click-count3', async () => {
await clickItem(page, 3)
})
it('list-item-click-count4', async () => {
await clickItem(page, 4)
})
it('list-item-click-count5', async () => {
await clickItem(page, 5)
})
})
async function clickItem(page, count) {
// click
const items = await page.$$('.list-item')
for (let i = 0; i < items.length; i++) {
const item = items[i]
await item.tap()
}
await page.waitFor(50)
// text count
const items_count = await page.$$('.list-item-text-count')
for (let i = 0; i < items_count.length; i++) {
const item = items_count[i]
expect(await item.text()).toBe(count + '')
}
}
<template>
<view class="page">
<view class="split-title">list item click</view>
<view v-for="item in items">
<view class="list-item" @click="onItemClick(item)">
<text class="list-item-text">{{item.text}}</text>
<text class="list-item-text-count">{{item.count}}</text>
</view>
</view>
</view>
</template>
<script>
type ListItem = {
text : string,
count : number
}
export default {
data() {
return {
items: [
{ text: 'List.Item1 Count: ', count: 0 },
{ text: 'List.Item2 Count: ', count: 0 },
{ text: 'List.Item3 Count: ', count: 0 },
{ text: 'List.Item4 Count: ', count: 0 },
{ text: 'List.Item5 Count: ', count: 0 },
{ text: 'List.Item6 Count: ', count: 0 },
{ text: 'List.Item7 Count: ', count: 0 },
{ text: 'List.Item8 Count: ', count: 0 },
] as ListItem[],
}
},
methods: {
onItemClick(e : ListItem) {
e.count++;
}
}
}
</script>
<style>
</style>
\ No newline at end of file
const PAGE_PATH = '/pages/directive/v-for/v-for-item-v-if'
describe('v-for-item-v-if', () => {
let page
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
await page.waitFor(500)
})
it('list-item-click', async () => {
// click
const items = await page.$$('.list-item')
for (let i = 0; i < items.length; i++) {
const item = items[i]
await item.tap()
}
await page.waitFor(100)
const elements = await page.$$('.list-item-text-show')
expect(elements.length).toBe(1)
})
})
\ No newline at end of file
<template>
<view class="page">
<view class="split-title">list item v-if</view>
<template v-for="item in items">
<view class="list-item" @click="onItemClick(item)">
<text class="list-item-text">{{ item.text }}:</text>
<text class="list-item-text-show" v-if="item.show">{{ item.show }}</text>
</view>
</template>
</view>
</template>
<script>
type ListItem = {
text : string,
show : boolean
}
export default {
data() {
return {
items: [
{ text: 'List.Item1 v-if: ', show: true },
{ text: 'List.Item2 v-if: ', show: false },
{ text: 'List.Item3 v-if: ', show: true },
] as ListItem[],
}
},
methods: {
onItemClick(e : ListItem) {
e.show = !e.show;
}
}
}
</script>
<style>
</style>
\ No newline at end of file
const PAGE_PATH = '/pages/directive/v-for/v-for-item-v-show'
describe('v-for-item-v-show', () => {
let page
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
await page.waitFor(500)
})
it('list-item-click', async () => {
// click
const items = await page.$$('.list-item')
for (let i = 0; i < items.length; i++) {
const item = items[i]
await item.tap()
}
await page.waitFor(100)
// math element count
const elements = await page.$$('.list-item-text-show')
expect(elements.length).toBe(items.length)
})
})
\ No newline at end of file
<template>
<view class="page">
<view class="split-title">list item v-show</view>
<view v-for="item in items">
<view class="list-item" @click="onItemClick(item)">
<text class="list-item-text">{{ item.text }}:</text>
<text class="list-item-text-show" v-show="item.show">{{ item.show }}</text>
</view>
</view>
</view>
</template>
<script>
type ListItem = {
text : string,
show : boolean
}
export default {
data() {
return {
items: [
{ text: 'List.Item1 v-show: ', show: true },
{ text: 'List.Item2 v-show: ', show: false },
{ text: 'List.Item3 v-show: ', show: true },
] as ListItem[],
}
},
methods: {
onItemClick(e : ListItem) {
e.show = !e.show;
}
}
}
</script>
<style>
</style>
\ No newline at end of file
<template>
<!-- #ifdef APP -->
<scroll-view style="flex: 1">
<!-- #endif -->
<view class="page">
<text class="bold mb-10">v-for number</text>
<view class="mb-10" v-for="item in 3" :key="item">
<text :id="`number-${item}`">{{ item }}</text>
</view>
<view class="bold mb-10">v-for object</view>
<view
v-for="(value, key) in object"
:key="key"
class="mb-10 flex justify-between flex-row">
<text :id="key">{{ key }}</text>
<text :id="value">{{ value }}</text>
</view>
<view class="bold mb-10">v-for & v-if list items</view>
<view
id="v-for-v-if-list-items"
v-for="item in listItems"
:key="item.name">
<template v-if="item.show">
<view class="mb-10 flex justify-between flex-row">
<text :id="item.name">{{ item.name }}</text>
<text @click="item.count++" :id="`v-if-${item.name}-count`">{{
item.count
}}</text>
</view>
<template v-for="child in item.items">
<view
v-if="child.show"
:key="child.name"
class="mb-10 flex justify-between flex-row">
<text :id="child.name">{{ child.name }}</text>
<text @click="child.count++" :id="`v-if-${child.name}-count`">{{
child.count
}}</text>
</view>
</template>
</template>
</view>
<view class="bold mb-10">v-for & v-show list items</view>
<view
id="v-for-v-show-list-items"
v-for="item in listItems"
v-show="item.show"
:key="item.name">
<view class="mb-10 flex justify-between flex-row">
<text :id="item.name">{{ item.name }}</text>
<text @click="item.count++" :id="`v-show-${item.name}-count`">{{
item.count
}}</text>
</view>
<view
v-for="child in item.items"
v-show="child.show"
:key="child.name"
class="mb-10 flex justify-between flex-row">
<text :id="child.name">{{ child.name }}</text>
<text @click="child.count++" :id="`v-show-${child.name}-count`">{{
child.count
}}</text>
</view>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script lang="uts">
type VForObject = {
key1 : string
key2 : string
key3 : string
}
type ListItem = {
name: string
count : number
show: boolean
items?: ListItem[]
}
export default {
data() {
return {
object: { key1: 'value1', key2: 'value2', key3: 'value3' } as VForObject,
listItems: [
{ name: '1',
count: 0,
show: true,
items:[
{ name: '1-1', count: 0, show: false },
{ name: '1-2', count: 0, show: true },
]
},
{ name: '2',
count: 0,
show: true,
items:[
{ name: '2-1', count: 0, show: true },
{ name: '2-2', count: 0, show: false },
]
},
{ name: '3',
count: 0,
show: false,
items:[
{ name: '3-1', count: 0, show: true },
{ name: '3-2', count: 0, show: true },
]
},
] as ListItem[],
}
}
}
</script>
const PAGE_PATH = '/pages/directive/v-for/v-for-v-for'
describe('v-for-v-for', () => {
let page
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
await page.waitFor(500)
})
it('item1.item1', async () => {
const item_item = await page.$('.list-item-item')
expect(await item_item.text()).toBe('item1.item1')
})
})
<template>
<view class="page">
<view class="split-title">list items</view>
<view v-for="item in items">
<view class="list-item">{{ item.text }}</view>
<view v-for="item2 in item.items">
<view class="list-item-item">{{ item2.text }}</view>
</view>
</view>
</view>
</template>
<script>
type ListItem = {
text : string,
items : ListItem[]
}
export default {
data() {
return {
items: [
{
text: 'item1',
items: [
{
text: 'item1.item1',
items: [] as ListItem[]
},
] as ListItem[]
},
] as ListItem[],
}
}
}
</script>
<style>
</style>
\ No newline at end of file
const PAGE_PATH = '/pages/directive/v-for/v-for' const OPTIONS_PAGE_PATH = '/pages/directive/v-for/v-for-options'
const COMPOSITION_PAGE_PATH = '/pages/directive/v-for/v-for-composition'
describe('v-for', () => { describe('v-for', () => {
let page let page
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH) const test = async (page) => {
// v-for number
const num1 = await page.$('#number-1')
expect(await num1.text()).toBe('1')
const num2 = await page.$('#number-2')
expect(await num2.text()).toBe('2')
const num3 = await page.$('#number-3')
expect(await num3.text()).toBe('3')
// v-for object
const value1 = await page.$('#value1')
expect(await value1.text()).toBe('value1')
const value2 = await page.$('#value2')
expect(await value2.text()).toBe('value2')
const value3 = await page.$('#value3')
expect(await value3.text()).toBe('value3')
const vIf1Count = await page.$('#v-if-1-count')
expect(await vIf1Count.text()).toBe('0')
await vIf1Count.tap()
expect(await vIf1Count.text()).toBe('1')
const vShow1Count = await page.$('#v-show-1-count')
expect(await vShow1Count.text()).toBe('1')
await vShow1Count.tap()
expect(await vShow1Count.text()).toBe('2')
await page.waitFor(500) await page.waitFor(500)
const image = await program.screenshot({
fullPage: true
});
expect(image).toSaveImageSnapshot();
}
it('v-for options API', async () => {
page = await program.reLaunch(OPTIONS_PAGE_PATH)
await page.waitFor('view')
await page.waitFor(500)
await test(page)
}) })
it('list-items-3', async () => {
const length = 3; it('v-for composition API', async () => {
const elements = await page.$$('.list-item') page = await program.reLaunch(COMPOSITION_PAGE_PATH)
expect(elements.length).toBe(length) await page.waitFor('view')
await page.waitFor(500)
await test(page)
}) })
}) })
<template>
<view class="page">
<view class="split-title">list items</view>
<view v-for="item in items">
<view class="list-item">{{ item.text }}</view>
</view>
<view class="split-title">number</view>
<view v-for="(_, index) in 8" :key="index">
<view class="map-number-1">{{ index }}</view>
</view>
<view class="split-title">object</view>
<view v-for="(value, key) in object">
key: {{ key }} value: {{ value }}
</view>
</view>
</template>
<script>
type ListItem = {
text : string
}
type MyObject = {
key1 : string
key2 : string
key3 : string
}
export default {
data() {
return {
items: [{ text: 'Foo1' }, { text: 'Foo2' }, { text: 'Foo3' }] as ListItem[],
object: { key1: 'Foo1', key2: 'Foo2', key3: 'Foo3' } as MyObject
}
}
}
</script>
<style>
</style>
\ No newline at end of file
...@@ -682,6 +682,22 @@ export default { ...@@ -682,6 +682,22 @@ export default {
url: 'v-if-composition' url: 'v-if-composition'
}, },
] ]
},
{
id: 'v-for',
name: 'v-for',
children: [
{
id: 'v-for-options',
name: 'v-for 选项式 API',
url: 'v-for-options'
},
{
id: 'v-for-composition',
name: 'v-for 组合式 API',
url: 'v-for-composition'
},
]
} }
] ]
}, },
......
...@@ -155,8 +155,8 @@ function transform(fileInfo, api) { ...@@ -155,8 +155,8 @@ function transform(fileInfo, api) {
- [x] v-html - [x] v-html
- [x] v-show - [x] v-show
- [ ] v-if v-else-if v-else - [x] v-if v-else-if v-else
- [ ] v-for - [x] v-for
- [ ] v-on - [ ] v-on
- [ ] v-bind - [ ] v-bind
- [ ] v-model - [ ] v-model
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册