# 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 ``` ### 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' ```