# vite_ts
### vue+vue-router+pinia+vite+typescript+prettier+eslint+stylelint+lint-staged+commitlint+tailwindcss
### 打包工具由webpack换成vite
### node版本请使用node18及以上
## 推荐使用node版本管理工具nvm
## 使用package.json内的脚本 'npm run commit' 提交代码
## 使用package.json内的脚本 'npm run commit' 提交代码
## 全局状态存储中以 map 为前缀的state状态都是用于数据检索用的 不建议用于页面展示
## css框架使用了tailwindcss
## 标准图标库 https://www.figma.com/file/cVbg9b6kIGiFdtgEisnMBo/NEW%E7%BB%84%E4%BB%B6%E5%BA%93?type=design&node-id=26%3A2189&mode=dev
## 地图sdk https://1000my.com/mapapidoc/index.html
解决文件行尾与prettier冲突 新项目根目录下新建.gitattributes文件(详细解决方案:https://juejin.cn/post/6844904062987550733)
```shell
老项目添加需要执行以下git命令
git rm --cached -r .
git reset --hard
.gitattributes
*.js eol=lf
*.jsx eol=lf
*.json eol=lf
```
# iconfont字体图标渐变色
```html
```
```css
.iconfont {
background-clip: text;
-webkit-text-fill-color: transparent;
background-image: linear-gradient(180deg, #BB8A65 0%, #E3BA9B 100%);
}
```
# 导视开发提测流程
1. 修改项目中根目录下的`.drone.yml`找到`name: 上传zip到iot测试接口platformProgramAdd文件`配置,如下所示:
```yml
commands:
# # 自动授权
# - export projectCode="projectCode=project-inluar4ppcxvciefgb_ila"
- export name="导视包ci流程测试" # 应用名称(自行填写 必填)
- export version=$(cat .tags) # 应用版本 (无需填写)
- export sourceId="8" # 应用来源id(默认为8 即测试环境专用 保持默认即可)
- export genre="localpack" # 应用类型 本地资源包 保持默认即可 [outchain, localpack]
- export resolution="1080*1920竖屏" # 分辨率(自行填写)[1080*1920竖屏, 1920*1080横屏, 3840*2160横屏, 2160*3840竖屏]
- export package="/drone/src/target/$DRONE_REPO_NAME.$(cat .tags).zip" # zip包名称 保持默认即可
- export des=$CI_COMMIT_MESSAGE # 应用描述 保持默认即可
- python3 iot_upload.py
```
2. 修改项目中根目录下的`.tpl`文件中的**git地址**配置,如下所示:
```tpl
项目git地址:https://git.1000my.com/
项目git地址:https://git.1000my.com/project_shpuxiang/shpuxiang_daoshi_vue
```
3. 钉钉**群机器人**配置([钉钉机器人接入官方文档](https://open.dingtalk.com/document/group/custom-robot-access))
* 在项目钉钉群界面点击右上角的**群设置**按钮。
* 在群设置界面点击**智能群助手**按钮。
* 在智能群助手界面点击**添加机器人**按钮。
* 在弹出的弹窗界面中点击添加机器人右边的**小齿轮**按钮。
* 在选择添加机器人列表中选择**自定义机器人**。
* 在机器人详情界面点击**添加**按钮。
* 在添加机器人界面可以修改机器人的**头像**以及**名字**,在**安全设置**选项中选择**自定义关键字**,并添加**地址**关键字,勾选**我已阅读并同意《自定义机器人服务及免责条款**》,然后点击**完成**按钮。
* 完成创建后会自动生成机器人的**Webhook**地址,例如:`https://oapi.dingtalk.com/robot/send?access_token=XXXXXX`。复制地址中的`access_token=`后面的值,修改项目中根目录下的`.drone.yml`文件中的**钉钉机器人token**配置,如下所示:
```yml
# 钉钉通知
- name: dingTalk notification
pull: if-not-exists
image: lddsb/drone-dingtalk-message
failure: ignore
settings:
token: 5f1337cd8cb70e007d2693f70a3ca89fdec543781a9a9fe2f5519e061a1820a8
```
4. 项目提测步骤:
* 通过`npm run commit`命令提交本地代码。
* `git push `提交代码到项目远端dev分支
* 在远端仓库合并`dev`分支到`test`分支
6. Vue3常用工具库函数[VueUse](https://vueuse.org/)
7. 开发 及内置组件使用说明见以下文档
8. 所有需要写在App.vue内的组件请放到PublicComponent组件
10. 地图SDK地址:https://1000my.com/mapapidoc/index.html
11. **所有跳到导航页面之前请先调用 @/utils/Class/Brand.ts 来生成一个新的shop数据 以更新store内的shop数据 (本身操作是店铺除外)看以下demo**
12. ```typescript
function nav(activity: Activity) {
return new Promise((resolve, reject) => {
if (activity.shopCode?.length) {
const shop = mapShopListByCode.value[activity.shopCode]?.[0]
if (shop) {
resolve(shop)
} else {
reject('Unable to match store')
}
return
}
if (activity.point?.length) {
const { title, point, fileUrl, titleEn } = activity
const [buildingOrder, floorOrder, yaxis] = splitStringToArray(point)
const navBuildingInfo = buildingList.value.find(item => item.buildingOrder === buildingOrder)
const shop = new Brand({
shopName: title,
shopNameEn: titleEn,
floorOrder,
floor: navBuildingInfo?.floorList?.find(item => item.floorOrder === floorOrder)?.floor ?? '',
logoUrl: fileUrl[0],
yaxis,
buildingOrder,
building: navBuildingInfo?.building
})
resolve(shop)
}
})
}
```
# 组件使用
### AutoBackNotification
| props | type | desc | default |
| :---: | :----: | :----------: | :-----: |
| title | string | 提示文字 | '' |
| delay | number | 倒计时的数字 | 0 |
### Marquees
| props | type | desc | default |
| :-----: | :----: | :---------------------: | :-----: |
| content | string | 滚动的内容 | '' |
| delay | number | 第一次滚动时的延迟 时间 | 0.8 |
| speed | number | 滚动速度 | 40 |
### Icon
| props | type | desc | default |
| :---: | :------: | :------: | :--------------: |
| type | IconType | 图标类型 | '' |
| color | string | 填充颜色 | rgba(0, 0, 0, 1) |
Icon组件大小由父容器决定 所以需要给父容器指定宽高 type类型详见icon.d.ts
### Tabs
| props | type | desc | default |
| :-----------: | :-------: | :--------: | :-----: |
| list | TabItem[] | 数据源 | [] |
| indicateColor | string | 选中的颜色 | #fff |
TabItem类型 详见base.d.ts
| events | type | desc |
| :----: | :-----------------------------------: | :-----: |
| click | (item: TabItem, index: number)=>void | 点击tab |
组件默认ui无法满足设计稿时 可直接修改组件源码以满足设计稿 或者通过slot插槽自定义ui 详见以下demo
```html
{{ item.title }}
{{ item.titleEn }}
```
### ScrollView
| props | type | desc | default |
| :-------------: | :-------------: | :----------------------------------------------------------: | :-----: |
| list | array \| string | 监听的数据源 当数据源改动时会自动调用refresh重新计算滚动高度 | - |
| scrollbar | boolean | 显示滚动条 | false |
| scrollX | boolean | 是否需要横向滚动 | false |
| refreshDelay | number | 延迟初始化实例的时间 | 20 |
| scrollTop | boolean | 当list数据改变时是否自动回到顶部或者左边(scrollX为true时) | true |
| observeImage | boolean | 是否监听图片(有瀑布流布局的地方建议开启) | false |
| stopPropagation | boolean | 是否阻止事件冒泡。多用在嵌套 scroll 的场景。 | false |
| pullUp | boolean | 是否下拉刷新 | false |
### EffectFade
| props | type | desc | default |
| :--------: | :--------------------------: | :----------------: | :-----: |
| list | array | 内部渲染需要的数据 | [] |
| pagination | boolean \| PaginationOptions | 是否开启提示点 | false |
**此组件只初始化swiper轮播等相关逻辑 只做展示 dom节点自行实现 通过作用域插槽可拿到循环的每一项数据 作用域插槽字段: `{ item }`**
```javascript
```
### Written(手写组件的父元素需指定宽高)
| props | type | desc | default |
| :-------------: | :----: | :-----------------------------------: | :-------------------: |
| backgroundColor | string | canvas 背景色 | #f2f2f2 |
| borderRadius | string | canvas的圆角 | 10px |
| fillText | string | canvas绘制区域的提示文字 | 手写区域 |
| fillFontSize | string | canvas绘制区域的提示文字大小 | 100px |
| fillStyle | string | canvas绘制区域的提示文字颜色 | rgba(85, 73, 54, 0.1) |
| lang | string | CN \| EN 指定接口返回的是字母还是汉字 | CN |
| strokeStyle | string | 笔触的颜色 | #000 |
| events | type | desc | callback params |
| :----: | :------: | :------------------------------: | :----------------------------: |
| result | function | 组件内部响应式变量list变化时触发 | 接口请求成功之后返回的汉字列表 |
### PlateInput
| props | type | desc | default |
| :----------: | :------------: | :--------------: | :-----: |
| List | array | 车牌号或者车位号 | [] |
| btnText | string | 按钮提示文字 | '' |
| searchMethod | '车牌'\|'车位' | 找车方式 | '车牌' |
| events | type | desc |
| :----------: | :------: | :-------------------------: |
| handle-input | function | 点击输入框 |
| confirm | function | 确认找车 即点击找车按钮触发 |
**车牌输入框组件现在接受一个slot插槽 可以用来点击时显示loading提示或其他内容**
### PlateKeyboard
| props | type | desc | default |
| :-----------: | :----: | :--------------------------: | :-----: |
| searchMethods | string | 找车方式 ['车牌', '车位'] | '车牌' |
| events | type | desc |
| :-------------: | :------: | :------------------------------------------------------: |
| handle-keyboard | function | 点击找车键盘 参数为点击时的文字 如果为del则会触发del事件 |
| del | function | 删除 |
### Lottie动画组件
| props | type | desc | default |
| :------: | :--------------: | :----------------: | :-----: |
| isLocale | boolean | 是否是json本地文件 | true |
| path | Record | 动画数据 | {} |
# composition hooks 使用
### 活动导航
```javascript
const { nav } = useActivityNav() //nav接受参数类型
async function _nav(activity: Activity) {
await nav(activity)
//your code ...
}
```
### 通用导航的hooks
```javascript
```
### 日期及天气
```javascript
const {whickWeek} = useDay()
const {currentTime} = useTime()
const {weather, icon} = useWeather()
```
### useSearchShop.ts
```javascript
import {ref} from 'vue'
import {useSearchShop} from '@/composables/useSearchShop'
const keywords = ref('')
const searchMethods = ref(0) //0:键盘搜索 1:手写搜索
//筛选之后的店铺列表
const {searchShopList} =useSearchShop(keywords,searchMethods)
```
### usePage.ts
```javascript
your html code...
const { scrollEnd, pageList, loaded } =usePage(shopList, scroll)
```
###
## 其余hooks详见脚手架内的composables文件夹
# 项目内使用的工具函数
```javascript
import {
randomNumber, //两个数字之间的随机数
isPhoneNumber, // 手机号码验证
isUppercaseWord, //是否是大写
isZhWord, //是否是中文
isNumber, //是否是数字
isLicensePlate //验证输入车牌是否正确
uniqBy //数组内对象去重
futureDate, //未来几天 默认七天
formatDay, // 格式化年月日
isInDuringDate, //当前时间是否在指定时间段内
addPrefixByRecursive, //指定的资源加上地址前缀
splitStringToArray, //字符串点位转换成数组需以下划线 '_' 连接
trimAll //去除字符串所有空格
} from '@/utils/utils'
```