提交 c107ce70 编写于 作者: crlfe's avatar crlfe 😲

增加组件实例示例

上级 97155cf5
......@@ -100,4 +100,4 @@ export default {
padding: 5px 0;
border-bottom: 1px solid #dfdfdf;
}
</style>
\ No newline at end of file
</style>
......@@ -57,6 +57,84 @@
"style": {
"navigationBarTitleText": "page-lifecycle"
}
},
{
"path": "pages/component-instance/data/data",
"style": {
"navigationBarTitleText": "$data"
}
},
{
"path": "pages/component-instance/props/props",
"style": {
"navigationBarTitleText": "$props"
}
},
{
"path": "pages/component-instance/el/el",
"style": {
"navigationBarTitleText": "$el"
}
},
{
"path": "pages/component-instance/options/options",
"style": {
"navigationBarTitleText": "$options"
}
},
{
"path": "pages/component-instance/parent/parent",
"style": {
"navigationBarTitleText": "$parent"
}
},
{
"path": "pages/component-instance/root/root",
"style": {
"navigationBarTitleText": "$root"
}
},
{
"path": "pages/component-instance/slots/slots",
"style": {
"navigationBarTitleText": "$slots"
}
},
{
"path": "pages/component-instance/refs/refs",
"style": {
"navigationBarTitleText": "$refs"
}
},
{
"path": "pages/component-instance/attrs/attrs",
"style": {
"navigationBarTitleText": "$attrs"
}
},
{
"path": "pages/component-instance/watch-function/watch-function",
"style": {
"navigationBarTitleText": "$watch()"
}
},
{
"path": "pages/component-instance/emit-function/emit-function",
"style": {
"navigationBarTitleText": "$emit()"
}
},
{
"path": "pages/component-instance/forceUpdate-function/forceUpdate-function",
"style": {
"navigationBarTitleText": "$forceUpdate()"
}
},
{
"path": "pages/component-instance/nextTick-function/nextTick-function",
"style": {
"navigationBarTitleText": "$nextTick()"
}
}
],
"globalStyle": {
......@@ -82,4 +160,4 @@
"query": "" //启动参数,在页面的onLoad函数里面得到
}]
}
}
\ No newline at end of file
}
const PAGE_PATH = '/pages/component-instance/attrs/attrs'
describe('$props', () => {
})
<template>
<view class="page">
<child
class="child-class"
style="color: red;"
id="child-id"
data-id="data-id"
val="val"
@result="() => {}"
name="child"
></child>
</view>
</template>
<script lang="ts">
import child from './child.uvue'
export default {
components: {
child
}
}
</script>
<style>
.page {
font-size: 16px;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 10px;
}
</style>
<template>
<view>
<view class="row">
<text>hasPropsAttrs</text>
<text>{{ hasPropsAttrs }}</text>
</view>
<view class="row">
<text>hasEmitsAttr</text>
<text>{{ hasEmitsAttr }}</text>
</view>
<view class="row">
<text>hasAttrs</text>
<text>{{ hasAttrs }}</text>
</view>
</view>
</template>
<script lang="ts">
export default {
emits: ['result'],
props: {
val: {
type: String,
default: "default value"
}
},
computed: {
hasPropsAttrs (): boolean {
return this.$attrs.has('val')
},
hasEmitsAttr (): boolean {
return this.$attrs.has('result')
},
hasAttrs (): boolean {
return this.$attrs.has('class')
}
}
}
</script>
<style scoped>
</style>
const PAGE_PATH = '/pages/component-instance/data/data'
describe('$data', () => {
let page
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
await page.waitFor(500)
})
it('should data.val === 2', async () => {
const plusButton = await page.$('.plus')
await plusButton.tap()
const val = await page.$('.val')
expect(await val.text()).toBe('2')
});
it('should data.val === 1', async () => {
const minusButton = await page.$('.minus')
await minusButton.tap()
const val = await page.$('.val')
expect(await val.text()).toBe('1')
})
})
<template>
<view class="page">
<view class="row">初始值: <text>1</text></view>
<view class="row">data.val: <text class="val">{{val}}</text></view>
<view class="row">data._val: <text class="_val">{{_val}}</text></view>
<view class="row">data.$val: <text class="$val">{{$val}}</text></view>
<view class="buttons">
<button class="btn plus" @click="click(1)">增加</button>
<button class="btn minus" @click="click(-1)">减少</button>
</view>
</view>
</template>
<script lang="ts">
export default {
data () {
return {
val: 1,
_val: 1,
$val: 1
}
},
methods: {
click (num: number) {
this.val += num
this._val += num
this.$val += num
}
}
}
</script>
<style>
.page {
font-size: 16px;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 10px;
}
.buttons {
display: flex;
flex-direction: row;
margin-top: 10px;
}
.btn {
flex: 1;
margin: 0 5px;
}
</style>
const PAGE_PATH = '/pages/component-instance/props/props'
describe('$props', () => {
})
<template>
<view class="page">
<text class="child">root node tagName:</text>
<text class="tag-name">{{el}}</text>
</view>
</template>
<script lang="ts">
export default {
data () {
return {
el: ''
}
},
mounted () {
this.el = this.$el?.nodeName ?? "unknown"
}
}
</script>
<style>
.page {
font-size: 16px;
display: flex;
flex-direction: row;
justify-content: space-between;
}
</style>
<template>
<view>
<button @click="click">调用父组件事件</button>
</view>
</template>
<script lang="ts">
export default {
emits: ['callback'],
methods: {
click () {
this.$emit('callback', 'string', `${Date.now()}`)
}
}
}
</script>
<style scoped>
</style>
const PAGE_PATH = '/pages/component-instance/props/props'
describe('$props', () => {
})
<template>
<view class="page">
<view class="row">
<text>子组件传的参数</text>
<text>
{{ value }}
</text>
</view>
<child @callback="callback"></child>
</view>
</template>
<script lang="ts">
import child from './child.uvue'
export default {
components: {
child
},
data () {
return {
value: [] as string[]
}
},
methods: {
callback (str: string, str1: string) {
this.value = [str, str1]
}
}
}
</script>
<style>
.page {
font-size: 16px;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 10px;
}
</style>
const PAGE_PATH = '/pages/component-instance/props/props'
describe('$props', () => {
})
<template>
<view class="page">
<view class="row">
<text>不支持 $forceUpdate()</text>
</view>
</view>
</template>
<script lang="ts">
type Obj = {
key: string
}
export default {
data () {
return {
// obj: {} as Obj
}
},
mounted () {
// this.obj.key = 'value'
// console.log(this.$forceUpdate)
}
}
</script>
<style>
.page {
font-size: 16px;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 10px;
}
</style>
const PAGE_PATH = '/pages/component-instance/props/props'
describe('$props', () => {
})
<template>
<view class="page">
<view class="row">
<text ref="text">{{value}}</text>
</view>
</view>
</template>
<script lang="ts">
type Obj = {
key: string
}
export default {
data () {
return {
value: 0
}
}
}
</script>
<style>
.page {
font-size: 16px;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 10px;
}
</style>
export default {
data () {
return {
type: 'minix'
}
},
methods: {
minixMethod () {
return "minixMethod"
}
}
}
const PAGE_PATH = '/pages/component-instance/props/props'
describe('$props', () => {
})
<template>
<view class="page">
<view class="row">
<text>name: </text>
<text>{{name}}</text>
</view>
</view>
</template>
<script lang="ts">
// import mixins from "./mixins";
export default {
// mixins: [mixins],
name: "$options",
customKey: "customValue",
data () {
return {
name: "",
customKey: ""
}
},
mounted () {
this.name = this.$options.name
},
methods: {
// getCustomKey (): string {
// return this.$options.customKey
// }
}
}
</script>
<style>
.page {
font-size: 16px;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 10px;
}
</style>
<template>
<view class="child">
<view>{{value}}</view>
</view>
</template>
<script lang="ts">
export default {
data () {
return {
value: "child"
}
},
mounted () {
this.value = this.$parent!.$data['value'] as string
},
methods: {
testFunction (): string {
return this.$parent!.$callMethod('testFunction') as string
}
}
}
</script>
<style scoped>
</style>
const PAGE_PATH = '/pages/component-instance/props/props'
describe('$props', () => {
})
<template>
<view class="page">
<child></child>
</view>
</template>
<script lang="ts">
import child from './child.uvue'
export default {
components: {
child
},
data () {
return {
value: "parent"
}
},
methods: {
testFunction (): string {
return "parentFunctionResult"
}
}
}
</script>
<style>
.page {
font-size: 16px;
display: flex;
flex-direction: row;
justify-content: space-between;
}
</style>
<template>
<view class="component">
<view class="row">
<text>string: </text><text>{{str}}</text>
</view>
<view class="row">
<text>num: </text><text>{{num}}</text>
</view>
<view class="row">
<text>bool: </text><text>{{bool}}</text>
</view>
<!-- <view class="row">-->
<!-- <text>arr: </text>-->
<!-- [<text v-for="text in arr">{{text}},</text>]-->
<!-- </view>-->
<!-- <view class="row">-->
<!-- <text>obj.key: </text><text>{{obj.key}}</text>-->
<!-- </view>-->
<!-- <view class="row">-->
<!-- <text>obj.key: </text><text>{{obj.key}}</text>-->
<!-- </view>-->
<!-- <view class="row">-->
<!-- <text>date timestamp: </text><text>{{date.now()}}</text>-->
<!-- </view>-->
<!-- <view class="row">-->
<!-- <text>function result: </text><text>{{func()}}</text>-->
<!-- </view>-->
<!-- <view class="row">-->
<!-- <text>symbol: </text><text>{{symbol}}</text>-->
<!-- </view>-->
</view>
</template>
<script lang="ts">
type IProps = {
str: string
}
export default {
props: {
str: {
type: String,
default: 'default value'
},
num: {
type: Number,
default: 0
},
bool: {
type: Boolean,
default: false
},
// arr: {
// type: Array,
// default: (): Array<string> => {
// return []
// }
// },
// obj: {
// type: Object,
// default: () => {
// return {}
// }
// },
// date: {
// type: Date,
// default: () => {
// return new Date()
// }
// },
// func: {
// type: Function,
// default: () => {
// return () => {}
// }
// },
// symbol: {
// type: Symbol,
// default: Symbol('default')
// },
}
}
</script>
<style scoped>
</style>
const PAGE_PATH = '/pages/component-instance/props/props'
describe('$props', () => {
})
<template>
<view class="page">
<check-type
str="abcd"
:num="12345"
:bool="true"
></check-type>
<!-- <view>简易类型</view>-->
<!-- <simple-->
<!-- str="abcd"-->
<!-- :num="12345"-->
<!-- :bool="true"-->
<!-- ></simple>-->
</view>
</template>
<script lang="ts">
import checkType from "./check-type.uvue";
// import simple from "./simple.uvue";
export default {
components: {
checkType,
// simple
}
}
</script>
<style>
.page {
font-size: 16px;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 10px;
}
.buttons {
display: flex;
flex-direction: row;
margin-top: 10px;
}
.btn {
flex: 1;
margin: 0 5px;
}
</style>
<template>
<view class="component">
<view class="row">
<text>string: </text><text>{{str}}</text>
</view>
<view class="row">
<text>num: </text><text>{{num}}</text>
</view>
<view class="row">
<text>bool: </text><text>{{bool}}</text>
</view>
<!-- <view class="row">-->
<!-- <text>arr: </text>-->
<!-- [<text v-for="text in arr">{{text}},</text>]-->
<!-- </view>-->
<!-- <view class="row">-->
<!-- <text>obj.key: </text><text>{{obj.key}}</text>-->
<!-- </view>-->
<!-- <view class="row">-->
<!-- <text>obj.key: </text><text>{{obj.key}}</text>-->
<!-- </view>-->
<!-- <view class="row">-->
<!-- <text>date timestamp: </text><text>{{date.now()}}</text>-->
<!-- </view>-->
<!-- <view class="row">-->
<!-- <text>function result: </text><text>{{func()}}</text>-->
<!-- </view>-->
<!-- <view class="row">-->
<!-- <text>symbol: </text><text>{{symbol}}</text>-->
<!-- </view>-->
</view>
</template>
<script lang="ts">
type IProps = {
str: string
}
export default {
props: ['str', 'num', 'bool'],
}
</script>
<script>
export default {
data () {
return {
value: "child value"
}
}
}
</script>
<template>
</template>
<style scoped>
</style>
const PAGE_PATH = '/pages/component-instance/props/props'
describe('$props', () => {
})
<template>
<view class="page">
<view ref="node">NodeRef</view>
<!-- <child ref="component">ComponentRef</child>-->
</view>
</template>
<script lang="ts">
// import child from './child.uvue'
export default {
// components: {
// child
// },
mounted () {
console.log(this.$refs)
}
}
</script>
<style>
.page {
font-size: 16px;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 10px;
}
</style>
const PAGE_PATH = '/pages/component-instance/props/props'
describe('$props', () => {
})
<template>
<view class="page">
<view class="row">rootIsApp: <text>{{isApp}}</text></view>
</view>
</template>
<script lang="ts">
export default {
data () {
return {
isApp: false
}
},
mounted () {
// this.isApp = this.$root.app
}
}
</script>
<style>
.page {
font-size: 16px;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 10px;
}
</style>
<template>
<view>
<slot name="header"></slot>
<slot name="footer"></slot>
</view>
</template>
<script lang="ts">
export default {
mounted () {
console.log(this.hasSlots())
},
methods: {
hasSlots (): boolean {
const header = this.$slots.get('header')
const footer = this.$slots.get('footer')
return header !== null && footer !== null
}
}
}
</script>
<style scoped>
</style>
const PAGE_PATH = '/pages/component-instance/props/props'
describe('$props', () => {
})
<template>
<view class="page">
<slot-comp>
<template v-slot:header>header</template>
<template v-slot:footer>footer</template>
</slot-comp>
</view>
</template>
<script lang="ts">
import slot from './slot.uvue'
export default {
components: {
slotComp: slot
}
}
</script>
<style>
.page {
font-size: 16px;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 10px;
}
</style>
const PAGE_PATH = '/pages/component-instance/props/props'
describe('$props', () => {
})
<template>
<view class="page">
<view class="row">
<text>初始值</text>
<text>init</text>
</view>
<view class="row">
<text>val</text>
<text>{{ val }}</text>
</view>
<view class="row">
<text>值是否变化</text>
<text>{{ changed }}</text>
</view>
</view>
</template>
<script lang="ts">
function sleep(timer: number = 1000, cb: () => void): void {
setTimeout(() => {
cb()
}, timer)
}
export default {
data() {
return {
val: "init",
changed: false,
a: 'a',
b: 'b',
// abChanged: false
}
},
mounted() {
this.createWatch()
// this.createGetterWatch()
},
methods: {
createWatch() {
this.$watch('val', () => {
this.changed = !this.changed
})
this.val = 'changed'
},
// createGetterWatch () {
// this.$watch(() => this.a + this.b, () => {
// this.abChanged = !this.abChanged
// })
//
// this.a = 'changed'
// }
}
}
</script>
<style>
.page {
font-size: 16px;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 10px;
}
</style>
......@@ -6,8 +6,8 @@
<!-- <text class="uni-panel-icon uni-icon" :class="item.open ? 'uni-panel-icon-on' : ''">{{item.open ? '&#xe581;' : '&#xe470;'}}</text> -->
</view>
<view class="uni-panel-c" v-if="item.open">
<view class="uni-navigate-item" v-for="(page,key) in item.pages" :key="key" @click="goDetailPage(page)">
<text class="uni-navigate-text">{{page}}</text>
<view class="uni-navigate-item" v-for="page in item.pages" :key="page.name" @click="goDetailPage(page)">
<text class="uni-navigate-text">{{page.name}}</text>
<!-- <text class="uni-navigate-icon uni-icon">&#xe470;</text> -->
</view>
</view>
......@@ -24,7 +24,22 @@
id : string,
name : string,
open : boolean,
pages : string[]
pages : IListPageItem[]
}
type IListPageItem = {
name: string
path: string
}
function createPageItem (parent: string | null = null): (page: string) => IListPageItem {
return function (page: string): IListPageItem {
const routeName = page.replace(/\$/g, '').replace('()', '-function')
return {
name: page,
path: parent !== null ? `/pages/${parent}/${routeName}/${routeName}`: `/pages/${routeName}/${routeName}`
} as IListPageItem
}
}
export default {
......@@ -36,8 +51,8 @@
name: '生命周期',
open: false,
pages: [
'page-lifecycle',
]
'page-lifecycle'
].map(createPageItem())
},
{
id: 'directives',
......@@ -55,7 +70,7 @@
'v-once',
// 'v-memo',
// 'v-cloak'
]
].map(createPageItem())
},
{
id: 'state',
......@@ -67,13 +82,13 @@
'computed',
'methods',
'watch'
]
].map(createPageItem('state'))
},
{
id: 'rendering',
name: '渲染选项',
open: false,
pages: ['template', 'render', 'slots']
pages: ['template', 'render', 'slots'].map(createPageItem('rendering'))
},
{
id: 'component-instance',
......@@ -93,7 +108,7 @@
'$emit()',
'$forceUpdate()',
'$nextTick()'
]
].map(createPageItem('component-instance'))
},
{
id: 'composition',
......@@ -104,7 +119,7 @@
'inject',
'mixins',
'extends'
]
].map(createPageItem('composition'))
}
] as ListItem[]
}
......@@ -145,9 +160,9 @@
// data: storageData
// })
},
goDetailPage(e : string) {
goDetailPage(e : IListPageItem) {
uni.navigateTo({
url: `/pages/${e}/${e}`
url: e.path
})
},
getLifeCycleNum(): number {
......@@ -176,4 +191,4 @@
.arrow-down {
transform: rotate(-135deg);
}
</style>
\ No newline at end of file
</style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册