tsx零基础页面开发全流程(vue环境)
后台-插件-广告管理-内容页头部广告(手机) |
tsx零基础页面开发全流程(vue环境)
- 一 注册 tsx 页面
- 二 页面布局绘制
- 三 注册并引入组件
- 三 LogistTrackCard 组件绘制
- 四 LogistTrackCard 组件绘制
- 五 动态数据接驳
- 5.1 tsx | props传递变量与使用变量
- 5.2 tsx | 表达式的灵活使用
- 5.3 tsx | 插槽使用
- 5.4 tsx | 动态类
- 六 效果展示
一 注册 tsx 页面
注册 tsx 页面分两步:
首先创建 tsx 页面文件index.tsx。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
其次将该文件注册到 router 对象上。
import { RouteRecordRaw } from "vue-router"; export const myOrderRoutes: RouteRecordRaw = { path: "/service", children: [ { path: "logistTrack", name: "logistTrack", meta: { title: "物流跟踪", }, // 注意这里的后缀为js 而不是tsx component: () => import("@/views/myOrder/logistTrack/index.js"), }, ], };- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
运行,该页面展示 123。
二 页面布局绘制
然后我们开始绘制页面,这次绘制的页面是物流追踪页面,整个页面分为上下两大块。这里我们开始引入样式。
新建样式文件。
// index.scss .logist_track { background-color: #f6f6f6; .logist_track_title, .logist_track_content { margin: 18px 24px; background-color: #ffffff; border-radius: 24px; } }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
在 tsx 中引入并使用样式。
// @/views/myOrder/logistTrack/index.tsx import { defineComponent } from "vue"; import "./index.scss"; const logistTrack = defineComponent({ setup(props, { slots }) { return () => ( <div class="logist_track" pageTitle="物流跟踪"> <div class="logist_track_title">123</div> <div class="logist_track_content">456</div> </div> ); }, }); export default logistTrack;- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
三 注册并引入组件
我们计划将页面的上半部分划分为一个组件,接下来我们注册并引入一个组件。
新建一个组件。
import { defineComponent } from "vue"; import "./index.scss"; const LogistTrackCard = defineComponent({ setup(props, { slots }) { return () => <div>我是一个组件</div>; }, }); export default LogistTrackCard;- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
在页面中引入并使用该组件。
import { defineComponent } from "vue"; import LogistTrackCard from "../components/LogistTrackCard/index"; import "./index.scss"; const logistTrack = defineComponent({ setup(props, { slots }) { return () => ( <div class="logist_track" pageTitle="物流跟踪"> <div class="logist_track_title"> <LogistTrackCard></LogistTrackCard> </div> <div class="logist_track_content">456</div> </div> ); }, }); export default logistTrack;- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
现在页面展示如下:
三 LogistTrackCard 组件绘制
接下来在组件 LogistTrackCard 内绘制静态页面。
组件整体分为两部分,下面的部分分裂为横向排列的 2 块,各占 50%,由 flex 布局而成。
这块没什么难点,直接给出。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
现在页面呈现如下。
我们可以美化一下,将组件的白色背景色去掉,添加背景图片。将灰色的箭头图片换为橙色图片。
.logist_track_card { background-image: url(../../../../assets/img/order/logist-track-ground.png); background-size: cover; ... }- 1
- 2
- 3
- 4
- 5
四 LogistTrackCard 组件绘制
我们为刚刚留出的位置元素写上内边距和高度,注册组件并写在位置元素中,超出位置元素的部分滚动展示。
这里我们可以使用vant的公共组件来实现。
vant-Steps步骤条 地址:https://vant-contrib.gitee.io/vant/#/zh-CN/steps
1 为刚刚留出的位置元素写上内边距和高度。
.logist_track { background-color: #F6F6F6; .logist_track_title, .logist_track_content { margin: 18px 24px; border-radius: 24px; } .logist_track_content { background-color: #FFFFFF; padding: 20px 18px; height: calc(100% - 314px); } }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
2 注册组件,引入组件,在组件内部使用vant-step进度条组件实现。
import { defineComponent } from 'vue' import './index.scss' const LogistTrackStep = defineComponent({ setup(props, { slots }) { return () => ( <div> <van-steps direction="vertical" active={0} active-color="#FFB24D"> <van-step> <h3>【城市】物流状态1</h3> <p>2016-07-12 12:40</p> </van-step> <van-step> <h3>【城市】物流状态2</h3> <p>2016-07-11 10:00</p> </van-step> <van-step> <h3>快件已发货</h3> <p>2016-07-10 09:30</p> </van-step> </van-steps> </div> ) } }) export default LogistTrackStep- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
3 优化step样式
我们可以新写一些样式,通过deep我们可以在使用vant公共样式的基础上有自己的特色。
我们为LogistTrackStep组件新建一个scss文件。(记得在组件内引入)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
接下来,我们修改一下LogistTrackStep组件展示内容,并添加一些样式。
import { defineComponent } from 'vue' import './index.scss' const LogistTrackStep = defineComponent({ components: {}, setup(props, { slots }) { return () => ( <div class="logist_track_step"> <van-steps direction="vertical" active={0} active-color="#FFB24D"> <van-step> <div class="status">配送中</div> <div class="time">2023-09-09 06:00:00</div> <p class="msg">快件到达 (上海市XX区) 完成分,准备配送</p> </van-step> <van-step> <div class="time">2023-09-09 06:00:00</div> <p class="msg">快件到达 (上海市XX区) 完成分,准备配送</p> </van-step> <van-step> <div class="time">2023-09-09 06:00:00</div> <p class="msg">快件到达 (上海市XX区) 完成分,准备配送</p> </van-step> </van-steps> </div> ) } }) export default LogistTrackStep- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
现在,静态页面已经绘制完成了,接下来是添加动态数据。
五 动态数据接驳
动态数据从哪来呢?一般是通过接口请求得到。
这里我们先用一个变量模拟,通过接口请求得到后将数据放到变量上即可。
建立变量,里面有我们所需要的数据,然后我们将数据传入对应组件中。传入的方式还是有props,但是tsx的props与vue文件中不同的是,不再用冒号来标志动态属性,而且使用大括号来包裹变量。
5.1 tsx | props传递变量与使用变量
... const logistTrack = defineComponent({ setup(props, { slots }) { const logistTrackData = { deliverystatus: 2, // 投递状态:0-快递收件(揽件); 1-在途中; 2-正在派件; 3-已签收 4-派送失败 5-疑难件 6-退件签收 expName: '顺丰快递', //快递公司名字 number: '运单编号', list: [{ status: '快件到达 (上海市XX区) 完成分拣,准备配送', // 事件详情 time: '2023-09-09 06:00:00', // 时间点 }, { status: '快件到达 (上海市XX区) 完成分拣,准备配送', // 事件详情 time: '2023-09-09 07:00:00', // 时间点 }, { status: '快件到达 (上海市XX区) 完成分拣,准备配送', // 事件详情 time: '2023-09-09 08:00:00', // 时间点 }] } return () => ( <BasePage class="logist_track" pageTitle="物流跟踪" > <div class="logist_track_title" > <LogistTrackCard expName={ logistTrackData.expName } number={ logistTrackData.number } ></LogistTrackCard> </div> <div class="logist_track_content" > <LogistTrackStep logistTrackStepList={ logistTrackData.list } deliverystatus={ logistTrackData.deliverystatus }></LogistTrackStep> </div> </BasePage> ) } }) export default logistTrack- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
接下来我们在两个组件中引入对应的props变量,引入方式与vue文件相同,使用变量还是使用单大括号阔起。
引入变量:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
使用变量:
... const LogistTrackCard = defineComponent({ // ... setup(props, { slots }) { return () => ( <div class="logist_track_card"> <div class="title_group"><span class="lable">{ props.expName }</span><span>{ props.number }</span></div> ... </div> ) } }) export default LogistTrackCard- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
5.2 tsx | 表达式的灵活使用
在第二个组件LogistTrackStep中,我们照常引入变量。
... const LogistTrackStep = defineComponent({ props: { logistTrackStepList: { type: Array<{ time: String, status: String }>, default: () => [] }, // 投递状态:0-快递收件(揽件); 1-在途中; 2-正在派件; 3-已签收 4-派送失败 5-疑难件 6-退件签收 deliverystatus: { type: Number, default: 0, }, }, ... }) export default LogistTrackStep- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
此时我们可以在页面中使用变量了,但是我们发现有两个问题:
1 logistTrackStepList是一个列表,我们需要循环展示,对应在vue组件中就是v-for属性,但是tsx中又有所不同。
2 deliverystatus是一个数字,我们需要展示对应的文字。
首先解决第一个问题,在tsx中我们可以通过{}包裹,在其中书写表达式,可以是一个函数执行语句,也可以是一个普通的表达式。
v-for不能使用,我们可以通过在{}中执行函数执行语句的方式,执行props.logistTrackStepList.map方法,让其根据列表项的值返回对应的尖括号语句。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
接下来解决第二个问题,我们新建一个对象,将deliverystatus的每一项与对应的字符串对应起来,根据deliverystatus的值取对应的项展示。
// ... const LogistTrackStep = defineComponent({ // ... setup(props, { slots }) { const deliverystatusObj = { 0: '快递收件(揽件)', 1: '在途中', 2: '正在派件', 3: '已签收', 4: '派送失败', 5: '疑难件', 6: '退件签收', } return () => ( // ... { i? '': <div class="status">{deliverystatusObj[(props.deliverystatus as keyof typeof deliverystatusObj)]}</div> } // ... ) } }) export default LogistTrackStep- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
上面通过deliverystatusObj[(props.deliverystatus as keyof typeof deliverystatusObj)取得对应的值,在jsx中等价于deliverystatusObj[props.deliverystatus],as keyof typeof deliverystatusObj是ts语法,是断言一个变量为一个对象的键类型的一种形式。
另外可以看到,这行还写了一个条件表达式,是为了仅在列表的最上方第一项展示物流状态。
到现在为止,物流页面已经编写完毕了,只要接上接口就好。
有同学发现,在物流页面上方的卡片中,有一部分没有接入数据。
在页面中有时会有这种情况,有的数据有时有,有时没有,可以使用插槽控制。
5.3 tsx | 插槽使用
我们将没有接入数据的部分写在组件插槽中,如果有传入,就展示当前效果,如果没有传入,就展示简单模式效果。
tsx插槽使用起来很简单,首先我们在父组件logistTrack中,向LogistTrackCard组件注入插槽。
注入插槽分为两部,首先我们将插槽对应内容写在LogistTrackCardSlot方法中返回,然后将LogistTrackCardSlot方法绑定在子组件v-slots属性上,v-slots属性对应一个对象,键为插槽名称,值为返回插槽内容的方法。
// ... const logistTrack = defineComponent({ // ... setup(props, { slots }) { // ... const LogistTrackCardSlot = () => { return ( <div class="content"> <div class="status_group"> <div class="status">配送中</div> <div class="msg">预计3月24日22:00前送达</div> </div> <div class="line-splice"></div> <div class="course"> <div>东莞</div> <img src={arrow_right_gray} alt="" /> <div>上海</div> </div> </div> ) } return () => ( <BasePage class="logist_track" pageTitle="物流跟踪" > <div class="logist_track_title" > <LogistTrackCard expName={ logistTrackData.expName } number={ logistTrackData.number } v-slots={{ default: () => LogistTrackCardSlot() }} > </LogistTrackCard> </div> <div class="logist_track_content" > <LogistTrackStep logistTrackStepList={ logistTrackData.list } deliverystatus={ logistTrackData.deliverystatus }></LogistTrackStep> </div> </BasePage> ) } }) export default logistTrack- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
在子组件中使用插槽也很简单,使用slots.default()引入即可,slots作为setup参数传入。
// ... const LogistTrackCard = defineComponent({ // ... setup(props, { slots }) { console.log(slots.default? slots.default() : '') return () => ( <div class="logist_track_card"> <div class="title_group"><span class="lable">{ props.expName }</span><span>{ props.number }</span></div> { slots.default? slots.default() : '' } </div> ) } }) export default LogistTrackCard- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
插槽准备完毕后我们可以修改一下样式,让其在插槽存在于不存在的时候展示不同的样式。
5.4 tsx | 动态类
使用动态类即可(与vue不同)。
<div class={['logist_track_card', {simple: slots.default}]}>- 1
当slots.default也就是默认插槽存在时,simple类存在。
六 效果展示
现在我们的页面已经开发完毕了,页面有两种状态,有插槽状态和没有插槽状态。
有插槽状态:
没有插槽状态:
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。
在线投稿:投稿 站长QQ:1888636
后台-插件-广告管理-内容页尾部广告(手机) |