0


tsx零基础页面开发全流程(vue环境)

tsx零基础页面开发全流程(vue环境)

一 注册 tsx 页面

注册 tsx 页面分两步:
首先创建 tsx 页面文件index.tsx。

import{ defineComponent }from"vue";const logistTrack =defineComponent({setup(props,{ slots }){return()=><div>123</div>;},});exportdefault logistTrack;

其次将该文件注册到 router 对象上。

import{ RouteRecordRaw }from"vue-router";exportconst myOrderRoutes: RouteRecordRaw ={
  path:"/service",
  children:[{
      path:"logistTrack",
      name:"logistTrack",
      meta:{
        title:"物流跟踪",},// 注意这里的后缀为js 而不是tsxcomponent:()=>import("@/views/myOrder/logistTrack/index.js"),},],};

运行,该页面展示 123。
请添加图片描述

二 页面布局绘制

然后我们开始绘制页面,这次绘制的页面是物流追踪页面,整个页面分为上下两大块。这里我们开始引入样式。

新建样式文件。

// index.scss
.logist_track{background-color: #f6f6f6;.logist_track_title,
  .logist_track_content{margin: 18px 24px;background-color: #ffffff;border-radius: 24px;}}

在 tsx 中引入并使用样式。

// @/views/myOrder/logistTrack/index.tsximport{ 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>);},});exportdefault logistTrack;

请添加图片描述

三 注册并引入组件

我们计划将页面的上半部分划分为一个组件,接下来我们注册并引入一个组件。

新建一个组件。

import{ defineComponent }from"vue";import"./index.scss";const LogistTrackCard =defineComponent({setup(props,{ slots }){return()=><div>我是一个组件</div>;},});exportdefault LogistTrackCard;

在页面中引入并使用该组件。

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>);},});exportdefault logistTrack;

现在页面展示如下:
请添加图片描述

三 LogistTrackCard 组件绘制

接下来在组件 LogistTrackCard 内绘制静态页面。
组件整体分为两部分,下面的部分分裂为横向排列的 2 块,各占 50%,由 flex 布局而成。
这块没什么难点,直接给出。

import{ defineComponent }from"vue";import"./index.scss";import arrow_right_gray from"@/assets/icons/arrow_right.png";const LogistTrackCard =defineComponent({setup(props,{ slots }){return()=>(<div class="logist_track_card"><div class="title_group"><span class="lable">顺丰快递</span><span>SF1223333333</span></div><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></div>);},});exportdefault LogistTrackCard;
.logist_track_card{.title_group{padding: 0 24px;height: 88px;font-size: 28px;font-family: PingFangSC-Medium, PingFang SC;font-weight: 500;color: #333333;line-height: 88px;.lable{margin-right: 18px;font-family: PingFangSC-Regular, PingFang SC;font-weight: 400;color: #666666;}}.content{padding: 24px;display: flex;align-items: center;.line-splice{width: 1px;height: 58px;border: 1px solid #d8d8d8;margin-left: 24px;}.status_group{text-align: center;width: 50%;.status{font-size: 36px;font-family: PingFangSC-Medium, PingFang SC;font-weight: 500;color: #333333;line-height: 50px;margin-bottom: 14px;}.msg{height: 53px;background: #f3f3f3;border-radius: 8px;font-size: 24px;font-family: PingFangSC-Regular, PingFang SC;font-weight: 400;color: #333333;line-height: 53px;padding: 0 13px;}}.course{display: flex;align-items: center;justify-content: center;width: 50%;font-size: 30px;font-family: PingFangSC-Regular, PingFang SC;font-weight: 400;color: #333333;line-height: 42px;img{margin: 0 32px;width: 15px;}}}}

现在页面呈现如下。
请添加图片描述

我们可以美化一下,将组件的白色背景色去掉,添加背景图片。将灰色的箭头图片换为橙色图片。

.logist_track_card{background-image:url(../../../../assets/img/order/logist-track-ground.png);background-size: cover;
    ...
}

请添加图片描述

四 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);}}

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-1212:40</p></van-step><van-step><h3>【城市】物流状态2</h3><p>2016-07-1110:00</p></van-step><van-step><h3>快件已发货</h3><p>2016-07-1009:30</p></van-step></van-steps></div>)}})exportdefault LogistTrackStep
import{ defineComponent }from'vue'import LogistTrackCard from'../components/LogistTrackCard/index'import LogistTrackStep from'../components/LogistTrackStep/index'import'./index.scss'const logistTrack =defineComponent({setup(props,{ slots }){return()=>(<BasePage class="logist_track" pageTitle="物流跟踪"><div class="logist_track_title"><LogistTrackCard></LogistTrackCard></div><div class="logist_track_content"><LogistTrackStep></LogistTrackStep></div></BasePage>)}})exportdefault logistTrack

请添加图片描述

3 优化step样式

我们可以新写一些样式,通过deep我们可以在使用vant公共样式的基础上有自己的特色。
我们为LogistTrackStep组件新建一个scss文件。(记得在组件内引入)

.logist_track_step{.van-step--vertical.van-step--process:first-child .van-step__line{border: 1px dashed #FFA800;height:calc(100% - 30px);top: 50px;left: -31px
    }.van-step__line{height:calc(100% - 30px);background-color: transparent;border: 1px dashed #E0E0E0;top: 50px;left: -31px;}.van-step--vertical .van-step__circle-container .van-step__circle{width: 16px;height: 16px;background-color: #E0E0E0;}}

请添加图片描述

接下来,我们修改一下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-0906:00:00</div><p class="msg">快件到达(上海市XX区) 完成分,准备配送</p></van-step><van-step><div class="time">2023-09-0906:00:00</div><p class="msg">快件到达(上海市XX区) 完成分,准备配送</p></van-step><van-step><div class="time">2023-09-0906:00:00</div><p class="msg">快件到达(上海市XX区) 完成分,准备配送</p></van-step></van-steps></div>)}})exportdefault LogistTrackStep
.logist_track_step{......
    .status{font-size: 30px;font-family: PingFangSC-Medium, PingFang SC;font-weight: 500;color: #333333;line-height: 42px;margin-bottom: 14px;}.time{font-size: 26px;font-family: PingFangSC-Regular, PingFang SC;font-weight: 400;color: #333333;line-height: 37px;margin-bottom: 12px;}.msg{font-size: 24px;font-family: PingFangSC-Regular, PingFang SC;font-weight: 400;color: #666666;line-height: 33px;}}

现在,静态页面已经绘制完成了,接下来是添加动态数据。
请添加图片描述

五 动态数据接驳

动态数据从哪来呢?一般是通过接口请求得到。
这里我们先用一个变量模拟,通过接口请求得到后将数据放到变量上即可。

建立变量,里面有我们所需要的数据,然后我们将数据传入对应组件中。传入的方式还是有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>)}})exportdefault logistTrack

接下来我们在两个组件中引入对应的props变量,引入方式与vue文件相同,使用变量还是使用单大括号阔起。
引入变量:

...const LogistTrackCard =defineComponent({
  props:{
    expName:{
      type: String,default:''},number:{
      type: String,default:''},},setup(props,{ slots }){...})exportdefault LogistTrackCard

使用变量:

...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>)}})exportdefault LogistTrackCard

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,},},...})exportdefault LogistTrackStep

此时我们可以在页面中使用变量了,但是我们发现有两个问题:
1 logistTrackStepList是一个列表,我们需要循环展示,对应在vue组件中就是v-for属性,但是tsx中又有所不同。
2 deliverystatus是一个数字,我们需要展示对应的文字。

首先解决第一个问题,在tsx中我们可以通过{}包裹,在其中书写表达式,可以是一个函数执行语句,也可以是一个普通的表达式。
v-for不能使用,我们可以通过在{}中执行函数执行语句的方式,执行props.logistTrackStepList.map方法,让其根据列表项的值返回对应的尖括号语句。

// ...const LogistTrackStep =defineComponent({// ...setup(props,{ slots }){// ...return()=>(<div class="logist_track_step"><van-steps direction="vertical" active={0} active-color="#FFB24D">{props.logistTrackStepList.map((item, i)=>(<van-step>{ i?'':<div class="status">配送中</div>}<div class="time">{item.time}</div><p class="msg">{item.status}</p></van-step>))}</van-steps></div>)}})exportdefault LogistTrackStep

接下来解决第二个问题,我们新建一个对象,将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 askeyoftypeof deliverystatusObj)]}</div>}// ...)}})exportdefault LogistTrackStep

上面通过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 }){// ...constLogistTrackCardSlot=()=>{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>)}})exportdefault logistTrack

在子组件中使用插槽也很简单,使用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>)}})exportdefault LogistTrackCard

插槽准备完毕后我们可以修改一下样式,让其在插槽存在于不存在的时候展示不同的样式。

5.4 tsx | 动态类

使用动态类即可(与vue不同)。

<div class={['logist_track_card',{simple: slots.default}]}>

当slots.default也就是默认插槽存在时,simple类存在。

六 效果展示

现在我们的页面已经开发完毕了,页面有两种状态,有插槽状态和没有插槽状态。

有插槽状态:
请添加图片描述
没有插槽状态:
请添加图片描述

标签: 前端 tsx jsx

本文转载自: https://blog.csdn.net/weixin_45809580/article/details/130082939
版权归原作者 前端呆头鹅 所有, 如有侵权,请联系我们删除。

“tsx零基础页面开发全流程(vue环境)”的评论:

还没有评论