pull/1/head
阿怪 11 months ago
commit 60bf302119

@ -0,0 +1,168 @@
<script>
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
<style scoped lang="scss">
/*每个页面公共css */
.page-bg-gray{
background: rgb(248, 248, 248);
}
.page-box{
/* height: 100%;
overflow: scroll; */
min-height: 100%;
}
uni-page-body,page{
height: 100%;
}
page{
font-size: 28rpx;
}
.text-ellipsis-1{ /*超出部分省略号 单行*/
overflow:hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 1;
display: -webkit-box;
-webkit-box-orient: vertical;
/* min-height: 38rpx; */
}
.icon-custom{
width: 32rpx;
height: 32rpx;
}
.small-text{
color: gray !important;
font-size: 24rpx;
font-weight: 100 !important;
}
.bold-text{
font-weight: 600;
font-size: 36rpx;
}
.margin-line{
height: 20rpx;
width: 100%;
background-color: rgb(248, 248, 248);
}
.clearCss{
opacity: 0 !important;
}
.shim{/* 垫片 */
width: 100%;
height: 140rpx;
}
.big-text{
font-size: 80rpx;
/* font-weight: 600; */
}
.red-text{
color: red;
}
.line{
height: 2rpx;
width: 100%;
background-color: #e7e7e7;
}
.num-show{
position: absolute;
width: 40rpx;
height: 40rpx;
color: white;
background: #7cc4e8;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
top: -24rpx;
right: -10rpx;
border: 2rpx solid white;
}
/* 通用卡片样式 */
.u-card{
background-color: white;
.u-card-row:last-child{
border-bottom: unset;
}
.u-card-row{
padding: 40rpx;
border-bottom: 2rpx solid #e7e7e7;
.u-card-row-btn{
color: #086EC7;
}
.u-card-row-top,.u-card-row-content{
display: flex;
align-items: center;
justify-content: space-between;
}
.u-card-row-top{
padding-bottom: 40rpx;
.u-card-left{
}
.u-card-right{
.u-card-right-btn{
color:#7cc4e8
}
}
}
.u-card-row-content{
.u-card-left{
// width: 50%;
}
.u-card-right{
// width: 50%;
display: flex;
}
}
}
}
//
.popup-content{
padding-top: 40rpx;
background-color: white;
border-radius: 20rpx 20rpx 0 0;
overflow: scroll;
}
.small-btn-css{
background: #7CC4E8;
color: white;
padding: 6rpx 40rpx;
border-radius: 40rpx;
font-size: 28rpx;
white-space: nowrap;
margin-left: 10rpx;
position: relative;
}
.cancel-btn{
display: block;
margin-top: 20rpx;
.add-btn{
background: white !important;
color: black !important;
border: 2rpx solid #7cc4e8 !important;
}
}
.invalidCss{
background-color: #767676 !important;
}
:deep(){
.uni-popup__wrapper{
bottom: -34px;
}
.popup-content{
bottom: -34px;
padding-bottom: 34px;
background-color: white;
}
}
</style>

@ -0,0 +1,404 @@
import net from './request.js';
// import store from '../store';
const API = {
/*
首页信息
*/
getIndexInfo: data => net.GET('/api/index/index'), // 首页信息
getIndexBanner: data => net.GET('/api/banner/index',data), // 轮播图
getIndexNotice: data => net.GET('/api/news/notice'), // 公告
getGoodsDetail: data => net.GET('/api/goods/detail',data),// 商品详情(普通商品)
getSeckillGoodsDetail: data => net.GET('/api/seckill_goods/detail',data),// 商品详情(秒杀)
getGroupGoodsDetail: data => net.GET('/api/group_goods/detail',data),// 商品详情(团购)
getGoodsList: data => net.GET('/api/goods/lists',data),// 商品列表(普通商品)
getSeckillGoodsList: data => net.GET('/api/seckill_goods/lists',data),// 商品列表(限时)
getGroupGoodsList: data => net.GET('/api/group_goods/lists?page=&keyword=',data),// 商品列表(团购)
getNewinfo: data => net.GET('/api/goods/getGoodsSpec',data), // 根据商品规格更新数据
getCategoryList:data => net.GET('/api/goods_category/lists'), // 获取商品分类
getCategory:data => net.GET('/api/goods/category',data), // 根据分类Id获取分类商品
getCartList:data => net.GET('/api/cart/lists',data), // 获取购物车列表
addCart:data => net.POST('/api/cart/add',data), // 加入购物车
delCart:data => net.POST('/api/cart/delete',data), // 删除购物车
updateCart:data => net.POST('/api/cart/edit',data), // 更新购物车
login:data => net.POST('/api/user/wechatLogin',data), // 登录
login_test:data => net.GET('/api/user/testLogin?id=1'), // 登录 测试专用
zhuce:data => net.POST('/api/user/profile',data), // 注册
getOrderList:data => net.GET('/api/order/lists',data), //订单列表
getOrderGroupList:data => net.GET('/api/group_order/lists',data), //订单列表(团购)
getOrderSeckillList:data => net.GET('/api/seckill_order/lists',data), //订单列表(秒杀)
pay:data => net.POST('/api/order/pay',data), //支付
payGroup:data => net.POST('/api/group_order/pay',data), //支付(团购)
paySeckill:data => net.POST('/api/seckill_order/pay',data), //支付(秒杀)
refund:data => net.POST('/api/order/refund',data), //退款
getOrderInviteList:data => net.GET('/api/invite/order',data), //分销订单
getOrderBaseinfo:data => net.POST('/api/order/preview',data), //获取订单提交页面的基本信息
getOrderGroupBaseinfo:data => net.POST('/api/group_order/preview',data), //获取订单提交页面的基本信息(团购)
getOrderSeckillBaseinfo:data => net.POST('/api/seckill_order/preview',data), //获取订单提交页面的基本信息(秒杀)
getOrderCartinfo:data => net.POST('/api/order/cartPreview',data), //获取订单提交页面的基本信息(购物车来的)
getDelivery:data => net.GET('/api/index/delivery',data), //获取配送相关的选项(普通商品)
staffApply:data => net.POST('/api/invite/apply',data), //业务员申请
deliveryApply:data => net.POST('/api/staff/apply',data), //配送员申请
getDeliveryArea:data => net.GET('/api/staff/getDeliveryArea'), //获取配送区域
getAddressList:data => net.GET('/api/address/lists'), //地址列表
getAddDetail:data => net.GET('/api/address/detail',data), //地址详情
addAddress:data => net.POST('/api/address/add',data), //新增地址
editAddress:data => net.POST('/api/address/edit',data), //修改地址
delAddress:data => net.GET('/api/address/delete',data), //删除地址
getDefaultAddress:data => net.GET('/api/address/getDefault'), //获取默认地址
orderSubmitFunc:data => net.POST('/api/order/order',data), //提交订单(普通订单)
orderSubmitCartFunc:data => net.POST('/api/order/cartOrder',data), //提交订单(购物车)
orderSubmitGroupFunc:data => net.POST('/api/group_order/order',data), //提交订单(团购订单)
orderSubmitSeckillFunc:data => net.POST('/api/seckill_order/order',data), //提交订单(秒杀订单)
orderDetail:data => net.GET('/api/order/detail',data), //订单详情-普通订单 (顾客)
orderGroupDetail:data => net.GET('/api/group_order/detail',data), //订单详情-团购订单
orderSeckillDetail:data => net.GET('/api/seckill_order/detail',data), //订单详情-秒杀订单
orderStaffDetail:data => net.GET('/api/staff/orderDetail',data), //订单详情-配送订单
orderLeaderDetail:data => net.GET('/api/leader/orderDetail',data), //订单详情-管理员订单
orderCancel:data => net.POST('/api/order/cancle',data), //取消订单
orderCancelGroup:data => net.POST('/api/group_order/cancle',data), //取消订单 (团购)
orderCancelSeckill:data => net.POST('/api/seckill_order/cancle',data), //取消订单 (秒杀)
/*
用户相关
*/
getUserInfo:data => net.GET('/api/user/userInfo',data), //获取用户信息
updateUserInfo:data => net.POST('/api/user/profile',data), //更新用户信息
rechargeFunc:data => net.POST('/api/recharge/recharge',data), //充值
withdrawalFunc:data => net.POST('/api/withdrawl/submit',data), //提现
vipBuy:data => net.POST('/api/vip/order',data), //购买VIP
vipConfig:data => net.GET('/api/vip/config'), //会员说明
/*
优惠券
*/
getCouponsList:data => net.GET('/api/coupon/userCoupons',data), //优惠券
getCouponsCenterList:data => net.GET('/api/coupon/lists',data), //领券中心
couponsCenterReceive:data => net.POST('/api/coupon/receive',data), //领取优惠
getMyStars:data => net.GET('/api/collect/lists',data), //我的收藏
/*
推广中心
*/
inviteCenter:data => net.GET('/api/invite/index',data), //首页
inviteCenterwithdrawl:data => net.POST('/api/withdrawl/submit',data), //提现
inviteCenterwithdrawlDetail:data => net.GET('/api/invite/withdrawlDetail',data), //提现明细
inviteCenterwithdrawlRecodes:data => net.GET('/api/invite/record',data), //提现明细(佣金)
getShareQrcode:data => net.GET('/api/user/getShareQrcode'), //用户分销二维码
/*
配置相关
*/
getConfig:data => net.GET('/api/index/config'),
setDeliveryTime:data => net.POST('/api/staff/setDeliveryTime',data), // 设置配送时间
getDeliveryTime:data => net.GET('/api/staff/getDeliveryTime'), // 获取配送时间
getStaffOrder:data => net.GET('/api/staff/orderLists',data), // 获取订单管理列表(配送员)
getManageOrder:data => net.GET('/api/leader/orderLists',data), // 获取订单管理列表(团长)
deliveryPhoto:data => net.POST('/api/staff/deliveryPhoto',data), // 送达拍照
reveiceOrder:data => net.POST('/api/staff/reveiceOrder',data), // 接单
reveiceOrderOk:data => net.POST('/api/leader/assignOrder',data), // 派单
getStaffList:data => net.GET('/api/leader/staffList'), // 配送员列表
goodsBuyFunc:data => net.POST('/api/leader/goodsBuy',data), // 商品申购
getRecordList:data => net.GET('/api/leader/recordList',data), // 货物入库
/**
*
* 登录类信息
*
*/
// 检查更新
getUpdateVersion:data => net.GET('/api/v1/index/version'),
// 获取定位
getLocationInfo:data => net.GET('/api/v1/index/ip',data),
// 验证码登陆
codeLogin: data => net.POST('/code/login', data),
// H5扫码登录邀请接口
inviteLogin: data => net.POST('/api/v1/invite/login', data),
// 发送手机验证码接口
sendVerifyCode: data => net.POST('/api/v1/sms/send', { send_type: 'student', ...data}),
// 注销账号
unRegister: data => net.POST('/api/v1/student/delete', data),
// 授权登录
accessLogin: (data, t = 'wx') => net.POST(`/api/v1/${t}/login`, data),
// 退出登录
logOut: data => net.POST('/api/v1/code/logout', data),
// 获取省份
getProvince: data => net.GET('/api/v1/colleges/getProvince', data),
// 根据学员所选择的教学点获取院校列表接口
collegesList: data => net.GET('/api/v1/colleges/list', data),
// 通过市反查省/自治区/直辖市
getProvinceByCity: data => net.GET('/api/v1/region/getProvinceByCity', data),
/**
*
* 用户信息
*
*/
// 学员个人信息接口
selectUserInfo: data => net.GET('/api/v1/student/info', data),
// 登录成功后填写学员信息接口
userUpdate: data => net.POST('/api/v1/student/update', data),
// 邀请二维码
qrcode: data => net.POST('/api/v1/student/invite/qrcode', data),
uploadBase64: data => net.POST('/api/v1/student/uploadBase64', data),
// 获取被邀请人列表接口
inviteList: data => net.GET('/api/v1/student/invite/list', data),
// 积分列表
scoreList: data => net.GET('/point', data),
// 余额明细
balanceList: data => net.POST('/api/v1/balance/detail/get/list', data),
// 模拟测试记录
recordList: data => net.GET('/api/v1/test-record/mock/examination/record', data),
// 练习题错误集详情
practiceList: data => net.GET('/api/v1/test-record/practice/list', data),
/**
*
* 首页数据
*
*/
// 首页配置获取
indexConfig: data => net.GET('/api/v1/index/config', data),
// 轮播
// indexBanner: data => net.GET('/app/banner', data),
indexBanner: data => net.POST('/api/v1/index/lbt', data),
// 获取咨询文章列表
// wzList: data => net.GET('/app/consult-wz', data),
wzList: data => net.POST('/api/v1/index/wz/list', data),
// 获取咨询文章
// wzInfo: id => net.GET(`/app/consult-wz/${id}`),
wzInfo: id => net.GET(`/api/v1/index/wz/${id}`),
// 获取课程分页
getCourseList: (data) => net.GET(`/app/course/page`,data),
// 获取推荐院校列表
// recommendwzList: data => net.GET('/app/academy', data),
recommendwzList: data => net.POST('/api/v1/index/academy/list', data),
// 获取推荐院校文章
// recommendwzInfo: id => net.GET(`/app/academy/${id}`),
recommendwzInfo: id => net.GET(`/api/v1/index/academy/${id}`),
// 推荐院校文章阅读量累计
// recomendaddReadNumber: data => net.PUT('/app/academy/num',data),
recomendaddReadNumber: data => net.POST('/api/v1/index/academy/add/num', data),
//获取考试大纲列表
syllabusList: data => net.POST('/api/v1/index/syllabus/list', data),
// 搜索
search: data => net.POST('/api/v1/index/search', data),
// 阅读量累计
addReadNumber: data => net.PUT('/app/consult-wz/num', data),
// 师资团队列表
lecturerList: data => net.GET('/api/v1/index/lecturer', data),
// 师资详情
lecturerDetail: id => net.GET(`/api/v1/index/lecturer/${id}`),
// 获取资料列表
indexMaterial: data => net.GET('/api/v1/index/material', data),
// indexMaterial: data => net.GET('/app/material', data),
// 获取资料详情
materialDetail: data => net.GET(`/api/v1/index/material/${data.id}`,{buyer_id:data.buyer_id}),
// 获取精品课程
indexBoutiqueCourse: data => net.GET('/api/v1/index/boutique/course', data),
// 获取精品课程详情
boutiqueCourseDetail: id => net.GET(`/api/v1/index/boutique/course/${id}`),
// 获取课程
courseList: data => net.POST('/api/v1/course/get', data),
// 获取套餐
comboList: data => net.POST('/api/v1/combo/course/get', data),
// courseList: data => net.GET('/app/course/page', data),
// 获取课程详情
courseDetail: (id, data) => net.GET(`/api/v1/course/${id}`, data),
// courseDetail: (id, data) => net.GET(`/app/course`, {id}),
// 获取线下课程
offlineCourseList: data => net.POST('/api/v1/offline/course/get', data),
// 获取线下课程详情
offlineCourseDetail: id => net.GET(`/api/v1/offline/course/${id}`),
// 获取套餐课程详情
getComboDetail: data => net.GET(`/api/v1/combo/course/${data.id}`,{buyer_id:data.buyer_id}),
// 获取直播课列表
// liveCourseList: data => net.GET('/api/v1/sys-course-live', data),
liveCourseList: data => net.GET('/api/v1/api-live-course', data),
// 直播课详情
viewCourse: (id, data) => net.GET('/api/v1/sys-course-live/'+id,{buyer_id:data.buyer_id}),
// 直播课详情 测试
viewCourse_test: (id, data) => net.GET('/api/v1/api-live-course/'+id,{buyer_id:data.buyer_id}),
/*题库 管理*/
//题库
getQuestionExercise:data => net.GET('/exercises', data),
// 科目
subjectList: data => net.GET('/api/v1/public/subject', data),
// subjectList: data => net.GET('/app/subject/list', data),
// 获取学员学习列表接口
learningList: data => net.GET('/api/v1/learning', data),
// 学习课程详情
learningDetail: data => net.GET(`/api/v1/learning/course/${data}`),
// 学习直播课程详情
learningLiveDetail: data => net.GET(`/api/v1/learning/course/live/${data}`),
// 学员学习计时接口
// "time_type": "stop" //计时类型 start-开始计时 stop-停止计时
studyDuration: data => net.POST('/api/v1/learning/course/duration', data),
// 学习统计API
courseStatistics: data => net.POST('/api/v1/learning/course/statistics', data),
// 题型分类
questionBankType: data => net.GET('/api/v1/questionBank/type', data),
// 网课、测试、题库详情
exercisesDetails: data => net.GET(`/api/v1/exercises/detail/${data}`),
// 测试练习题列表
testList: data => net.GET('/api/v1/exercises/test/list', data),
// 模拟试卷列表
examinationList: data => net.GET('/api/v1/examination/list', data),
// 获取题库、网课题目列表接口
exerciseSubjectList: data => net.GET('/api/v1/exercise/subject/list', data),
// 试题分类
exercisesType: data => net.GET('/api/v1/exercises/type', data),
// 模拟题详情
examinationDetail: id => net.GET(`/api/v1/examination/detail/${id}`),
// 开始答题
startTest: data => net.POST('/api/v1/exercises/start/answer', data),// question_bank_id
// 交卷
submitTest: data => net.POST('/api/v1/exercises/submit', data),
// 下一题
nextSubject: data => net.POST('/api/v1/exercises/next', data),
// 重新答题
againAnswer: data => net.POST('/api/v1/exercises/againAnswer', data),
// 答题成绩报告
scoreReport: data => net.GET('/api/v1/exercises/achievement/report', data),
// 获取团购列表
getGroupList: data => net.GET('/api/v1/group/page', data),
// 获取团购详情
getGroupPurchaseData: data => net.GET('/api/v1/group', data),
//发起拼团
starGroupPurchase:data => net.POST('/api/v1/group',data),
//加入拼团
joinGroupPurchase:data => net.POST('/api/v1/group/join',data),
/**
*
* 支付接口
*
*/
// 支付接口
wxOrAlipay: data => net.POST('/api/v1/pay', data),
// 获取openid
getOpenID: data => {
return uni.request({
url:'https://api.weixin.qq.com/sns/oauth2/access_token',
method:'GET',
// header: {
// ...header,
// ...headers
// },
data
})
},
// 余额支付
yuePay: data => net.POST('/api/v1/student/pay/balance', data),
//H5下单API
// v3_pay:data => net.POST('https://api.mch.weixin.qq.com/v3/pay/transactions/h5',data)
v3_pay:data => {
return uni.request({
url: 'https://api.mch.weixin.qq.com/v3/pay/transactions/h5',
method:'POST',
header: {
"Content-Type": "application/json",
},
data
})
},
//测试
pay_check:data => net.POST('/api/v1/wxpay/check',data),
pay_callback:data => net.POST('/api/v1/wxpay/callback',data),
/**
*
* 地址接口
*
*/
// 列表
addressList: data => net.POST('/api/v1/address', data), // student_id
// 新增/编辑
addressAction: data => net.POST(`/api/v1/address/add`, data),
editaddressAction: data => net.PUT(`/api/v1/address`, data),
// 删除
addressDelete: data => net.DELETE('/api/v1/address', data), // id
/**
*
* 购物车接口
*
*/
// 列表
cartList: data => net.POST('/api/v1/shopping/cart', data),
// 添加
cartAdd: data => net.POST('/api/v1/shopping/cart/add', data),
// 编辑
cartUpdate: data => net.POST('/api/v1/shopping/cart/update', data),
// 删除
cartDelete: data => net.POST('/api/v1/shopping/cart/delete', data), // id
/**
*
* 订单接口
*
*/
// 订单查询
orderList: data => net.POST('/api/v1/api-order/get/my/order/list', data),
// 确认收货
orderUpdate: data => net.POST('/api/v1/api-order/update/material/order', data),
// 删除
orderDelete: data => net.POST('/api/v1/api-order/delete/order', data),
/**
* 商品价格合计
* @param { order_count_list: [{ id: '', order_type: '', num: ''}] }
*
*/
orderCount: data => net.POST('/api/v1/api-order/order/count', data),
/**
* 资料在线课程的立即购买/购物车
* @param { goods: [{ id: '', order_type: '', num: ''}], student_id: '' }
*
*/
orderBuynow: data => net.POST('/api/v1/api-order/order/buynow', data),
// 新增资料订单
orderMaterialAdd: data => net.POST('/api/v1/api-order/add/material/order', data),
// 新增在线课程订单
orderOnlineAdd: data => net.POST('/api/v1/api-order/add/online/order', data),
// 直播课订单
orderLiveAdd: data => net.POST('/api/v1/api-order/add/live/order', data),
// 新增套餐课程订单
orderComboAdd: data => net.POST('/api/v1/api-order/add/combo/order', data),
// 新增线下订单==报名
orderOfflineAdd: data => net.POST('/api/v1/api-order/add/offline/order', data),
// 新增团购订单
orderGroupAdd: data => net.POST('/api/v1/api-order/add/group/order', data),
// 分享平台
shareProvider: () => net.getShareProvider(),
// 支付方式
paymentProvider: () => net.getPaymentProvider(),
// 物流查询
queryKuaidi: data => net.POST('/api/v1/kuaidi/poll/query', data),
// SHARE: () => net.SHARE(),
// 提现
transfer: data => net.POST('/api/v1/wxpay/transfer', data),
// 获取我的收藏分页列表
getStarList: data => net.POST('/api/v1/favorite/get', data),
// 取消收藏
cancelStar: data => net.DELETE('/api/v1/favorite',data),
//添加收藏
addStar:data => net.POST('/api/v1/favorite',data)
};
export default API

@ -0,0 +1,208 @@
import config from '../config'
// import store from '../store'
const loginUrl = 'pages/user/login';
export default {
REQUEST(url, method = 'GET', data, checkLogin = true, header) {
let token = uni.getStorageSync('access_token') || '';
const headers = {
"Content-Type": "application/json",
"Authorization": token,
"x-token": token,
"token":token,
// "X-Forwarded-For":'client_ip'
// 'Referer':'twzxjy.com'
}
var pages = getCurrentPages();
var page = pages[pages.length - 1];
return uni.request({
url: config.baseUrl + url,
method,
header: {
...header,
...headers
},
data
}).then(res => {
// console.log(res)
if (res.statusCode === 200 && res.data) {
if (res.data.code === 409) {
uni.showModal({
title:"提示",
content:"您的账号已在其他设备登录,已强制下线!",
confirmColor: '#006647',
showCancel: false,
success: (res) => {
if (res.confirm) {
uni.removeStorageSync('access_token');
uni.removeStorageSync('user_info');
if (checkLogin && page.route != loginUrl) {
uni.navigateTo({
url: '/' + loginUrl
});
}
}
}
});
return {
...res.data
}
}
if (res.data.code === 5) { // 用户认证失败
uni.removeStorageSync('access_token');
if(page.route != loginUrl && checkLogin) {
uni.navigateTo({
url: '/' + loginUrl
});
}
}
return res.data;
} else {
const reg = /abort/;
let code = 0;
let msg = (res[0] && res[0].errMsg) || '未知错误';
if ((res[0] && res[0].errMsg) && reg.test(res[0].errMsg)) {
msg = '网络请求中断'
}
return {
code,
msg,
data: null
}
}
}).catch(parmas => {
// console.log(params)
return parmas
//      return Promise.reject()
})
},
GET(url, body, checkLogin = true, header) {
return this.REQUEST(url, 'GET', body, checkLogin, header);
},
POST(url, body, checkLogin = true, header) {
return this.REQUEST(url, 'POST', body, checkLogin, header);
},
PUT(url, body, header) {
return this.REQUEST(url, 'PUT', body, header);
},
DELETE(url, body, header) {
return this.REQUEST(url, 'DELETE', body, header);
},
UPLOAD(data) {
return new Promise((resolve, reject) => {
let token = uni.getStorageSync('access_token') || '';
uni.uploadFile({
...data,
url: config.base_url + data.url,
header: {
"Access-Token": token
},
success(res) {
res.data = JSON.parse(res.data);
if (res.data.code === 401) {
uni.removeStorageSync('access_token');
uni.removeStorageSync('userInfo');
uni.navigateTo({
url: '/pages/login/login'
});
}
resolve(res);
},
fail(e) {
console.log(e);
reject(e)
},
});
});
},
getShareProvider: () => {
return uni.getProvider({
service: "share"
}).then(res => {
let data = []
for (let i = 0; i < res.provider.length; i++) {
switch (res.provider[i]) {
case 'weixin':
data.push({
name: '微信好友',
id: 'weixin',
icon: '/static/wx.png'
})
data.push({
name: '朋友圈',
id: 'weixin',
type: 'WXSenceTimeline',
icon: '/static/pyq.png'
})
break;
case 'qq':
data.push({
name: 'QQ好友',
id: 'qq',
icon: '/static/qq.png'
})
break;
default:
break;
}
}
return data;
}).catch(parmas => {
return Promise.reject()
});
},
getPaymentProvider: () => {
return uni.getProvider({
service: "payment"
}).then(res => {
let data = [];
const aliPay = {
name: '支付宝支付',
id: 'alipay',
icon: '/static/order/zfbp@3x.png'
};
const wxPay = {
name: '微信支付',
id: 'wxpay',
icon: '/static/order/wxp@3x.png'
};
const yuePay = {
name: '余额支付',
id: 'yepay',
icon: '/static/order/yep@3x.png'
}
for (let i = 0; i < res[1].provider.length; i++) {
switch (res[1].provider[i]) {
case 'alipay':
data.push({
...aliPay
})
break
case 'wxpay':
data.push({
...wxPay
})
break;
default:
break;
}
}
//#ifdef H5
return [aliPay, wxPay, yuePay];
//#endif
return [...data, yuePay];
}).catch(parmas => {
return Promise.reject()
});
}
}

BIN
components/.DS_Store vendored

Binary file not shown.

@ -0,0 +1,74 @@
<template>
<div class="skeleton animated">
<div class="skeleton-row" v-for="(item, index) in rowList" :style="item.style || {}" :key="index">
<div class="skeleton-row-item" v-for="(colItem, colIndex) in item.colItems"
:class="[colItem.childRowItems ? 'no-height' : '']" :key="colIndex" :style="colItem.style">
<template v-if="colItem.childRowItems">
<div class="skeleton-row-item" v-for="(childRowItem, childRowIndex) in colItem.childRowItems"
:key="childRowIndex" :style="childRowItem.style || {}"></div>
</template>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Skeleton',
props: {
rowList: {
type: Array,
default: () => []
},
},
}
</script>
<style lang="scss" scoped>
.skeleton {
width: 100%;
--color: #F6F6F6;
&.animated {
animation: blink 1.2s ease-in-out infinite;
}
* {
box-sizing: border-box;
}
}
.skeleton-row {
display: flex;
width: 100%;
align-content: space-between;
}
.skeleton-row-item {
height: 26px;
border-radius: 12rpx;
display: inline-block;
&:not(.no-height) {
background: var(--color);
}
&.no-height {
height: auto;
}
}
@keyframes blink {
0% {
opacity: 1;
}
50% {
opacity: 0.6;
}
100% {
opacity: 1;
}
}
</style>

@ -0,0 +1,46 @@
<script setup>
//
import {watch,ref,reactive} from "vue"
// icons
import normal from "/static/default_icon.png"
import search_icon from "/static/default_search_icon.png"
// props
const props = defineProps(['type',"title","message"])
//
</script>
<template>
<view class="default-icon-box">
<view class="icon-box">
<image v-if="type=='search'" :src="search_icon" mode="widthFix"></image>
<image v-else :src="normal" mode="widthFix"></image>
</view>
<view class="text-box">
<view class="title-part">{{title?title:'暂无数据...'}}</view>
<view class="message-part empty-text">{{message?message:''}}</view>
</view>
</view>
</template>
<style scoped lang="scss">
.default-icon-box{
padding: 20rpx;
.icon-box{
text-align: center;
image{
width: 200rpx;
}
}
.text-box{
text-align: center;
margin-top: 20rpx;
font-size: 28rpx;
color:gray;
.title-part{
margin-bottom: 10rpx;
}
.message-part{
}
}
}
</style>

@ -0,0 +1,219 @@
<script setup>
import { ref} from "vue"
// typecategory- list
const props = defineProps(['info','type','list','title','buy_type']);
import goodsInfo from "@/components/goodsInfo.vue"
import goodsSpecs from "@/components/goodsSpecs.vue"
// import goodsCartPay from "@/components/goodsCartPay.vue"
import api from "@/api/index"
//
const detail_info = ref(null)
const show_state = ref(false)
// const isShow = ref(false)
//
function toDetail(item) { //
let url = ''
// if(props.buy_type == 'group') { //
// url = '/pages/goods/goodsDetail?info='+encodeURIComponent(JSON.stringify(item))+"&buy_type="+props.buy_type
// }
// else if(props.buy_type == 'limited'){ //
// }
// else{ //
// url = '/pages/goods/goodsDetail?info='+encodeURIComponent(JSON.stringify(item))+"&buy_type="+props.buy_type
// }
url = '/pages/goods/goodsDetail?id='+item.id+'&info='+encodeURIComponent(JSON.stringify(item))+"&buy_type="+props.buy_type
uni.navigateTo({
url
})
}
function toPlate() { //
let url = ''
// if(props.buy_type == 'group') { //
// url = "/pages/goods/goodsPlate?info="+JSON.stringify(props.info)
// }
// else{
// return
// }
url = "/pages/goods/goodsPlate?info="+encodeURIComponent(JSON.stringify(props.info))+"&buy_type="+props.buy_type
uni.navigateTo({
url
})
}
function addToCart(item) { //
getGoodsDetail(item.id)
return
// uni.showToast({
// title: '',
// icon:'success',
// duration: 2000,
// // mask:true
// });
}
async function getGoodsDetail(id) {//
const res = await api.getGoodsDetail({
id
})
if(res.code === 1) {
detail_info.value = res.data
detail_info.value = res.data
//
if(detail_info.value.goods_images) {
detail_info.value.goods_images = detail_info.value.goods_images.split(",")
detail_info.value.goods_images = detail_info.value.goods_images.map((item,i) => {
let o = {
image:item,
skip_url:'',
skip_url_type:2
}
return item = o
})
}
//
// console.log(detail_info.value)
show_state.value = !show_state.value
}
}
function afterChoose(params) { //
if(params.state === 1) {
// current_info.value.id
// getCartList() //
uni.showToast({
title: '已加入购物车!',
icon:'success',
duration: 2000,
// mask:true
});
// isShow.value = true
}
}
// function closedFunc() {
// isShow.value = false
// }
</script>
<template>
<view class="goods-card-box">
<!-- 展示分类 -->
<view class="category-box" v-if="type === 'category'">
<view class="gcb-title" style="justify-content: center;">
{{title}}
</view>
<view class="gcb-list">
<view class="gcb-list-card" v-for="(item,i) in list">
<!-- <img style="width:100%;border:1px solid #f1f1f1;border-radius: 5px;" :src="item.cover" alt=""> -->
<image style="width: 100%;border-radius: 5px;" :style="{ height: item.goods_image?'':'100rpx'}" :src="item.goods_image" mode="widthFix"></image>
<view class="g-show-name text-ellipsis-1">{{item.goods_name}}</view>
</view>
</view>
</view>
<!-- 商品分组 方式1-->
<view class="goods-box" v-if="type === 'goods'">
<view class="gcb-title" @tap="toPlate">
<view class="title-wrap">
{{title}}
</view>
<uni-icons class="toCss" type="right" color="white" size="16"></uni-icons>
</view>
<view class="gcb-list">
<view class="gcb-list-card" v-for="(item,i) in list">
<goodsInfo @tap="toDetail(item)" type=1 :info="item" >
<template v-if="buy_type=='activity'" #btn>
<view class="g-cart" @tap.stop="addToCart(item)">
<image src="@/static/cart.png" mode="widthFix" ></image>
</view>
</template>
</goodsInfo>
</view>
</view>
</view>
<goodsSpecs :goods_info="detail_info" @choosedOk="afterChoose" :show_state="show_state"></goodsSpecs>
<!-- <goodsCartPay :isShow="isShow" @closedState="closedFunc"></goodsCartPay> -->
</view>
</template>
<style lang="scss">
.gcb-title{
display: flex;
align-items: center;
}
.toCss{
position: absolute;
right: 10px;
// position: absolute; right: 10px; top: 30%;
}
.title-wrap{
position: relative;
top: 0;
left: 0;
width: 100%;
}
.g-cart{
image{
width: 40rpx;
height: 40rpx;
}
}
.g-buy-box{
display: flex;
justify-content: space-between;
align-items: center;
.g-price-box{
color: #FD5B4E;
display: flex;
align-items: end;
.g-price{
font-size: 18px;
margin-right: 10rpx;
font-weight: 600;
}
.g-price-o{
color: gray;
font-size: 28rpx;
text-decoration: line-through;
}
}
}
.g-desc{
color: gray;
font-size: 28rpx;
margin: 10px 0;
}
.g-show-name{
margin-top: 20rpx;
font-weight: bolder;
}
.gcb-title{
position: relative;
background: linear-gradient(0deg, #82c8ea, #abdef4);
color: white;
padding: 16rpx 0;
font-size: 36rpx;
font-weight: 600;
text-align: center;
}
.gcb-list{
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 0 20rpx;
.gcb-list-card{
// padding: 20rpx;
width: 48%;
margin: 20rpx 0;
}
}
.goods-card-box{
background: white;
border: 1px solid #82c8ea;
border-radius: 10px;
overflow: hidden;
margin-bottom: 40rpx;
border-top: unset;
.category-box{
text-align: center;
}
}
</style>

@ -0,0 +1,225 @@
<script setup>
//
import { onShow,onLoad,onHide } from "@dcloudio/uni-app"
import {ref,onMounted,nextTick,reactive,watch} from "vue"
import myButton from "@/components/myButton.vue"
import { useStore } from '@/store'
import api from "@/api/index"
import goodsInfo from "@/components/goodsInfo.vue"
const store = useStore()
const props = defineProps(['cart_show','cart_list']);
const emits = defineEmits(['del_cart'])
onLoad((e) => {
styleObject.value.height = store.systemInfo.screenHeight/1.8+'px'
// console.log(":",props.goods_info)
// getList()
})
watch(
() => props.cart_list,
(newVal, oldVal) => {
// info.value = newVal
list.value = newVal
console.log("cart_list新值",newVal)
updateList()
}
)
watch(
()=>props.cart_show,
(newVal, oldVal) => {
styleObject.value.height = store.systemInfo.screenHeight/1.8+'px'
cart_popup.value.open('bottom')
})
//
const list = ref([])
const cart_popup = ref()
const styleObject = ref({
height: '0px',
})
const total_num = ref(1)
const current_ = ref(0)
//
function updateList(){
// console.log(list.value)
if(list.value && list.value.length>0) {
for(let item of list.value) {
item.goods_image = item.goods.goods_image
item.goods_name = item.goods.goods_name
item.goods_id = item.goods.id
item.sell_price = item.price * item.num
item.single_price = item.price
item.desc = item.spec.name+',¥'+item.spec.sell_price
}
}
}
async function getList() { //
const res = await api.getCartList()
if(res.code ===1) {
list.value = res.data
}
}
function changeNumFunc(value){
setTimeout(() => {
// console.log(value,current_.value)
if(value>0) {
list.value[current_.value].num = value
list.value[current_.value].sell_price = list.value[current_.value].single_price * value
// list.value[current_.value].price = value
//
store.cartChange = !store.cartChange
emits('update_cart',[list.value[current_.value].id,list.value[current_.value].num])
}
else if(value<1) { //
// total_num.value = 1
store.cartChange = !store.cartChange
emits('del_cart',[list.value[current_.value].id])
}
else{ //
}
},0)
}
function lockItem(i) { //
current_.value = i
}
async function ofunc() { //
if(list.value.length > 0) {
uni.navigateTo({
url:'../order/order_submit?type=cart&info='+encodeURIComponent(JSON.stringify(props.cart_list))
})
}
}
async function clearFunc() { //
if(list.value.length<1) {
uni.showToast({
title:"没有商品哦~",
icon:"none"
})
return
}
uni.showModal({
title:'清除提示',
content:'确定要清除购物车吗?',
success:(val)=>{
console.log(val)
if(val.confirm) {
let arr = []
for(let item of list.value) {
arr.push(item.id)
}
store.cartChange = !store.cartChange
emits('del_cart',arr)
}
}
})
}
</script>
<template>
<view class="goodsCartBox">
<uni-popup ref="cart_popup" @change="change">
<view class="popup-content" :style="styleObject" >
<view class="pc-top">
<view class="pc-top-left">
已选商品
<text style="color: gray;">({{list.length}})</text>
</view>
<view class="pc-top-right" style="color: gray;" @click="clearFunc">
清空购物车
</view>
</view>
<view class="pc-content">
<view class="list-row" v-for="(item,i) in list" @tap="lockItem(i)">
<goodsInfo :type="2" :info="item" >
<template #btn>
<uni-number-box :value="item.num" @change="changeNumFunc" />
</template>
</goodsInfo>
</view>
</view>
<view class="pc-bottom" style="padding: 40rpx 0 ;">
<!-- 按钮 -->
<myButton v-if="list.length>0" style="width: 100%;" class="op-right" :type="2" @tap="ofunc(3)">
去结算
</myButton>
</view>
</view>
</uni-popup>
</view>
</template>
<style scoped lang="scss">
.pc-bottom{
z-index: 100;
position: fixed;
width: 100%;
bottom: 0;
background-color: white;
}
.goodsCartBox{
.popup-content{
position: relative;
padding-top: 40rpx;
background-color: white;
border-radius: 10px 10px 0 0;
overflow: scroll;
.pc-top{
position: fixed;
top: 34px;
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
box-sizing: border-box;
padding: 40rpx;
background-color: white;
z-index: 10;
}
.pc-content{
.list-row{
padding: 20rpx;
}
margin-bottom: 260rpx;
margin-top: 20rpx;
}
.pc-row{
padding:0 40rpx;
padding-bottom: 40rpx;
.pcr-title{
color: gray;
font-size: 30rpx;
padding: 20rpx 0;
}
.pc-choose-card-box{
.pc-choose-card{
display: inline-block;
background: #f1f1f1;
margin-right: 20rpx;
margin-bottom: 20rpx;
padding: 10rpx 20rpx;
border-radius: 10rpx;
// font-weight: bolder;
font-size: 28rpx;
}
}
}
.main-info{
display: flex;
// align-items:;
.pcr-left{
margin-right: 40rpx;
.pcrl-img-box{
border: 2rpx solid #dadada;
width: 180rpx;
height: 180rpx;
image{
width: 180rpx;
height: 180rpx;
}
}
}
.pcr-right{
.pcrr-row{
margin-bottom: 20rpx;
}
}
}
}
}
</style>

@ -0,0 +1,169 @@
<script setup>
//
import { onLoad,onShow } from "@dcloudio/uni-app"
import api from "@/api/index"
import {ref,onMounted,nextTick,watch} from "vue"
// import custom from "@/utils/index"
import { useStore } from '@/store'
const store = useStore()
// import searchBox from "@/components/searchBox.vue"
// import notice from "@/components/notice.vue"
// import goodsInfo from "@/components/goodsInfo.vue"
// import goodsSpecs from "@/components/goodsSpecs.vue"
import goodsCart from "@/components/goodsCart.vue"
const props = defineProps(['isShow']);
const emits = defineEmits([])
watch(() => {
return props.isShow
},(val1,val2) => {
console.log(props.isShow)
})
//
const cart_show = ref(false)
const current_ = ref(0)
const choosed_list = ref([])
const choosed_info_list = ref([])
const totalprice = ref(0)
const detail_info = ref(null)
//
function showCart() { //
cart_show.value = !cart_show.value
}
async function update_cart_func(params) {
// console.log(params)
const res = await api.updateCart({
cart_id:params[0],
num:params[1]
})
if(res.code === 1) {
getCartList()
}
}
const cart_list = ref(null)
async function getCartList() { //
const res = await api.getCartList()
// console.log(res)
if(res.code === 1) {
// if(res.data.length >0) {
cart_list.value = res.data
// console.log(cart_list.value)
totalprice.value = cart_list.value.reduce((total,item) => {
return total + parseFloat(item.price)
},0)
// choosed_list.value.push(item.id)
// totalprice.value += item.sell_price
// choosed_info_list.value.push(item)
// }
}
}
async function toPay() { //
//
const res = await api.getDefaultAddress()
if(res.code ===1 ) {
if(!res.data) { //
uni.showToast({
title:"请设置默认地址",
duration:1500,
icon:'none'
})
setTimeout(() => {
uni.navigateTo({
url:'../address/index'
})
},1500)
}
else{
uni.navigateTo({
url:'../order/order_submit?info='+encodeURIComponent(JSON.stringify(cart_list.value))
})
}
}
}
</script>
<template>
<view class="goodsCartPayBox">
<view class="checkoutBox" v-if="cart_list && cart_list.length>0" @tap="showCart">
<!-- 结算信息 -->
<view class="checkoutBox-left">
<!-- 商品数量 -->
<view class="goods-num">
<image src="../..//static/cart2.png" mode=""></image>
<view class="num-show">{{cart_list.length}}</view>
</view>
<!-- 价格信息以及配送费 -->
<view class="goods-info">
<view class="g-price">{{totalprice}}</view>
<view class="g-price-o" >
<!-- 另需配送费10 -->
</view>
</view>
</view>
<view class="checkoutBox-right">
<view class="checkout-btn" @tap.stop="toPay">
去结算
</view>
</view>
</view>
<goodsCart @del_cart="del_cart_func" @update_cart="update_cart_func" :cart_show="cart_show" :cart_list="cart_list"></goodsCart>
</view>
</template>
<style scoped lang="scss">
.goodsCartPayBox{
}
.checkoutBox-right{
width: 50%;
display: flex;
align-items: center;
justify-content: flex-end;
.checkout-btn{
display: flex;
height: 100%;
background: #7cc4e8;
padding: 0 20rpx;
color: white;
align-items: center;
justify-content: center;
width: 60%;
}
}
.g-price{
color: #FD5B4E;
font-size: 36rpx;
margin-right: 10rpx;
font-weight: 600;
}
.g-price-o{
color: gray;
font-size: 28rpx;
// text-decoration: line-through;
}
.checkoutBox{
position: absolute;
bottom: 0px;
width: 100%;
background: white;
display: flex;
.checkoutBox-left{
padding: 20rpx;
width: 50%;
display: flex;
.goods-num{
margin-right: 40rpx;
padding: 20rpx;
background: #f8f8f8;
border-radius: 50%;
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
position: relative;
image{
width: 40rpx;
height: 40rpx;
}
}
}
}
</style>

@ -0,0 +1,139 @@
<script setup>
import { ref} from "vue"
// typecategory- list
const props = defineProps(['type','info',"noPrice"]);
</script>
<template>
<view class="goodsInfoBox">
<!-- 展示方式1 上下结构-->
<view class="showtype1 " v-if="type==1">
<!-- <img style="width:100%;border-radius: 5px;" :src="info.cover" alt=""> -->
<image style="width: 100%;border-radius: 5px;" :style="{ height: info && info.goods_image?'340rpx':'340rpx'}" :src="info?.goods_image" mode="aspectFill"></image>
<view class="g-show-name text-ellipsis-1">{{info?.goods_name}}</view>
<view class="g-desc">
{{info?.desc}}
</view>
<view class="g-buy-box">
<view class="g-price-box">
<view class="g-price">{{info?.sell_price}}</view>
<view class="g-price-o" v-if="info?.market_price">
{{info?.market_price}}
</view>
</view>
<slot name="btn"></slot>
</view>
</view>
<!-- 展示方式2 左右结构-->
<view class="showtype2 " v-else>
<view class="gcb-list-card-img-box">
<!-- <img style="width:100%;border-radius: 5px;" :src="info.cover" alt=""> -->
<!-- <image :src="info?.goods_image" style="width: 100%;" :style="{ height: info && info.goods_image?'':'100rpx'}" mode="widthFix"></image> -->
<image :src="info?.goods_image" style="width: 100%;" mode="widthFix"></image>
</view>
<view class="gcb-list-card-info-box">
<view class="g-show-name text-ellipsis-1">{{info?.goods_name}}</view>
<view class="g-desc">
{{info?.desc}}
</view>
<view class="g-buy-box">
<view class="g-price-box" v-if="!noPrice">
<view class="g-price">{{info?.sell_price}}</view>
<view class="g-price-o" v-if="info?.market_price">
{{info?.market_price}}
</view>
</view>
<slot name="btn"></slot>
</view>
</view>
</view>
</view>
</template>
<style lang="scss">
.gcb-list-card-info-box{
width: 70%;
}
.showtype2{
display: flex;
.gcb-list-card-img-box{
// width: 30%;
// padding: 20rpx;
max-height: 200rpx;
max-width: 200rpx;
width: 30%;
border: 1px solid #ececec;
overflow: hidden;
margin-right: 20rpx;
display: flex;
align-items: center;
image{
max-height: 200rpx;
width: 150rpx;
height: 150rpx;
}
}
}
.g-buy-box{
display: flex;
justify-content: space-between;
align-items: center;
.g-cart{
image{
width: 40rpx;
height: 40rpx;
}
}
.g-price-box{
color: #FD5B4E;
display: flex;
align-items: flex-end;
.g-price{
font-size: 36rpx;
margin-right: 10rpx;
font-weight: 600;
}
.g-price-o{
color: gray;
font-size: 28rpx;
text-decoration: line-through;
}
}
}
.g-desc{
color: gray;
font-size: 28rpx;
margin: 20rpx 0;
}
.g-show-name{
margin-top: 20rpx;
font-weight: bolder;
}
.gcb-title{
background: linear-gradient(0deg, #82c8ea, #abdef4);
color: white;
padding: 16rpx 0;
font-size: 36rpx;
font-weight: 600;
text-align: center;
}
.gcb-list{
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 0 20rpx;
.gcb-list-card{
// padding: 20rpx;
width: 48%;
margin: 20rpx 0;
}
}
.goods-card-box{
background: white;
border: 2rpx solid #82c8ea;
border-radius: 20rpx;
overflow: hidden;
.category-box{
text-align: center;
}
}
</style>

@ -0,0 +1,439 @@
<script setup>
//
import { onShow,onLoad,onHide } from "@dcloudio/uni-app"
import {ref,onMounted,nextTick,reactive,watch} from "vue"
import myButton from "@/components/myButton.vue"
import { useStore } from '@/store'
import api from "@/api/index"
const store = useStore()
/*
注意区分show_status-按钮是否有效show_state-是否展示本组件
show_type如果是团购或秒杀无法添加到购物车
*/
const props = defineProps(['show_type','goods_info','btn_text','show_state','show_status','payBtn']);// goods_info:(goodsDetailinfo)
const emits = defineEmits(['choosedOk','choosedDeliveryOk'])
onLoad((e) => {
console.log('规格!!!',props)
// styleObject.value.height = store.systemInfo.screenHeight/1.5+'px'
// console.log(":",styleObject.value)
getDelivery()
})
onShow(() =>{
// styleObject.value.height = store.systemInfo.screenHeight/1.5+'px'
})
watch(
() => props.goods_info,
(newVal, oldVal) => {
info.value = newVal
console.log('监听参数',info.value)
goods_type.value = info.value.type
handleFunc()
}
)
watch(()=>props.show_state,(newVal, oldVal) => {
// console.log(11111,props.show_type)
if(newVal && !deliveryInfo.value) {
getDelivery()
}
styleObject.value.height = store.systemInfo.screenHeight/1.8+'px'
popup.value.open('bottom')
// console.log(deliveryInfo.value)
// console.log(":",props.show_state)
})
//
const goods_type = ref(null)
const update_fields = ref(['cost_price','createtime','market_price','sales','sell_price','stock','weight']) //
const styleObject = ref({
height: '',
})
const info = ref(null)
const total_num = ref(1)
const popup = ref()
const info_text = ref('')
const deliveryInfo = ref(null)
//
async function getDelivery(){ //
const res = await api.getDelivery()
// console.log(res)
if(res.code === 1) {
deliveryInfo.value = res.data
// console.log(deliveryInfo.value)
}
}
function chooseFunc(type){
// type.value = type
// open uni-popup type
popup.value.open(type)
}
function change(e) {
// console.log('' + e.type + ',' + e.show);
}
function handleFunc() {
if(info.value.specs && info.value.specs.length>0) {
choosed_list.value = new Array(info.value.specs.length);
// console.log("choosed_list:",choosed_list.value)
}
}
const choosed_list = ref([])
function choosePopFunc2(i,i2) { //
choosed_list.value[i] = i2
let str = choosed_list.value.join()
getNewinfo(i,i2,str)
}
const current_specs_id = ref(null)
const emitParams = ref({total_num:1})
async function getNewinfo(i,i2,str) {
// console.log(str)
const res = await api.getNewinfo({
goods_id:info.value.id,
ks:str
})
if(res.code === 1) {
info.value.specs[i].choosed_val = i2
//
for(let prop in update_fields.value) {
info.value[update_fields.value[prop]] = res.data[update_fields.value[prop]]
}
info_text.value = res.data.name
// console.log(info.value)
current_specs_id.value = res.data.id
emitParams.value.current_specs_id = res.data.id
emitParams.value.flag_res = checkFunc()
emits('choosedOk',emitParams.value)
}
else{
// res.msg
uni.showToast({
duration:2000,
title:res.msg,
icon:'error'
})
}
}
function changeNumFunc(value){
if(value<info.value.stock && value>0) {
// info.value.sell_price = parseFloat(info.value.sell_price) ++
total_num.value = value
}
else if(value<1) {
total_num.value = 1
}
else{ //
uni.showToast({
title:"超出库存了",
icon:"error"
})
return
}
emitParams.value.total_num = total_num.value
emitParams.value.flag_res = checkFunc()
emits("choosedOk",emitParams.value)
// console.log(value)
}
async function ofunc(type) { //
if(['group','limited'].includes(props.show_type)){ //
return
}
let flag_res = checkFunc()
let iocn_flag = 'success',title = '已加入购物车!'
// console.log(flag_res)
if(!flag_res.flag) {
iocn_flag = 'error',
title = flag_res.text
}
else{
if(goods_type==1) {
//
let warning_text = checkDeliveryInfo()
if(warning_text) {
uni.showToast({
title:warning_text,
icon:"error"
})
return
}
}
let add_res = await addCart()
if(add_res.state) {
popup.value.close()
emitParams.value.state = 1
emitParams.value.flag_res = checkFunc()
store.cartChange = !store.cartChange
emits('choosedOk',emitParams.value)
}
else{
iocn_flag = 'error'
}
title = add_res.msg
}
uni.showToast({
title,
icon:iocn_flag,
duration: 2000,
// mask:true
});
}
async function addCart() {
// let add_res = false
let add_res = {
state:false,
msg:''
}
let params = {
goods_id:info.value.id,
spec_id:current_specs_id.value?current_specs_id.value:-1,
num:total_num.value,
frequency:deliveryInfo.value.frequency[deliveryInfo.value.frequency_index],
delivery_start_time:deliveryInfo.value.start_time[deliveryInfo.value.start_time_index],
need_milk_box:deliveryInfo.value.need_milk_box[deliveryInfo.value.need_milk_box_index]
}
const res = await api.addCart(params)
if(res.code === 1) {
add_res.state = true
}
add_res.msg = res.msg
return add_res
}
function checkDeliveryInfo() { //
if(!deliveryInfo.value) {
return '请选择配送频率'
}
let c_arr = [
{
prop:'frequency_index',
title:'请选择配送频率'
},
{
prop:'start_time_index',
title:'请选择起送时间'
},
{
prop:'need_milk_box_index',
title:'请选择是否需要奶箱'
}
]
// deliveryInfo.value.
for(let i = 0;i<c_arr.length;i++) {
if(!deliveryInfo.value.hasOwnProperty(c_arr[i].prop)) {
return c_arr[i].title
}
}
}
function checkFunc() {
let flag = true
let res_flag = {
flag:true,
text:''
}
if(info.value.specs && info.value.specs.length>0) {
for(let item of info.value.specs) {
if(!item.hasOwnProperty('choosed_val')) {
res_flag.flag = false
res_flag.text = '请选择'+item.title
break;
}
}
}
// console.log(info.value)
return res_flag
}
function chooseDeliveryFunc(prop,title) {
// console.log(prop,title)
deliveryInfo.value[prop] = title
emits('choosedDeliveryOk',{info:deliveryInfo.value})
}
function determine(func) {
emits('payOk')
}
</script>
<template>
<view class="goodsSpecsBox">
<!-- <view class="g-cart btn-css" @tap="chooseFunc('bottom')">
选择
</view> -->
<uni-popup ref="popup" @change="change">
<view class="popup-content" :style="styleObject" >
<!-- 产品主信息 -->
<view class="pc-row main-info">
<view class="pcr-left">
<view class="pcrl-img-box">
<image :src="info?.goods_image" mode=""></image>
</view>
</view>
<view class="pcr-right">
<view class="pcrr-row bold-text">
{{info?.goods_name}}
</view>
<view class="pcrr-row small-text">
产品描述
</view>
<view class="pcrr-row small-text">
{{info?.sellpoint}}
</view>
</view>
</view>
<!-- 规格 -->
<view class="pc-row" v-for="(item,i) in info?.specs">
<view class="pcr-title">
{{item.title}}
</view>
<view class="pc-choose-card-box">
<view @tap="choosePopFunc2(i,i2)" :class="{choosedCard:item.choosed_val==i2}" class="pc-choose-card" v-for="(item2,i2) in item.items">
{{item2.title}}
</view>
</view>
<!-- <view class="small-text">
温馨提示:配送区域为重庆市南岸区四公里到六公里
</view> -->
</view>
<!-- 配送相关选项 -->
<!-- deliveryInfo -->
<template v-if="goods_type == 1">
<view class="pc-row">
<view class="pcr-title">
配送频率
</view>
<view class="pc-choose-card-box">
<view @tap="chooseDeliveryFunc('frequency_index',i2)" :class="{choosedCard:deliveryInfo?.frequency_index==i2}" class="pc-choose-card" v-for="(item2,i2) in deliveryInfo?.frequency">
{{item2}}
</view>
</view>
</view>
<view class="pc-row">
<view class="pcr-title">
起送时间
</view>
<view class="pc-choose-card-box">
<view @tap="chooseDeliveryFunc('start_time_index',i2)" :class="{choosedCard:deliveryInfo?.start_time_index==i2}" class="pc-choose-card" v-for="(item2,i2) in deliveryInfo?.start_time">
{{item2}}
</view>
</view>
</view>
<view class="pc-row">
<view class="pcr-title">
是否需要奶箱
</view>
<view class="pc-choose-card-box">
<view @tap="chooseDeliveryFunc('need_milk_box_index',i2)" :class="{choosedCard:deliveryInfo?.need_milk_box_index==i2}" class="pc-choose-card" v-for="(item2,i2) in deliveryInfo?.need_milk_box">
{{item2}}
</view>
</view>
</view>
</template>
<!-- 数量 -->
<view class="pc-row total-info-box">
<view class="tib-left">
<view class="tib-left-row">
<text class="total-price bold-text">{{parseFloat(info?.sell_price) * total_num}}</text>
<text class="small-text">库存{{info?.stock}}</text>
</view>
<view class="tib-left-row small-text">
{{info_text}}
</view>
</view>
<view class="tib-right">
<uni-number-box :value="total_num" @change="changeNumFunc" />
</view>
</view>
<!-- 按钮 -->
<view class="pc-row total-info-box">
<myButton :invalid="['group','limited'].includes(show_type)" showType="plain" style="width: 100%;" class="op-right" :type="2" @tap="ofunc(3)">
加入购物车
</myButton>
<myButton @tap="determine(1)" v-if="['group','limited'].includes(show_type) && payBtn" style="width: 100%;" class="op-right" :type="2">
{{btn_text}}
</myButton>
<myButton v-else-if="payBtn" style="width: 100%;" class="op-right" :type="2" @tap="determine(1)">
去结算
</myButton>
</view>
</view>
</uni-popup>
</view>
</template>
<style scoped lang="scss">
// .invalidCss .add-btn-part .add-btn {
// color: white !important;
// background-color: #d7d7d7 !important;
// border: 2rpx solid #d7d7d7 !important;
// }
.btn-css{
background: #7CC4E8;
color: white;
padding: 6rpx 40rpx;
border-radius: 20px;
font-size: 28rpx;
white-space: nowrap;
margin-left: 10rpx;
position: relative;
}
//
.total-info-box{
display: flex;
align-items: center;
justify-content: space-between;
.tib-left{
margin-right: 20rpx;
.tib-left-row{
color: red;
margin-bottom: 20rpx;
}
}
}
//
.choosedCard{
background-color: rgb(124, 196, 232) !important;
color: white !important;
}
.goodsSpecsBox{
.popup-content{
padding-top: 40rpx;
background-color: white;
border-radius: 10px 10px 0 0;
overflow: scroll;
.pc-row{
padding:0 40rpx;
padding-bottom: 40rpx;
.pcr-title{
color: gray;
font-size: 30rpx;
padding: 20rpx 0;
}
.pc-choose-card-box{
.pc-choose-card{
display: inline-block;
background: #f1f1f1;
margin-right: 20rpx;
margin-bottom: 20rpx;
padding: 10rpx 20rpx;
border-radius: 10rpx;
// font-weight: bolder;
font-size: 28rpx;
}
}
}
.main-info{
display: flex;
// align-items:;
.pcr-left{
margin-right: 40rpx;
.pcrl-img-box{
border: 2rpx solid #dadada;
width: 180rpx;
height: 180rpx;
image{
width: 180rpx;
height: 180rpx;
}
}
}
.pcr-right{
.pcrr-row{
margin-bottom: 20rpx;
}
}
}
}
}
</style>

@ -0,0 +1,9 @@
<script setup>
</script>
<template>
<view class="testBox">
测试
</view>
</template>
<style>
</style>

@ -0,0 +1,136 @@
<template>
<view class="i-skeleton" :style="{width: 'calc(100% - '+ size +')', background: bgColor}">
<view class="body">
<slot></slot>
</view>
<view class="body" :style="{width: width, height: height}" v-if="rows">
<view class="item_row">
<view class="icon" v-if="icon"></view>
<view class="colunm" v-if="type==='column'" :style="{width: icon ? '75%' : '100%'}">
<view class="rows"
:style="{width: typeof rowsW === 'string' ? rowsW : rowsW[index], height: typeof rowsH === 'string' ? rowsH : rowsH[index] }"
v-for="(item,index) in rows" :key="index"></view>
</view>
<view class="row" v-else-if="type === 'row'">
<view class="rows"
:style="{width: typeof rowsW === 'string' ? rowsW : rowsW[index], height: typeof rowsH === 'string' ? rowsH : rowsH[index] }"
v-for="(item,index) in rows" :key="index"></view>
</view>
</view>
</view>
</view>
</template>
<script lang="ts" setup>
import { defineProps } from 'vue';
const props = defineProps({
type: {
type: String,
default: 'column'
},
size: {
type: String,
default: '64rpx'
},
rows: {
type: Number,
default: 0
},
bgColor: {
type: String,
default: '#FFFFFF'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300rpx'
},
icon: {
type: Boolean,
default: true
},
rowsW: {
type: [String, Array],
default: '300rpx'
},
rowsH: {
type: [String, Array],
default: '20rpx'
}
})
</script>
<style lang="scss" scoped>
.i-skeleton {
margin: 0 auto;
border-radius: 12rpx;
.body {
border-radius: 12rpx;
display: flex;
flex-direction: column;
.item_row {
height: 100%;
display: flex;
flex-direction: row;
align-items: center;
padding: 0 24rpx;
.icon {
width: 120rpx;
height: 120rpx;
background-color: #E6E6F0;
border-radius: 8rpx;
margin-right: 24rpx;
animation-duration: 2s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeHolderShimmer;
animation-timing-function: ease-out;
background: linear-gradient(to right, #E6E6F0 8%, #dddddd 18%, #E6E6F0 33%);
background-size: 800rpx 104rpx;
}
.colunm {
display: flex;
flex-direction: column;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
width: 100%;
.rows {
margin-right: 8rpx;
}
}
.rows {
border-radius: 4rpx;
margin-bottom: 8rpx;
animation-duration: 2s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeHolderShimmer;
animation-timing-function: ease-out;
background: linear-gradient(to right, #E6E6F0 8%, #dddddd 18%, #E6E6F0 33%);
background-size: 800rpx 100rpx;
}
}
}
@keyframes placeHolderShimmer {
0% {
background-position: -400rpx 0
}
100% {
background-position: 400rpx 0
}
}
}
</style>

@ -0,0 +1,128 @@
<template>
<div>
<map class="positFemr" show-location :latitude="latitude" :longitude="longitude" scale="15" :markers="markers"
@regionchange="regionchange" @callouttap="navigation" @markertap="markertaptap" @tap="tapMap">
<cover-view class="among" v-if="showOper">
详情信息
<cover-image />
</cover-view>
</map>
</div>
</template>
<script>
import {
mapState
} from 'vuex'
export default {
props: {
latitude: { //纬度
type: Number,
default: ''
},
longitude: { //经度
type: Number,
default: ''
},
markers: { //点数据
type: Array,
default: []
},
showOper:{
type: Boolean,
default: false
}
},
methods: {
regionchange(e) {
this.$emit('regionchange', e)
},
navigation(e) {
this.$emit('navigation', e)
},
relativeposi() {
uni.createMapContext("map", this).moveToLocation({
latitude: this.latitude,
longitude: this.longitude,
});
},
markertaptap(e) {
this.$emit('markertaptap', e)
},
tapMap(e) {
this.$emit('tapMap', e)
},
},
}
</script>
<style scoped>
.positFemr {
position: fixed;
width: 100%;
height: 100vh;
position: fixed;
top: 0;
left: 0;
}
.coloena {
color: #000;
background: #fff;
padding: 15rpx 20rpx;
border-radius: 5px;
font-size: 28rpx;
box-shadow: 1px 2px 6px 1px rgba(130, 146, 188, 0.3400);
overflow: hidden;
}
.left {
float: left;
width: 78rpx;
height: 78rpx;
border-radius: 50%;
margin-top: 5rpx;
}
.right {
margin-left: 90rpx;
font-weight: none;
}
.tieoarr {
font-weight: bold;
margin-bottom: 10rpx;
}
.imgSieor {
width: 136rpx;
height: 80rpx;
display: inline-block;
}
.maoetop {
margin-right: 10rpx;
display: inline-block;
}
.maoetop1 {
color: #0F2E51FF;
display: inline-block;
}
.maoetop2 {
color: #46C166FF;
display: inline-block;
}
.among {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 200rpx;
background: red;
}
</style>

@ -0,0 +1,46 @@
<script setup>
import { ref } from 'vue'
const props = defineProps(['bgcolor','type','showType','invalid'])
// const type = ref(1) // 1-;2-
</script>
<template>
<view class="buttonBox">
<view class="add-btn-part" :class="{normalCss:type==2,plainCss:showType=='plain'}">
<view class="add-btn" :style="{ background: bgcolor?bgcolor:'#7cc4e8'}" :class="{plainCss:showType=='plain',invalidCssBtn:invalid}">
<slot></slot>
</view>
</view>
</view>
</template>
<style scoped lang="scss">
.normalCss{
position: unset !important;
bottom: unset !important;
width: 100%;
}
.plainCss{
background: white !important;
color: #7cc4e8 !important;
}
.invalidCssBtn{
color: white !important;
background-color: #d7d7d7 !important;
border: 2rpx solid #d7d7d7 !important;
}
.add-btn-part{
position: fixed;
bottom: 40rpx;
width: 100%;
.add-btn{
margin: 0 auto;
width: 80%;
text-align: center;
background: #7cc4e8;
border: 1px solid #7cc4e8;
color: white;
padding: 10px 0;
border-radius: 40rpx;
}
}
</style>

@ -0,0 +1,298 @@
<script setup>
//
import { onShow,onLoad,onHide } from "@dcloudio/uni-app"
import {ref,onMounted,nextTick,reactive,watch} from "vue"
import myButton from "@/components/myButton.vue"
import { useStore } from '@/store'
import api from "@/api/index"
import goodsInfo from "@/components/goodsInfo.vue"
import emptyCard from "@/components/emptyCard.vue"
const store = useStore()
const props = defineProps(['coupon_show','coupon_list']);
const emits = defineEmits(['choosedOk'])
import utils from "@/utils/index.js"
onLoad((e) => {
styleObject.value.height = store.systemInfo.screenHeight/1.8+'px'
// console.log(":",props.goods_info)
// getList()
})
watch(
() => props.coupon_list,
(newVal, oldVal) => {
// info.value = newVal
list.value = newVal
console.log(newVal)
updateList()
}
)
watch(
()=>props.coupon_show,
(newVal, oldVal) => {
cart_popup.value.open('bottom')
})
//
const list = ref([])
const cart_popup = ref()
const styleObject = ref({
height: '0px',
})
const total_num = ref(1)
const current_ = ref(-1)
//
function updateList(){
// console.log(list.value)
if(list.value && list.value.length>0) {
for(let item of list.value) {
// item.goods_image = item.goods.goods_image
// item.goods_name = item.goods.goods_name
// item.goods_id = item.goods.id
// item.sell_price = item.price * item.num
// item.single_price = item.price
// item.desc = item.spec.name+','+item.spec.sell_price
}
}
}
// async function getList() { //
// const res = await api.getCartList()
// if(res.code ===1) {
// list.value = res.data
// }
// }
// function changeNumFunc(value){
// setTimeout(() => {
// // console.log(value,current_.value)
// if(value>0) {
// list.value[current_.value].num = value
// list.value[current_.value].sell_price = list.value[current_.value].single_price * value
// // list.value[current_.value].price = value
// //
// emits('update_cart',[list.value[current_.value].id,list.value[current_.value].num])
// }
// else if(value<1) { //
// // total_num.value = 1
// emits('del_cart',[list.value[current_.value].id])
// }
// else{ //
// }
// },0)
// }
// function lockItem(i) { //
// current_.value = i
// }
async function toUseFunc(item,i) { //
current_.value = i
// const res = await api.couponsCenterReceive({
// coupon_id:item.id
// })
// if(res.code === 1) {
// uni.showToast({
// title:"",
// icon:"success"
// })
// // getList()
// }
}
function ofunc() {
if(current_.value==-1) {
uni.showToast({
title:"请选择优惠券",
icon:"error"
})
}
else{
// console.log(list.value[current_.value])
cart_popup.value.close()
emits("choosedOk",list.value[current_.value])
}
}
function timestampToDate(stamp) { //
var time = new Date(stamp);
var y = time.getFullYear();
var m = time.getMonth()+1;
var d = time.getDate();
const date = `${y}-${m}-${d}`
return date
}
</script>
<template>
<view class="goodsCartBox">
<uni-popup ref="cart_popup" @change="change">
<view class="popup-content" :style="styleObject" >
<view class="pc-top">
<view class="pc-top-left">
优惠券
<!-- <text style="color: gray;">({{list.length}})</text> -->
</view>
<!-- <view class="pc-top-right" style="color: gray;" @click="clearFunc">
清空购物车
</view> -->
</view>
<view class="pc-content couponBox">
<!-- <view class="list-row" v-for="(item,i) in list" @tap="lockItem(i)">
<goodsInfo :type="2" :info="item" >
<template #btn>
<uni-number-box :value="item.num" @change="changeNumFunc" />
</template>
</goodsInfo>
</view> -->
<view class="c-part" v-if="list.length>0" @tap="toUseFunc(item,i)" v-for="(item,i) in list">
<view class="state-css small-text" v-if="item.bind_type == 1">
<!-- 已领取 -->
<!-- <image src="../../static/had.png" mode="widthFix"></image> -->
</view>
<view class="cp-row" style="padding-bottom: 0px;">
<view class="cpr-left">
{{item.coupon_name}}
</view>
<view class="cpr-right" style="color: red;">
<text class="big-text">{{item.money}}</text>
</view>
</view>
<view class="cp-row small-text" style="padding-top: 0px;">
<view class="cpr-left">
有效期至{{item.expire_time}}
</view>
<view class="cpr-right">
<text class="red-text">{{item.num}}可用</text>
</view>
</view>
<view class="line"></view>
<view class="cp-row small-text">
<view class="cpr-left">
指定商品可用
</view>
<view class="cpr-right">
<view class="checkBox-css">
<uni-icons v-if="current_ == i" type="checkmarkempty" size="20"></uni-icons>
</view>
</view>
</view>
</view>
<emptyCard v-else></emptyCard>
</view>
<view class="pc-bottom" style="padding: 40rpx 0 ;">
<!-- 按钮 -->
<myButton v-if="list.length>0" style="width: 100%;" class="op-right" :type="2" @tap="ofunc">
确认使用
</myButton>
</view>
</view>
</uni-popup>
</view>
</template>
<style scoped lang="scss">
.checkBox-css{
width: 34rpx;
height: 34rpx;
border: 1px solid #cacaca;
}
/*
优惠券
*/
.hasDone{
background-color: #cccccc !important;
}
.state-css{
position: absolute;
right: 0;
image{
width: 100rpx;
}
}
.button-css{
background-color: red;
color: white;
border-radius: 10rpx;
padding: 6rpx 20rpx;
}
.couponBox{
.c-part{
background-color: white;
margin: 20rpx;
border-radius: 5px;
.cp-row{
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx 30rpx;
}
}
}
.pc-bottom{
position: fixed;
width: 100%;
bottom: 20rpx;
}
.goodsCartBox{
.popup-content{
position: relative;
padding-top: 40rpx;
background-color: white;
border-radius: 10px 10px 0 0;
overflow: scroll;
background: #f2f2f2;
.pc-top{
position: fixed;
top:120rpx;
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
box-sizing: border-box;
padding: 40rpx;
background-color: white;
z-index: 10;
border-bottom: 1px solid #eaeaea;
}
.pc-content{
.list-row{
padding: 20rpx;
}
margin-bottom: 240rpx;
margin-top: 100rpx;
}
.pc-row{
padding:0 40rpx;
padding-bottom: 40rpx;
.pcr-title{
color: gray;
font-size: 30rpx;
padding: 20rpx 0;
}
.pc-choose-card-box{
.pc-choose-card{
display: inline-block;
background: #f1f1f1;
margin-right: 20rpx;
margin-bottom: 20rpx;
padding: 10rpx 20rpx;
border-radius: 10rpx;
// font-weight: bolder;
font-size: 28rpx;
}
}
}
.main-info{
display: flex;
// align-items:;
.pcr-left{
margin-right: 40rpx;
.pcrl-img-box{
border: 2rpx solid #dadada;
width: 180rpx;
height: 180rpx;
image{
width: 180rpx;
height: 180rpx;
}
}
}
.pcr-right{
.pcrr-row{
margin-bottom: 20rpx;
}
}
}
}
}
</style>

@ -0,0 +1,97 @@
<script setup>
//
import {watch,ref,reactive} from "vue"
// props
const props = defineProps(['lbt_list',"height","isRadius","indicatorDots"])
//
const interval = ref(2000)
const autoplay = ref(true)
// const indicatorDots = ref(false)
//
watch(()=> {
return props.lbt_list
},(val1,val2) => {
// console.log(val1)
})
//
function intervalChange(e) {
interval.value = e.target.value
}
function lbtFunc(item) {
//
uni.navigateTo({
url:item.url
});
return
//
// if(item.skip_url_type == 2) { //
// uni.navigateTo({
// url:item.skip_url
// });
// }
// else{ //
// uni.navigateTo({
// url:`/pages/webview/webview?links=${item.skip_url}&name=${item.name}`
// });
// }
}
</script>
<template>
<view class="swiper-box">
<view class="uni-margin-wrap">
<swiper class="swiper" :class="{radiuscss:isRadius}" :style="'height: '+height*2+'rpx;'" circular :indicator-dots="indicatorDots" :autoplay="autoplay" :interval="interval"
:duration="duration">
<swiper-item @click="lbtFunc(item)" v-for="(item,i) in lbt_list">
<view class="swiper-item uni-bg-red">
<!-- <img style="width: 100%;" :src="item.url" alt=""> -->
<image :src="item.image" style="width: 100%;" mode="widthFix"></image>
</view>
</swiper-item>
</swiper>
</view>
</view>
</template>
<style>
.radiuscss{
border-radius:30rpx;
overflow: hidden;
}
.swiper-box{
}
.swiper-item>img{
width: 100%;
}
.uni-margin-wrap {
width: 690rpx;
width: 100%;
}
.swiper {
height: 300rpx;
}
.swiper-item {
display: block;
height: 300rpx;
line-height: 300rpx;
text-align: center;
}
.swiper-list {
margin-top: 40rpx;
margin-bottom: 0;
}
.uni-common-mt {
margin-top: 60rpx;
position: relative;
}
.info {
position: absolute;
right: 20rpx;
}
.uni-padding-wrap {
width: 550rpx;
padding: 0 100rpx;
}
</style>

@ -0,0 +1,71 @@
<script setup>
import { ref} from "vue"
const props = defineProps(['type','list'])
const showAll = ref(false)
function switchFunc() {
showAll.value=!showAll.value
console.log(showAll.value)
}
function toDetailFunc(item) {
uni.navigateTo({
url:"/pages/notice/index?content="+encodeURIComponent(item.content)
})
}
</script>
<template>
<view class="notice-box">
<view class="n-row" v-if="!showAll" @tap="toDetailFunc(list[0])">
<view class="nr-left">
<image class="icon-custom" src="@/static/notice.png" mode=""></image>
<view class="nr-text text-ellipsis-1" :class="{smalltext:type=='small'}">
{{list[0]?.content}}
</view>
</view>
<view v-if="list.length > 1 && !showAll" class="showmore-btn" @tap="switchFunc" :class="{smalltext:type=='small'}">
更多
<uni-icons type="bottom" size="15"></uni-icons>
</view>
</view>
<view class="n-row-part" v-else>
<view class="n-row" v-for="(item,i) in list" @tap="toDetailFunc(item)">
<view class="nr-left">
<image class="icon-custom" src="@/static/notice.png" mode=""></image>
<view class="nr-text text-ellipsis-1" :class="{smalltext:type=='small'}">
{{item?.content}}
</view>
</view>
</view>
<view v-if="showAll" class="showmore-btn" style="text-align: right;" :class="{smalltext:type=='small'}">
<text @tap="switchFunc"></text>
<uni-icons type="top" size="15"></uni-icons>
</view>
</view>
</view>
</template>
<style lang="scss">
.smalltext{
color: gray !important;
font-size: 28rpx !important;
font-weight: unset !important;
}
.n-row{
display: flex;
justify-content: space-between;
margin: 20rpx 0;
.icon-custom{
margin-right: 10px;
}
.nr-left{
display: flex;
align-items: center;
}
.nr-text{
width: 85%;
font-weight: bolder;
}
.showmore-btn{
white-space: nowrap;
}
}
</style>

@ -0,0 +1,61 @@
<script setup>
import { useStore } from '@/store'
const store = useStore()
// props
const props = defineProps(['width'])
</script>
<template>
<!-- <view class="custom-status-bar" id="custom-status-bar" :style="{paddingTop: `${store.status_bar_height}px`,width:`${width}`}"> -->
<view class="custom-status-bar" id="custom-status-bar" :style="{width:`${width}`}">
<view class="empty-wrap"></view>
<view class="search-box">
<input class="uni-input" confirm-type="search" placeholder="" />
<view class="search-btn">
<icon style="color: rgb(248, 248, 248);" type="search" size="16"/>
</view>
</view>
</view>
</template>
<style>
.empty-wrap{
width: 100%;
height:20rpx;
}
.search-btn{
position: absolute;
/* right: 0%; */
/* background: #26758d; */
color: white;
width: 63rpx;
height: 63rpx;
/* border-radius: 50%; */
text-align: center;
line-height: 50%;
display: flex;
align-items: center;
justify-content: center;
/* box-shadow: -1px 1px 10px grey; */
}
.uni-input{
width: 100%;
padding: 20rpx;
/* margin: 20rpx 0; */
/* border: 2rpx solid #e7e7e7; */
/* border-radius: 100rpx; */
font-size: 20rpx;
color: gray;
}
.search-box{
display: flex;
/* width: 95%; */
align-items: center;
position: relative;
/* width: 100%; */
/* position: fixed; */
top:0px;
background: white;
z-index: 10;
border-radius: 100rpx;
border: 2rpx solid #eeeeee;
}
</style>

@ -0,0 +1,21 @@
// isdev 为 true 表示开发环境 false 表示发布环境
const isdev = true;
const baseUrl = isdev ? 'http://niunai.zhitou1688.com' : 'http://niunai.zhitou1688.com';// 办公室接口 & 测试环境
// const baseUrl = isdev ? 'http://192.168.1.133:8899' : 'https://api.gwkjxb.com';// 办公室接口 & 正式环境
// const baseUrl = 'https://api.gwkjxb.com';// 正式环境(由于本地测试后台没有启动,暂时通用正式服)
// const baseUrl = isdev ? 'http://1.117.68.37:8000' : 'https://apiwx.twzxjy.com';// 支付测试接口
const shareUrl = isdev ? 'https://h5.gwkjxb.com/' : 'http://test_h5.gwkjxb.com/';
const teacher_admin_url = 'http://teacher.gwkjxb.com/#/login'
const config = {
appName: '牛奶配送',
baseUrl,
appVersion: '1.0.6',
developer: '牛奶配送',
// appLogo: require('../static/logo.png'),
shareUrl,
teacher_admin_url,
appID:'wx2a050f9a5c87a6dc',
isdev
}
export default config

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>

@ -0,0 +1,24 @@
import App from './App'
// #ifndef VUE3
import Vue from 'vue'
import './uni.promisify.adaptor'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import * as Pinia from 'pinia';
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
app.use(Pinia.createPinia())
return {
app
}
}
// #endif

@ -0,0 +1,72 @@
{
"name" : "vision-record",
"appid" : "__UNI__A2B2065",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* */
"modules" : {},
/* */
"distribute" : {
/* android */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios */
"ios" : {},
/* SDK */
"sdkConfigs" : {}
}
},
/* */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "3"
}

12
node_modules/.bin/vue-demi-fix generated vendored

@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../vue-demi/bin/vue-demi-fix.js" "$@"
else
exec node "$basedir/../vue-demi/bin/vue-demi-fix.js" "$@"
fi

@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\vue-demi\bin\vue-demi-fix.js" %*

@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../vue-demi/bin/vue-demi-fix.js" $args
} else {
& "$basedir/node$exe" "$basedir/../vue-demi/bin/vue-demi-fix.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../vue-demi/bin/vue-demi-fix.js" $args
} else {
& "node$exe" "$basedir/../vue-demi/bin/vue-demi-fix.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret

12
node_modules/.bin/vue-demi-switch generated vendored

@ -0,0 +1,12 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../vue-demi/bin/vue-demi-switch.js" "$@"
else
exec node "$basedir/../vue-demi/bin/vue-demi-switch.js" "$@"
fi

@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\vue-demi\bin\vue-demi-switch.js" %*

@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../vue-demi/bin/vue-demi-switch.js" $args
} else {
& "$basedir/node$exe" "$basedir/../vue-demi/bin/vue-demi-switch.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../vue-demi/bin/vue-demi-switch.js" $args
} else {
& "node$exe" "$basedir/../vue-demi/bin/vue-demi-switch.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret

69
node_modules/.package-lock.json generated vendored

@ -0,0 +1,69 @@
{
"name": "version-record",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"node_modules/@vue/devtools-api": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz",
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
},
"node_modules/pinia": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.6.tgz",
"integrity": "sha512-bIU6QuE5qZviMmct5XwCesXelb5VavdOWKWaB17ggk++NUwQWWbP5YnsONTk3b752QkW9sACiR81rorpeOMSvQ==",
"dependencies": {
"@vue/devtools-api": "^6.5.0",
"vue-demi": ">=0.14.5"
},
"funding": {
"url": "https://github.com/sponsors/posva"
},
"peerDependencies": {
"@vue/composition-api": "^1.4.0",
"typescript": ">=4.4.4",
"vue": "^2.6.14 || ^3.3.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
},
"typescript": {
"optional": true
}
}
},
"node_modules/vue": {
"version": "2.6.14",
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz",
"integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==",
"peer": true
},
"node_modules/vue-demi": {
"version": "0.14.6",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
}
}
}

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

@ -0,0 +1,22 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./api.js"), exports);
__exportStar(require("./app.js"), exports);
__exportStar(require("./component.js"), exports);
__exportStar(require("./context.js"), exports);
__exportStar(require("./hooks.js"), exports);
__exportStar(require("./util.js"), exports);

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

@ -0,0 +1,5 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HOOK_PLUGIN_SETTINGS_SET = exports.HOOK_SETUP = void 0;
exports.HOOK_SETUP = 'devtools-plugin:setup';
exports.HOOK_PLUGIN_SETTINGS_SET = 'plugin:settings:set';

@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isProxyAvailable = exports.getTarget = exports.getDevtoolsGlobalHook = void 0;
function getDevtoolsGlobalHook() {
return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__;
}
exports.getDevtoolsGlobalHook = getDevtoolsGlobalHook;
function getTarget() {
// @ts-ignore
return (typeof navigator !== 'undefined' && typeof window !== 'undefined')
? window
: typeof global !== 'undefined'
? global
: {};
}
exports.getTarget = getTarget;
exports.isProxyAvailable = typeof Proxy === 'function';

@ -0,0 +1,44 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.setupDevtoolsPlugin = void 0;
const env_js_1 = require("./env.js");
const const_js_1 = require("./const.js");
const proxy_js_1 = require("./proxy.js");
__exportStar(require("./api/index.js"), exports);
__exportStar(require("./plugin.js"), exports);
__exportStar(require("./time.js"), exports);
function setupDevtoolsPlugin(pluginDescriptor, setupFn) {
const descriptor = pluginDescriptor;
const target = (0, env_js_1.getTarget)();
const hook = (0, env_js_1.getDevtoolsGlobalHook)();
const enableProxy = env_js_1.isProxyAvailable && descriptor.enableEarlyProxy;
if (hook && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) {
hook.emit(const_js_1.HOOK_SETUP, pluginDescriptor, setupFn);
}
else {
const proxy = enableProxy ? new proxy_js_1.ApiProxy(descriptor, hook) : null;
const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || [];
list.push({
pluginDescriptor: descriptor,
setupFn,
proxy,
});
if (proxy)
setupFn(proxy.proxiedTarget);
}
}
exports.setupDevtoolsPlugin = setupDevtoolsPlugin;

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

@ -0,0 +1,111 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ApiProxy = void 0;
const const_js_1 = require("./const.js");
const time_js_1 = require("./time.js");
class ApiProxy {
constructor(plugin, hook) {
this.target = null;
this.targetQueue = [];
this.onQueue = [];
this.plugin = plugin;
this.hook = hook;
const defaultSettings = {};
if (plugin.settings) {
for (const id in plugin.settings) {
const item = plugin.settings[id];
defaultSettings[id] = item.defaultValue;
}
}
const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`;
let currentSettings = Object.assign({}, defaultSettings);
try {
const raw = localStorage.getItem(localSettingsSaveId);
const data = JSON.parse(raw);
Object.assign(currentSettings, data);
}
catch (e) {
// noop
}
this.fallbacks = {
getSettings() {
return currentSettings;
},
setSettings(value) {
try {
localStorage.setItem(localSettingsSaveId, JSON.stringify(value));
}
catch (e) {
// noop
}
currentSettings = value;
},
now() {
return (0, time_js_1.now)();
},
};
if (hook) {
hook.on(const_js_1.HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => {
if (pluginId === this.plugin.id) {
this.fallbacks.setSettings(value);
}
});
}
this.proxiedOn = new Proxy({}, {
get: (_target, prop) => {
if (this.target) {
return this.target.on[prop];
}
else {
return (...args) => {
this.onQueue.push({
method: prop,
args,
});
};
}
},
});
this.proxiedTarget = new Proxy({}, {
get: (_target, prop) => {
if (this.target) {
return this.target[prop];
}
else if (prop === 'on') {
return this.proxiedOn;
}
else if (Object.keys(this.fallbacks).includes(prop)) {
return (...args) => {
this.targetQueue.push({
method: prop,
args,
resolve: () => { },
});
return this.fallbacks[prop](...args);
};
}
else {
return (...args) => {
return new Promise(resolve => {
this.targetQueue.push({
method: prop,
args,
resolve,
});
});
};
}
},
});
}
async setRealTarget(target) {
this.target = target;
for (const item of this.onQueue) {
this.target.on[item.method](...item.args);
}
for (const item of this.targetQueue) {
item.resolve(await this.target[item.method](...item.args));
}
}
}
exports.ApiProxy = ApiProxy;

@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.now = exports.isPerformanceSupported = void 0;
let supported;
let perf;
function isPerformanceSupported() {
var _a;
if (supported !== undefined) {
return supported;
}
if (typeof window !== 'undefined' && window.performance) {
supported = true;
perf = window.performance;
}
else if (typeof global !== 'undefined' && ((_a = global.perf_hooks) === null || _a === void 0 ? void 0 : _a.performance)) {
supported = true;
perf = global.perf_hooks.performance;
}
else {
supported = false;
}
return supported;
}
exports.isPerformanceSupported = isPerformanceSupported;
function now() {
return isPerformanceSupported() ? perf.now() : Date.now();
}
exports.now = now;

@ -0,0 +1,108 @@
import type { ComponentBounds, Hookable } from './hooks.js';
import type { Context } from './context.js';
import type { ComponentInstance, ComponentState, StateBase } from './component.js';
import type { App } from './app.js';
import type { ID } from './util.js';
export interface DevtoolsPluginApi<TSettings> {
on: Hookable<Context>;
notifyComponentUpdate(instance?: ComponentInstance): void;
addTimelineLayer(options: TimelineLayerOptions): void;
addTimelineEvent(options: TimelineEventOptions): void;
addInspector(options: CustomInspectorOptions): void;
sendInspectorTree(inspectorId: string): void;
sendInspectorState(inspectorId: string): void;
selectInspectorNode(inspectorId: string, nodeId: string): void;
getComponentBounds(instance: ComponentInstance): Promise<ComponentBounds>;
getComponentName(instance: ComponentInstance): Promise<string>;
getComponentInstances(app: App): Promise<ComponentInstance[]>;
highlightElement(instance: ComponentInstance): void;
unhighlightElement(): void;
getSettings(pluginId?: string): TSettings;
now(): number;
/**
* @private Not implemented yet
*/
setSettings(values: TSettings): void;
}
export interface AppRecord {
id: string;
name: string;
instanceMap: Map<string, ComponentInstance>;
rootInstance: ComponentInstance;
}
export interface TimelineLayerOptions<TData = any, TMeta = any> {
id: string;
label: string;
color: number;
skipScreenshots?: boolean;
groupsOnly?: boolean;
ignoreNoDurationGroups?: boolean;
screenshotOverlayRender?: (event: TimelineEvent<TData, TMeta> & ScreenshotOverlayEvent, ctx: ScreenshotOverlayRenderContext) => ScreenshotOverlayRenderResult | Promise<ScreenshotOverlayRenderResult>;
}
export interface ScreenshotOverlayEvent {
layerId: string;
renderMeta: any;
}
export interface ScreenshotOverlayRenderContext<TData = any, TMeta = any> {
screenshot: ScreenshotData;
events: (TimelineEvent<TData, TMeta> & ScreenshotOverlayEvent)[];
index: number;
}
export declare type ScreenshotOverlayRenderResult = HTMLElement | string | false;
export interface ScreenshotData {
time: number;
}
export interface TimelineEventOptions {
layerId: string;
event: TimelineEvent;
all?: boolean;
}
export interface TimelineEvent<TData = any, TMeta = any> {
time: number;
data: TData;
logType?: 'default' | 'warning' | 'error';
meta?: TMeta;
groupId?: ID;
title?: string;
subtitle?: string;
}
export interface TimelineMarkerOptions {
id: string;
time: number;
color: number;
label: string;
all?: boolean;
}
export interface CustomInspectorOptions {
id: string;
label: string;
icon?: string;
treeFilterPlaceholder?: string;
stateFilterPlaceholder?: string;
noSelectionText?: string;
actions?: {
icon: string;
tooltip?: string;
action: () => void | Promise<void>;
}[];
nodeActions?: {
icon: string;
tooltip?: string;
action: (nodeId: string) => void | Promise<void>;
}[];
}
export interface CustomInspectorNode {
id: string;
label: string;
children?: CustomInspectorNode[];
tags?: InspectorNodeTag[];
}
export interface InspectorNodeTag {
label: string;
textColor: number;
backgroundColor: number;
tooltip?: string;
}
export interface CustomInspectorState {
[key: string]: (StateBase | Omit<ComponentState, 'type'>)[];
}

@ -0,0 +1 @@
export {};

@ -0,0 +1 @@
export declare type App = any;

@ -0,0 +1 @@
export {};

@ -0,0 +1,78 @@
import type { InspectorNodeTag } from './api.js';
import type { ID } from './util.js';
export declare type ComponentInstance = any;
export interface ComponentTreeNode {
uid: ID;
id: string;
name: string;
renderKey: string | number;
inactive: boolean;
isFragment: boolean;
hasChildren: boolean;
children: ComponentTreeNode[];
domOrder?: number[];
consoleId?: string;
isRouterView?: boolean;
macthedRouteSegment?: string;
tags: InspectorNodeTag[];
autoOpen: boolean;
meta?: any;
}
export interface InspectedComponentData {
id: string;
name: string;
file: string;
state: ComponentState[];
functional?: boolean;
}
export interface StateBase {
key: string;
value: any;
editable?: boolean;
objectType?: 'ref' | 'reactive' | 'computed' | 'other';
raw?: string;
}
export interface ComponentStateBase extends StateBase {
type: string;
}
export interface ComponentPropState extends ComponentStateBase {
meta?: {
type: string;
required: boolean;
/** Vue 1 only */
mode?: 'default' | 'sync' | 'once';
};
}
export declare type ComponentBuiltinCustomStateTypes = 'function' | 'map' | 'set' | 'reference' | 'component' | 'component-definition' | 'router' | 'store';
export interface ComponentCustomState extends ComponentStateBase {
value: CustomState;
}
export declare type CustomState = {
_custom: {
type: ComponentBuiltinCustomStateTypes | string;
objectType?: string;
display?: string;
tooltip?: string;
value?: any;
abstract?: boolean;
file?: string;
uid?: number;
readOnly?: boolean;
/** Configure immediate child fields */
fields?: {
abstract?: boolean;
};
id?: any;
actions?: {
icon: string;
tooltip?: string;
action: () => void | Promise<void>;
}[];
/** internal */
_reviveId?: number;
};
};
export declare type ComponentState = ComponentStateBase | ComponentPropState | ComponentCustomState;
export interface ComponentDevtoolsOptions {
hide?: boolean;
}

@ -0,0 +1,5 @@
import type { AppRecord } from './api.js';
export interface Context {
currentTab: string;
currentAppRecord: AppRecord;
}

@ -0,0 +1,180 @@
import type { ComponentTreeNode, InspectedComponentData, ComponentInstance, ComponentDevtoolsOptions } from './component.js';
import type { App } from './app.js';
import type { CustomInspectorNode, CustomInspectorState, TimelineEvent } from './api.js';
export declare const enum Hooks {
TRANSFORM_CALL = "transformCall",
GET_APP_RECORD_NAME = "getAppRecordName",
GET_APP_ROOT_INSTANCE = "getAppRootInstance",
REGISTER_APPLICATION = "registerApplication",
WALK_COMPONENT_TREE = "walkComponentTree",
VISIT_COMPONENT_TREE = "visitComponentTree",
WALK_COMPONENT_PARENTS = "walkComponentParents",
INSPECT_COMPONENT = "inspectComponent",
GET_COMPONENT_BOUNDS = "getComponentBounds",
GET_COMPONENT_NAME = "getComponentName",
GET_COMPONENT_INSTANCES = "getComponentInstances",
GET_ELEMENT_COMPONENT = "getElementComponent",
GET_COMPONENT_ROOT_ELEMENTS = "getComponentRootElements",
EDIT_COMPONENT_STATE = "editComponentState",
GET_COMPONENT_DEVTOOLS_OPTIONS = "getAppDevtoolsOptions",
GET_COMPONENT_RENDER_CODE = "getComponentRenderCode",
INSPECT_TIMELINE_EVENT = "inspectTimelineEvent",
TIMELINE_CLEARED = "timelineCleared",
GET_INSPECTOR_TREE = "getInspectorTree",
GET_INSPECTOR_STATE = "getInspectorState",
EDIT_INSPECTOR_STATE = "editInspectorState",
SET_PLUGIN_SETTINGS = "setPluginSettings"
}
export interface ComponentBounds {
left: number;
top: number;
width: number;
height: number;
}
export declare type HookPayloads = {
[Hooks.TRANSFORM_CALL]: {
callName: string;
inArgs: any[];
outArgs: any[];
};
[Hooks.GET_APP_RECORD_NAME]: {
app: App;
name: string;
};
[Hooks.GET_APP_ROOT_INSTANCE]: {
app: App;
root: ComponentInstance;
};
[Hooks.REGISTER_APPLICATION]: {
app: App;
};
[Hooks.WALK_COMPONENT_TREE]: {
componentInstance: ComponentInstance;
componentTreeData: ComponentTreeNode[];
maxDepth: number;
filter: string;
recursively: boolean;
};
[Hooks.VISIT_COMPONENT_TREE]: {
app: App;
componentInstance: ComponentInstance;
treeNode: ComponentTreeNode;
filter: string;
};
[Hooks.WALK_COMPONENT_PARENTS]: {
componentInstance: ComponentInstance;
parentInstances: ComponentInstance[];
};
[Hooks.INSPECT_COMPONENT]: {
app: App;
componentInstance: ComponentInstance;
instanceData: InspectedComponentData;
};
[Hooks.GET_COMPONENT_BOUNDS]: {
componentInstance: ComponentInstance;
bounds: ComponentBounds;
};
[Hooks.GET_COMPONENT_NAME]: {
componentInstance: ComponentInstance;
name: string;
};
[Hooks.GET_COMPONENT_INSTANCES]: {
app: App;
componentInstances: ComponentInstance[];
};
[Hooks.GET_ELEMENT_COMPONENT]: {
element: HTMLElement | any;
componentInstance: ComponentInstance;
};
[Hooks.GET_COMPONENT_ROOT_ELEMENTS]: {
componentInstance: ComponentInstance;
rootElements: (HTMLElement | any)[];
};
[Hooks.EDIT_COMPONENT_STATE]: {
app: App;
componentInstance: ComponentInstance;
path: string[];
type: string;
state: EditStatePayload;
set: (object: any, path?: string | (string[]), value?: any, cb?: (object: any, field: string, value: any) => void) => void;
};
[Hooks.GET_COMPONENT_DEVTOOLS_OPTIONS]: {
componentInstance: ComponentInstance;
options: ComponentDevtoolsOptions;
};
[Hooks.GET_COMPONENT_RENDER_CODE]: {
componentInstance: ComponentInstance;
code: string;
};
[Hooks.INSPECT_TIMELINE_EVENT]: {
app: App;
layerId: string;
event: TimelineEvent;
all?: boolean;
data: any;
};
[Hooks.TIMELINE_CLEARED]: Record<string, never>;
[Hooks.GET_INSPECTOR_TREE]: {
app: App;
inspectorId: string;
filter: string;
rootNodes: CustomInspectorNode[];
};
[Hooks.GET_INSPECTOR_STATE]: {
app: App;
inspectorId: string;
nodeId: string;
state: CustomInspectorState;
};
[Hooks.EDIT_INSPECTOR_STATE]: {
app: App;
inspectorId: string;
nodeId: string;
path: string[];
type: string;
state: EditStatePayload;
set: (object: any, path?: string | (string[]), value?: any, cb?: (object: any, field: string, value: any) => void) => void;
};
[Hooks.SET_PLUGIN_SETTINGS]: {
app: App;
pluginId: string;
key: string;
newValue: any;
oldValue: any;
settings: any;
};
};
export declare type EditStatePayload = {
value: any;
newKey?: string | null;
remove?: undefined | false;
} | {
value?: undefined;
newKey?: undefined;
remove: true;
};
export declare type HookHandler<TPayload, TContext> = (payload: TPayload, ctx: TContext) => void | Promise<void>;
export interface Hookable<TContext> {
transformCall(handler: HookHandler<HookPayloads[Hooks.TRANSFORM_CALL], TContext>): any;
getAppRecordName(handler: HookHandler<HookPayloads[Hooks.GET_APP_RECORD_NAME], TContext>): any;
getAppRootInstance(handler: HookHandler<HookPayloads[Hooks.GET_APP_ROOT_INSTANCE], TContext>): any;
registerApplication(handler: HookHandler<HookPayloads[Hooks.REGISTER_APPLICATION], TContext>): any;
walkComponentTree(handler: HookHandler<HookPayloads[Hooks.WALK_COMPONENT_TREE], TContext>): any;
visitComponentTree(handler: HookHandler<HookPayloads[Hooks.VISIT_COMPONENT_TREE], TContext>): any;
walkComponentParents(handler: HookHandler<HookPayloads[Hooks.WALK_COMPONENT_PARENTS], TContext>): any;
inspectComponent(handler: HookHandler<HookPayloads[Hooks.INSPECT_COMPONENT], TContext>): any;
getComponentBounds(handler: HookHandler<HookPayloads[Hooks.GET_COMPONENT_BOUNDS], TContext>): any;
getComponentName(handler: HookHandler<HookPayloads[Hooks.GET_COMPONENT_NAME], TContext>): any;
getComponentInstances(handler: HookHandler<HookPayloads[Hooks.GET_COMPONENT_INSTANCES], TContext>): any;
getElementComponent(handler: HookHandler<HookPayloads[Hooks.GET_ELEMENT_COMPONENT], TContext>): any;
getComponentRootElements(handler: HookHandler<HookPayloads[Hooks.GET_COMPONENT_ROOT_ELEMENTS], TContext>): any;
editComponentState(handler: HookHandler<HookPayloads[Hooks.EDIT_COMPONENT_STATE], TContext>): any;
getComponentDevtoolsOptions(handler: HookHandler<HookPayloads[Hooks.GET_COMPONENT_DEVTOOLS_OPTIONS], TContext>): any;
getComponentRenderCode(handler: HookHandler<HookPayloads[Hooks.GET_COMPONENT_RENDER_CODE], TContext>): any;
inspectTimelineEvent(handler: HookHandler<HookPayloads[Hooks.INSPECT_TIMELINE_EVENT], TContext>): any;
timelineCleared(handler: HookHandler<HookPayloads[Hooks.TIMELINE_CLEARED], TContext>): any;
getInspectorTree(handler: HookHandler<HookPayloads[Hooks.GET_INSPECTOR_TREE], TContext>): any;
getInspectorState(handler: HookHandler<HookPayloads[Hooks.GET_INSPECTOR_STATE], TContext>): any;
editInspectorState(handler: HookHandler<HookPayloads[Hooks.EDIT_INSPECTOR_STATE], TContext>): any;
setPluginSettings(handler: HookHandler<HookPayloads[Hooks.SET_PLUGIN_SETTINGS], TContext>): any;
}

@ -0,0 +1,6 @@
export * from './api.js';
export * from './app.js';
export * from './component.js';
export * from './context.js';
export * from './hooks.js';
export * from './util.js';

@ -0,0 +1,6 @@
export * from './api.js';
export * from './app.js';
export * from './component.js';
export * from './context.js';
export * from './hooks.js';
export * from './util.js';

@ -0,0 +1,4 @@
export declare type ID = number | string;
export interface WithId {
id: ID;
}

@ -0,0 +1,2 @@
export declare const HOOK_SETUP = "devtools-plugin:setup";
export declare const HOOK_PLUGIN_SETTINGS_SET = "plugin:settings:set";

@ -0,0 +1,2 @@
export const HOOK_SETUP = 'devtools-plugin:setup';
export const HOOK_PLUGIN_SETTINGS_SET = 'plugin:settings:set';

@ -0,0 +1,15 @@
import type { PluginDescriptor, SetupFunction } from './index.js';
import type { ApiProxy } from './proxy.js';
export interface PluginQueueItem {
pluginDescriptor: PluginDescriptor;
setupFn: SetupFunction;
proxy?: ApiProxy;
}
interface GlobalTarget {
__VUE_DEVTOOLS_PLUGINS__?: PluginQueueItem[];
__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__?: boolean;
}
export declare function getDevtoolsGlobalHook(): any;
export declare function getTarget(): GlobalTarget;
export declare const isProxyAvailable: boolean;
export {};

@ -0,0 +1,12 @@
export function getDevtoolsGlobalHook() {
return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__;
}
export function getTarget() {
// @ts-ignore
return (typeof navigator !== 'undefined' && typeof window !== 'undefined')
? window
: typeof global !== 'undefined'
? global
: {};
}
export const isProxyAvailable = typeof Proxy === 'function';

@ -0,0 +1,18 @@
import type { DevtoolsPluginApi } from './api/index.js';
import type { PluginDescriptor, ExtractSettingsTypes, PluginSettingsItem } from './plugin.js';
export * from './api/index.js';
export * from './plugin.js';
export * from './time.js';
export { PluginQueueItem } from './env.js';
declare type Cast<A, B> = A extends B ? A : B;
declare type Narrowable = string | number | bigint | boolean;
declare type Narrow<A> = Cast<A, [] | (A extends Narrowable ? A : never) | ({
[K in keyof A]: Narrow<A[K]>;
})>;
declare type Exact<C, T> = {
[K in keyof C]: K extends keyof T ? T[K] : never;
};
export declare type SetupFunction<TSettings = any> = (api: DevtoolsPluginApi<TSettings>) => void;
export declare function setupDevtoolsPlugin<TDescriptor extends Exact<TDescriptor, PluginDescriptor>, TSettings = ExtractSettingsTypes<TDescriptor extends {
settings: infer S;
} ? S extends Record<string, PluginSettingsItem> ? S : Record<string, PluginSettingsItem> : Record<string, PluginSettingsItem>>>(pluginDescriptor: Narrow<TDescriptor>, setupFn: SetupFunction<TSettings>): void;

@ -0,0 +1,26 @@
import { getTarget, getDevtoolsGlobalHook, isProxyAvailable } from './env.js';
import { HOOK_SETUP } from './const.js';
import { ApiProxy } from './proxy.js';
export * from './api/index.js';
export * from './plugin.js';
export * from './time.js';
export function setupDevtoolsPlugin(pluginDescriptor, setupFn) {
const descriptor = pluginDescriptor;
const target = getTarget();
const hook = getDevtoolsGlobalHook();
const enableProxy = isProxyAvailable && descriptor.enableEarlyProxy;
if (hook && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) {
hook.emit(HOOK_SETUP, pluginDescriptor, setupFn);
}
else {
const proxy = enableProxy ? new ApiProxy(descriptor, hook) : null;
const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || [];
list.push({
pluginDescriptor: descriptor,
setupFn,
proxy,
});
if (proxy)
setupFn(proxy.proxiedTarget);
}
}

@ -0,0 +1,47 @@
import type { App } from './api/index.js';
export interface PluginDescriptor {
id: string;
label: string;
app: App;
packageName?: string;
homepage?: string;
componentStateTypes?: string[];
logo?: string;
disableAppScope?: boolean;
disablePluginScope?: boolean;
/**
* Run the plugin setup and expose the api even if the devtools is not opened yet.
* Useful to record timeline events early.
*/
enableEarlyProxy?: boolean;
settings?: Record<string, PluginSettingsItem>;
}
export declare type PluginSettingsItem = {
label: string;
description?: string;
} & ({
type: 'boolean';
defaultValue: boolean;
} | {
type: 'choice';
defaultValue: string | number;
options: {
value: string | number;
label: string;
}[];
component?: 'select' | 'button-group';
} | {
type: 'text';
defaultValue: string;
});
declare type InferSettingsType<T extends PluginSettingsItem> = [T] extends [{
type: 'boolean';
}] ? boolean : [T] extends [{
type: 'choice';
}] ? T['options'][number]['value'] : [T] extends [{
type: 'text';
}] ? string : unknown;
export declare type ExtractSettingsTypes<O extends Record<string, PluginSettingsItem>> = {
[K in keyof O]: InferSettingsType<O[K]>;
};
export {};

@ -0,0 +1 @@
export {};

@ -0,0 +1,20 @@
import type { Context, DevtoolsPluginApi, Hookable } from './api/index.js';
import type { PluginDescriptor } from './plugin.js';
interface QueueItem {
method: string;
args: any[];
resolve?: (value?: any) => void;
}
export declare class ApiProxy<TTarget extends DevtoolsPluginApi<any> = DevtoolsPluginApi<any>> {
target: TTarget | null;
targetQueue: QueueItem[];
proxiedTarget: TTarget;
onQueue: QueueItem[];
proxiedOn: Hookable<Context>;
plugin: PluginDescriptor;
hook: any;
fallbacks: Record<string, any>;
constructor(plugin: PluginDescriptor, hook: any);
setRealTarget(target: TTarget): Promise<void>;
}
export {};

@ -0,0 +1,107 @@
import { HOOK_PLUGIN_SETTINGS_SET } from './const.js';
import { now } from './time.js';
export class ApiProxy {
constructor(plugin, hook) {
this.target = null;
this.targetQueue = [];
this.onQueue = [];
this.plugin = plugin;
this.hook = hook;
const defaultSettings = {};
if (plugin.settings) {
for (const id in plugin.settings) {
const item = plugin.settings[id];
defaultSettings[id] = item.defaultValue;
}
}
const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`;
let currentSettings = Object.assign({}, defaultSettings);
try {
const raw = localStorage.getItem(localSettingsSaveId);
const data = JSON.parse(raw);
Object.assign(currentSettings, data);
}
catch (e) {
// noop
}
this.fallbacks = {
getSettings() {
return currentSettings;
},
setSettings(value) {
try {
localStorage.setItem(localSettingsSaveId, JSON.stringify(value));
}
catch (e) {
// noop
}
currentSettings = value;
},
now() {
return now();
},
};
if (hook) {
hook.on(HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => {
if (pluginId === this.plugin.id) {
this.fallbacks.setSettings(value);
}
});
}
this.proxiedOn = new Proxy({}, {
get: (_target, prop) => {
if (this.target) {
return this.target.on[prop];
}
else {
return (...args) => {
this.onQueue.push({
method: prop,
args,
});
};
}
},
});
this.proxiedTarget = new Proxy({}, {
get: (_target, prop) => {
if (this.target) {
return this.target[prop];
}
else if (prop === 'on') {
return this.proxiedOn;
}
else if (Object.keys(this.fallbacks).includes(prop)) {
return (...args) => {
this.targetQueue.push({
method: prop,
args,
resolve: () => { },
});
return this.fallbacks[prop](...args);
};
}
else {
return (...args) => {
return new Promise(resolve => {
this.targetQueue.push({
method: prop,
args,
resolve,
});
});
};
}
},
});
}
async setRealTarget(target) {
this.target = target;
for (const item of this.onQueue) {
this.target.on[item.method](...item.args);
}
for (const item of this.targetQueue) {
item.resolve(await this.target[item.method](...item.args));
}
}
}

@ -0,0 +1,2 @@
export declare function isPerformanceSupported(): boolean;
export declare function now(): number;

@ -0,0 +1,23 @@
let supported;
let perf;
export function isPerformanceSupported() {
var _a;
if (supported !== undefined) {
return supported;
}
if (typeof window !== 'undefined' && window.performance) {
supported = true;
perf = window.performance;
}
else if (typeof global !== 'undefined' && ((_a = global.perf_hooks) === null || _a === void 0 ? void 0 : _a.performance)) {
supported = true;
perf = global.perf_hooks.performance;
}
else {
supported = false;
}
return supported;
}
export function now() {
return isPerformanceSupported() ? perf.now() : Date.now();
}

@ -0,0 +1,37 @@
{
"name": "@vue/devtools-api",
"version": "6.5.0",
"description": "Interact with the Vue devtools from the page",
"main": "lib/cjs/index.js",
"browser": "lib/esm/index.js",
"module": "lib/esm/index.js",
"types": "lib/esm/index.d.ts",
"sideEffects": false,
"author": {
"name": "Guillaume Chau"
},
"files": [
"lib/esm",
"lib/cjs"
],
"license": "MIT",
"repository": {
"url": "https://github.com/vuejs/vue-devtools.git",
"type": "git",
"directory": "packages/api"
},
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "rimraf lib && yarn build:esm && yarn build:cjs",
"build:esm": "tsc --module es2015 --outDir lib/esm -d",
"build:cjs": "tsc --module commonjs --outDir lib/cjs",
"build:watch": "yarn tsc --module es2015 --outDir lib/esm -d -w --sourceMap"
},
"devDependencies": {
"@types/node": "^13.9.1",
"@types/webpack-env": "^1.15.1",
"typescript": "^4.5.2"
}
}

21
node_modules/pinia/LICENSE generated vendored

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2019-present Eduardo San Martin Morote
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

24
node_modules/pinia/README.md generated vendored

@ -0,0 +1,24 @@
<p align="center">
<a href="https://pinia.vuejs.org" target="_blank" rel="noopener noreferrer">
<img width="180" src="https://pinia.vuejs.org/logo.svg" alt="Pinia logo">
</a>
</p>
# Pinia
> Intuitive, type safe and flexible Store for Vue
## 👉 [Demo with Vue 3 on StackBlitz](https://stackblitz.com/github/piniajs/example-vue-3-vite)
## Help me keep working on this project 💚
- [Become a Sponsor on GitHub](https://github.com/sponsors/posva)
- [One-time donation via PayPal](https://paypal.me/posva)
## Documentation
To learn more about Pinia, check [its documentation](https://pinia.vuejs.org).
## License
[MIT](http://opensource.org/licenses/MIT)

2019
node_modules/pinia/dist/pinia.cjs generated vendored

File diff suppressed because it is too large Load Diff

986
node_modules/pinia/dist/pinia.d.ts generated vendored

@ -0,0 +1,986 @@
import { App } from 'vue-demi';
import { ComputedRef } from 'vue-demi';
import type { DebuggerEvent } from 'vue-demi';
import { EffectScope } from 'vue-demi';
import type { Plugin as Plugin_2 } from 'vue-demi';
import { Ref } from 'vue-demi';
import { ToRef } from 'vue-demi';
import { ToRefs } from 'vue-demi';
import { UnwrapRef } from 'vue-demi';
import type { WatchOptions } from 'vue-demi';
/**
* Creates an _accept_ function to pass to `import.meta.hot` in Vite applications.
*
* @example
* ```js
* const useUser = defineStore(...)
* if (import.meta.hot) {
* import.meta.hot.accept(acceptHMRUpdate(useUser, import.meta.hot))
* }
* ```
*
* @param initialUseStore - return of the defineStore to hot update
* @param hot - `import.meta.hot`
*/
export declare function acceptHMRUpdate<Id extends string = string, S extends StateTree = StateTree, G extends _GettersTree<S> = _GettersTree<S>, A = _ActionsTree>(initialUseStore: StoreDefinition<Id, S, G, A>, hot: any): (newModule: any) => any;
/**
* Type of an object of Actions. For internal usage only.
* For internal use **only**
*/
export declare type _ActionsTree = Record<string, _Method>;
export declare type _Awaited<T> = T extends null | undefined ? T : T extends object & {
then(onfulfilled: infer F): any;
} ? F extends (value: infer V, ...args: any) => any ? _Awaited<V> : never : T;
/**
* Creates a Pinia instance to be used by the application
*/
export declare function createPinia(): Pinia;
/**
* Recursive `Partial<T>`. Used by {@link Store['$patch']}.
*
* For internal use **only**
*/
export declare type _DeepPartial<T> = {
[K in keyof T]?: _DeepPartial<T[K]>;
};
/**
* Options parameter of `defineStore()` for setup stores. Can be extended to
* augment stores with the plugin API. @see {@link DefineStoreOptionsBase}.
*/
export declare interface DefineSetupStoreOptions<Id extends string, S extends StateTree, G, A> extends DefineStoreOptionsBase<S, Store<Id, S, G, A>> {
/**
* Extracted actions. Added by useStore(). SHOULD NOT be added by the user when
* creating the store. Can be used in plugins to get the list of actions in a
* store defined with a setup function. Note this is always defined
*/
actions?: A;
}
/**
* Creates a `useStore` function that retrieves the store instance
*
* @param id - id of the store (must be unique)
* @param options - options to define the store
*/
export declare function defineStore<Id extends string, S extends StateTree = {}, G extends _GettersTree<S> = {}, A = {}>(id: Id, options: Omit<DefineStoreOptions<Id, S, G, A>, 'id'>): StoreDefinition<Id, S, G, A>;
/**
* Creates a `useStore` function that retrieves the store instance
*
* @param options - options to define the store
*/
export declare function defineStore<Id extends string, S extends StateTree = {}, G extends _GettersTree<S> = {}, A = {}>(options: DefineStoreOptions<Id, S, G, A>): StoreDefinition<Id, S, G, A>;
/**
* Creates a `useStore` function that retrieves the store instance
*
* @param id - id of the store (must be unique)
* @param storeSetup - function that defines the store
* @param options - extra options
*/
export declare function defineStore<Id extends string, SS>(id: Id, storeSetup: () => SS, options?: DefineSetupStoreOptions<Id, _ExtractStateFromSetupStore<SS>, _ExtractGettersFromSetupStore<SS>, _ExtractActionsFromSetupStore<SS>>): StoreDefinition<Id, _ExtractStateFromSetupStore<SS>, _ExtractGettersFromSetupStore<SS>, _ExtractActionsFromSetupStore<SS>>;
/**
* Options parameter of `defineStore()` for option stores. Can be extended to
* augment stores with the plugin API. @see {@link DefineStoreOptionsBase}.
*/
export declare interface DefineStoreOptions<Id extends string, S extends StateTree, G, A> extends DefineStoreOptionsBase<S, Store<Id, S, G, A>> {
/**
* Unique string key to identify the store across the application.
*/
id: Id;
/**
* Function to create a fresh state. **Must be an arrow function** to ensure
* correct typings!
*/
state?: () => S;
/**
* Optional object of getters.
*/
getters?: G & ThisType<UnwrapRef<S> & _StoreWithGetters<G> & PiniaCustomProperties> & _GettersTree<S>;
/**
* Optional object of actions.
*/
actions?: A & ThisType<A & UnwrapRef<S> & _StoreWithState<Id, S, G, A> & _StoreWithGetters<G> & PiniaCustomProperties>;
/**
* Allows hydrating the store during SSR when complex state (like client side only refs) are used in the store
* definition and copying the value from `pinia.state` isn't enough.
*
* @example
* If in your `state`, you use any `customRef`s, any `computed`s, or any `ref`s that have a different value on
* Server and Client, you need to manually hydrate them. e.g., a custom ref that is stored in the local
* storage:
*
* ```ts
* const useStore = defineStore('main', {
* state: () => ({
* n: useLocalStorage('key', 0)
* }),
* hydrate(storeState, initialState) {
* // @ts-expect-error: https://github.com/microsoft/TypeScript/issues/43826
* storeState.n = useLocalStorage('key', 0)
* }
* })
* ```
*
* @param storeState - the current state in the store
* @param initialState - initialState
*/
hydrate?(storeState: UnwrapRef<S>, initialState: UnwrapRef<S>): void;
}
/**
* Options passed to `defineStore()` that are common between option and setup
* stores. Extend this interface if you want to add custom options to both kinds
* of stores.
*/
export declare interface DefineStoreOptionsBase<S extends StateTree, Store> {
}
/**
* Available `options` when creating a pinia plugin.
*/
export declare interface DefineStoreOptionsInPlugin<Id extends string, S extends StateTree, G, A> extends Omit<DefineStoreOptions<Id, S, G, A>, 'id' | 'actions'> {
/**
* Extracted object of actions. Added by useStore() when the store is built
* using the setup API, otherwise uses the one passed to `defineStore()`.
* Defaults to an empty object if no actions are defined.
*/
actions: A;
}
/**
* For internal use **only**
*/
export declare type _ExtractActionsFromSetupStore<SS> = SS extends undefined | void ? {} : _ExtractActionsFromSetupStore_Keys<SS> extends keyof SS ? Pick<SS, _ExtractActionsFromSetupStore_Keys<SS>> : never;
/**
* Type that enables refactoring through IDE.
* For internal use **only**
*/
export declare type _ExtractActionsFromSetupStore_Keys<SS> = keyof {
[K in keyof SS as SS[K] extends _Method ? K : never]: any;
};
/**
* For internal use **only**
*/
export declare type _ExtractGettersFromSetupStore<SS> = SS extends undefined | void ? {} : _ExtractGettersFromSetupStore_Keys<SS> extends keyof SS ? Pick<SS, _ExtractGettersFromSetupStore_Keys<SS>> : never;
/**
* Type that enables refactoring through IDE.
* For internal use **only**
*/
export declare type _ExtractGettersFromSetupStore_Keys<SS> = keyof {
[K in keyof SS as SS[K] extends ComputedRef ? K : never]: any;
};
/**
* For internal use **only**
*/
export declare type _ExtractStateFromSetupStore<SS> = SS extends undefined | void ? {} : _ExtractStateFromSetupStore_Keys<SS> extends keyof SS ? _UnwrapAll<Pick<SS, _ExtractStateFromSetupStore_Keys<SS>>> : never;
/**
* Type that enables refactoring through IDE.
* For internal use **only**
*/
export declare type _ExtractStateFromSetupStore_Keys<SS> = keyof {
[K in keyof SS as SS[K] extends _Method | ComputedRef ? never : K]: any;
};
/**
* Get the currently active pinia if there is any.
*/
export declare const getActivePinia: () => Pinia | undefined;
/**
* Type of an object of Getters that infers the argument. For internal usage only.
* For internal use **only**
*/
export declare type _GettersTree<S extends StateTree> = Record<string, ((state: UnwrapRef<S> & UnwrapRef<PiniaCustomStateProperties<S>>) => any) | (() => any)>;
/**
* Allows directly using actions from your store without using the composition
* API (`setup()`) by generating an object to be spread in the `methods` field
* of a component. The values of the object are the actions while the keys are
* the names of the resulting methods.
*
* @example
* ```js
* export default {
* methods: {
* // other methods properties
* // useCounterStore has two actions named `increment` and `setCount`
* ...mapActions(useCounterStore, { moar: 'increment', setIt: 'setCount' })
* },
*
* created() {
* this.moar()
* this.setIt(2)
* }
* }
* ```
*
* @param useStore - store to map from
* @param keyMapper - object to define new names for the actions
*/
export declare function mapActions<Id extends string, S extends StateTree, G extends _GettersTree<S>, A, KeyMapper extends Record<string, keyof A>>(useStore: StoreDefinition<Id, S, G, A>, keyMapper: KeyMapper): _MapActionsObjectReturn<A, KeyMapper>;
/**
* Allows directly using actions from your store without using the composition
* API (`setup()`) by generating an object to be spread in the `methods` field
* of a component.
*
* @example
* ```js
* export default {
* methods: {
* // other methods properties
* ...mapActions(useCounterStore, ['increment', 'setCount'])
* },
*
* created() {
* this.increment()
* this.setCount(2) // pass arguments as usual
* }
* }
* ```
*
* @param useStore - store to map from
* @param keys - array of action names to map
*/
export declare function mapActions<Id extends string, S extends StateTree, G extends _GettersTree<S>, A>(useStore: StoreDefinition<Id, S, G, A>, keys: Array<keyof A>): _MapActionsReturn<A>;
/**
* For internal use **only**
*/
export declare type _MapActionsObjectReturn<A, T extends Record<string, keyof A>> = {
[key in keyof T]: A[T[key]];
};
/**
* For internal use **only**
*/
export declare type _MapActionsReturn<A> = {
[key in keyof A]: A[key];
};
/**
* Alias for `mapState()`. You should use `mapState()` instead.
* @deprecated use `mapState()` instead.
*/
export declare const mapGetters: typeof mapState;
/**
* Allows using state and getters from one store without using the composition
* API (`setup()`) by generating an object to be spread in the `computed` field
* of a component. The values of the object are the state properties/getters
* while the keys are the names of the resulting computed properties.
* Optionally, you can also pass a custom function that will receive the store
* as its first argument. Note that while it has access to the component
* instance via `this`, it won't be typed.
*
* @example
* ```js
* export default {
* computed: {
* // other computed properties
* // useCounterStore has a state property named `count` and a getter `double`
* ...mapState(useCounterStore, {
* n: 'count',
* triple: store => store.n * 3,
* // note we can't use an arrow function if we want to use `this`
* custom(store) {
* return this.someComponentValue + store.n
* },
* doubleN: 'double'
* })
* },
*
* created() {
* this.n // 2
* this.doubleN // 4
* }
* }
* ```
*
* @param useStore - store to map from
* @param keyMapper - object of state properties or getters
*/
export declare function mapState<Id extends string, S extends StateTree, G extends _GettersTree<S>, A, KeyMapper extends Record<string, keyof S | keyof G | ((store: Store<Id, S, G, A>) => any)>>(useStore: StoreDefinition<Id, S, G, A>, keyMapper: KeyMapper): _MapStateObjectReturn<Id, S, G, A, KeyMapper>;
/**
* Allows using state and getters from one store without using the composition
* API (`setup()`) by generating an object to be spread in the `computed` field
* of a component.
*
* @example
* ```js
* export default {
* computed: {
* // other computed properties
* ...mapState(useCounterStore, ['count', 'double'])
* },
*
* created() {
* this.count // 2
* this.double // 4
* }
* }
* ```
*
* @param useStore - store to map from
* @param keys - array of state properties or getters
*/
export declare function mapState<Id extends string, S extends StateTree, G extends _GettersTree<S>, A, Keys extends keyof S | keyof G>(useStore: StoreDefinition<Id, S, G, A>, keys: readonly Keys[]): _MapStateReturn<S, G, Keys>;
/**
* For internal use **only**
*/
export declare type _MapStateObjectReturn<Id extends string, S extends StateTree, G extends _GettersTree<S>, A, T extends Record<string, keyof S | keyof G | ((store: Store<Id, S, G, A>) => any)> = {}> = {
[key in keyof T]: () => T[key] extends (store: any) => infer R ? R : T[key] extends keyof Store<Id, S, G, A> ? Store<Id, S, G, A>[T[key]] : never;
};
/**
* For internal use **only**
*/
export declare type _MapStateReturn<S extends StateTree, G extends _GettersTree<S>, Keys extends keyof S | keyof G = keyof S | keyof G> = {
[key in Keys]: () => Store<string, S, G, {}>[key];
};
/**
* Allows using stores without the composition API (`setup()`) by generating an
* object to be spread in the `computed` field of a component. It accepts a list
* of store definitions.
*
* @example
* ```js
* export default {
* computed: {
* // other computed properties
* ...mapStores(useUserStore, useCartStore)
* },
*
* created() {
* this.userStore // store with id "user"
* this.cartStore // store with id "cart"
* }
* }
* ```
*
* @param stores - list of stores to map to an object
*/
export declare function mapStores<Stores extends any[]>(...stores: [...Stores]): _Spread<Stores>;
/**
* Interface to allow customizing map helpers. Extend this interface with the
* following properties:
*
* - `suffix`: string. Affects the suffix of `mapStores()`, defaults to `Store`.
*/
export declare interface MapStoresCustomization {
}
/**
* Same as `mapState()` but creates computed setters as well so the state can be
* modified. Differently from `mapState()`, only `state` properties can be
* added.
*
* @param useStore - store to map from
* @param keyMapper - object of state properties
*/
export declare function mapWritableState<Id extends string, S extends StateTree, G extends _GettersTree<S>, A, KeyMapper extends Record<string, keyof S>>(useStore: StoreDefinition<Id, S, G, A>, keyMapper: KeyMapper): _MapWritableStateObjectReturn<S, KeyMapper>;
/**
* Allows using state and getters from one store without using the composition
* API (`setup()`) by generating an object to be spread in the `computed` field
* of a component.
*
* @param useStore - store to map from
* @param keys - array of state properties
*/
export declare function mapWritableState<Id extends string, S extends StateTree, G extends _GettersTree<S>, A, Keys extends keyof S>(useStore: StoreDefinition<Id, S, G, A>, keys: readonly Keys[]): {
[K in Keys]: {
get: () => S[K];
set: (value: S[K]) => any;
};
};
/**
* For internal use **only**
*/
export declare type _MapWritableStateObjectReturn<S extends StateTree, T extends Record<string, keyof S>> = {
[key in keyof T]: {
get: () => S[T[key]];
set: (value: S[T[key]]) => any;
};
};
/**
* For internal use **only**
*/
export declare type _MapWritableStateReturn<S extends StateTree> = {
[key in keyof S]: {
get: () => S[key];
set: (value: S[key]) => any;
};
};
/**
* Generic type for a function that can infer arguments and return type
*
* For internal use **only**
*/
export declare type _Method = (...args: any[]) => any;
/**
* Possible types for SubscriptionCallback
*/
export declare enum MutationType {
/**
* Direct mutation of the state:
*
* - `store.name = 'new name'`
* - `store.$state.name = 'new name'`
* - `store.list.push('new item')`
*/
direct = "direct",
/**
* Mutated the state with `$patch` and an object
*
* - `store.$patch({ name: 'newName' })`
*/
patchObject = "patch object",
/**
* Mutated the state with `$patch` and a function
*
* - `store.$patch(state => state.name = 'newName')`
*/
patchFunction = "patch function"
}
/**
* Every application must own its own pinia to be able to create stores
*/
export declare interface Pinia {
install: (app: App) => void;
/**
* root state
*/
state: Ref<Record<string, StateTree>>;
/**
* Adds a store plugin to extend every store
*
* @param plugin - store plugin to add
*/
use(plugin: PiniaPlugin): Pinia;
/* Excluded from this release type: _p */
/* Excluded from this release type: _a */
/* Excluded from this release type: _e */
/* Excluded from this release type: _s */
/* Excluded from this release type: _testing */
}
/**
* Interface to be extended by the user when they add properties through plugins.
*/
export declare interface PiniaCustomProperties<Id extends string = string, S extends StateTree = StateTree, G = _GettersTree<S>, A = _ActionsTree> {
}
/**
* Properties that are added to every `store.$state` by `pinia.use()`.
*/
export declare interface PiniaCustomStateProperties<S extends StateTree = StateTree> {
}
/**
* Plugin to extend every store.
*/
export declare interface PiniaPlugin {
/**
* Plugin to extend every store. Returns an object to extend the store or
* nothing.
*
* @param context - Context
*/
(context: PiniaPluginContext): Partial<PiniaCustomProperties & PiniaCustomStateProperties> | void;
}
/**
* Context argument passed to Pinia plugins.
*/
export declare interface PiniaPluginContext<Id extends string = string, S extends StateTree = StateTree, G = _GettersTree<S>, A = _ActionsTree> {
/**
* pinia instance.
*/
pinia: Pinia;
/**
* Current app created with `Vue.createApp()`.
*/
app: App;
/**
* Current store being extended.
*/
store: Store<Id, S, G, A>;
/**
* Initial options defining the store when calling `defineStore()`.
*/
options: DefineStoreOptionsInPlugin<Id, S, G, A>;
}
/**
* Plugin to extend every store.
* @deprecated use PiniaPlugin instead
*/
export declare type PiniaStorePlugin = PiniaPlugin;
/**
* Vue 2 Plugin that must be installed for pinia to work. Note **you don't need
* this plugin if you are using Nuxt.js**. Use the `buildModule` instead:
* https://pinia.vuejs.org/ssr/nuxt.html.
*
* @example
* ```js
* import Vue from 'vue'
* import { PiniaVuePlugin, createPinia } from 'pinia'
*
* Vue.use(PiniaVuePlugin)
* const pinia = createPinia()
*
* new Vue({
* el: '#app',
* // ...
* pinia,
* })
* ```
*
* @param _Vue - `Vue` imported from 'vue'.
*/
export declare const PiniaVuePlugin: Plugin_2;
declare interface _SetActivePinia {
(pinia: Pinia): Pinia;
(pinia: undefined): undefined;
(pinia: Pinia | undefined): Pinia | undefined;
}
/**
* Sets or unsets the active pinia. Used in SSR and internally when calling
* actions and getters
*
* @param pinia - Pinia instance
*/
export declare const setActivePinia: _SetActivePinia;
/**
* Changes the suffix added by `mapStores()`. Can be set to an empty string.
* Defaults to `"Store"`. Make sure to extend the MapStoresCustomization
* interface if you are using TypeScript.
*
* @param suffix - new suffix
*/
export declare function setMapStoreSuffix(suffix: MapStoresCustomization extends Record<'suffix', infer Suffix> ? Suffix : string): void;
/**
* Tells Pinia to skip the hydration process of a given object. This is useful in setup stores (only) when you return a
* stateful object in the store but it isn't really state. e.g. returning a router instance in a setup store.
*
* @param obj - target object
* @returns obj
*/
export declare function skipHydrate<T = any>(obj: T): T;
/**
* For internal use **only**.
*/
export declare type _Spread<A extends readonly any[]> = A extends [infer L, ...infer R] ? _StoreObject<L> & _Spread<R> : unknown;
/**
* Generic state of a Store
*/
export declare type StateTree = Record<string | number | symbol, any>;
/**
* Store type to build a store.
*/
export declare type Store<Id extends string = string, S extends StateTree = {}, G = {}, A = {}> = _StoreWithState<Id, S, G, A> & UnwrapRef<S> & _StoreWithGetters<G> & (_ActionsTree extends A ? {} : A) & PiniaCustomProperties<Id, S, G, A> & PiniaCustomStateProperties<S>;
/**
* Extract the actions of a store type. Works with both a Setup Store or an
* Options Store.
*/
export declare type StoreActions<SS> = SS extends Store<string, StateTree, _GettersTree<StateTree>, infer A> ? A : _ExtractActionsFromSetupStore<SS>;
/**
* Return type of `defineStore()`. Function that allows instantiating a store.
*/
export declare interface StoreDefinition<Id extends string = string, S extends StateTree = StateTree, G = _GettersTree<S>, A = _ActionsTree> {
/**
* Returns a store, creates it if necessary.
*
* @param pinia - Pinia instance to retrieve the store
* @param hot - dev only hot module replacement
*/
(pinia?: Pinia | null | undefined, hot?: StoreGeneric): Store<Id, S, G, A>;
/**
* Id of the store. Used by map helpers.
*/
$id: Id;
/* Excluded from this release type: _pinia */
}
/**
* Generic and type-unsafe version of Store. Doesn't fail on access with
* strings, making it much easier to write generic functions that do not care
* about the kind of store that is passed.
*/
export declare type StoreGeneric = Store<string, StateTree, _GettersTree<StateTree>, _ActionsTree>;
/**
* Extract the getters of a store type. Works with both a Setup Store or an
* Options Store.
*/
export declare type StoreGetters<SS> = SS extends Store<string, StateTree, infer G, _ActionsTree> ? _StoreWithGetters<G> : _ExtractGettersFromSetupStore<SS>;
/**
* For internal use **only**.
*/
export declare type _StoreObject<S> = S extends StoreDefinition<infer Ids, infer State, infer Getters, infer Actions> ? {
[Id in `${Ids}${MapStoresCustomization extends Record<'suffix', infer Suffix> ? Suffix : 'Store'}`]: () => Store<Id extends `${infer RealId}${MapStoresCustomization extends Record<'suffix', infer Suffix> ? Suffix : 'Store'}` ? RealId : string, State, Getters, Actions>;
} : {};
/**
* Argument of `store.$onAction()`
*/
export declare type StoreOnActionListener<Id extends string, S extends StateTree, G, A> = (context: StoreOnActionListenerContext<Id, S, G, {} extends A ? _ActionsTree : A>) => void;
/**
* Context object passed to callbacks of `store.$onAction(context => {})`
* TODO: should have only the Id, the Store and Actions to generate the proper object
*/
export declare type StoreOnActionListenerContext<Id extends string, S extends StateTree, G, A> = _ActionsTree extends A ? _StoreOnActionListenerContext<StoreGeneric, string, _ActionsTree> : {
[Name in keyof A]: Name extends string ? _StoreOnActionListenerContext<Store<Id, S, G, A>, Name, A> : never;
}[keyof A];
/**
* Actual type for {@link StoreOnActionListenerContext}. Exists for refactoring
* purposes. For internal use only.
* For internal use **only**
*/
export declare interface _StoreOnActionListenerContext<Store, ActionName extends string, A> {
/**
* Name of the action
*/
name: ActionName;
/**
* Store that is invoking the action
*/
store: Store;
/**
* Parameters passed to the action
*/
args: A extends Record<ActionName, _Method> ? Parameters<A[ActionName]> : unknown[];
/**
* Sets up a hook once the action is finished. It receives the return value
* of the action, if it's a Promise, it will be unwrapped.
*/
after: (callback: A extends Record<ActionName, _Method> ? (resolvedReturn: _Awaited<ReturnType<A[ActionName]>>) => void : () => void) => void;
/**
* Sets up a hook if the action fails. Return `false` to catch the error and
* stop it from propagating.
*/
onError: (callback: (error: unknown) => void) => void;
}
/**
* Properties of a store.
*/
export declare interface StoreProperties<Id extends string> {
/**
* Unique identifier of the store
*/
$id: Id;
/* Excluded from this release type: _p */
/* Excluded from this release type: _getters */
/* Excluded from this release type: _isOptionsAPI */
/**
* Used by devtools plugin to retrieve properties added with plugins. Removed
* in production. Can be used by the user to add property keys of the store
* that should be displayed in devtools.
*/
_customProperties: Set<string>;
/* Excluded from this release type: _hotUpdate */
/* Excluded from this release type: _hotUpdating */
/* Excluded from this release type: _hmrPayload */
}
/**
* Extract the state of a store type. Works with both a Setup Store or an
* Options Store. Note this unwraps refs.
*/
export declare type StoreState<SS> = SS extends Store<string, infer S, _GettersTree<StateTree>, _ActionsTree> ? UnwrapRef<S> : _ExtractStateFromSetupStore<SS>;
/**
* Extracts the return type for `storeToRefs`.
* Will convert any `getters` into `ComputedRef`.
*/
declare type StoreToRefs<SS extends StoreGeneric> = ToRefs<StoreState<SS> & PiniaCustomStateProperties<StoreState<SS>>> & ToComputedRefs<StoreGetters<SS>>;
/**
* Creates an object of references with all the state, getters, and plugin-added
* state properties of the store. Similar to `toRefs()` but specifically
* designed for Pinia stores so methods and non reactive properties are
* completely ignored.
*
* @param store - store to extract the refs from
*/
export declare function storeToRefs<SS extends StoreGeneric>(store: SS): StoreToRefs<SS>;
/**
* Store augmented for actions. For internal usage only.
* For internal use **only**
*/
export declare type _StoreWithActions<A> = {
[k in keyof A]: A[k] extends (...args: infer P) => infer R ? (...args: P) => R : never;
};
/**
* Store augmented with getters. For internal usage only.
* For internal use **only**
*/
export declare type _StoreWithGetters<G> = {
readonly [k in keyof G]: G[k] extends (...args: any[]) => infer R ? R : UnwrapRef<G[k]>;
};
/**
* Base store with state and functions. Should not be used directly.
*/
export declare interface _StoreWithState<Id extends string, S extends StateTree, G, A> extends StoreProperties<Id> {
/**
* State of the Store. Setting it will internally call `$patch()` to update the state.
*/
$state: UnwrapRef<S> & PiniaCustomStateProperties<S>;
/**
* Applies a state patch to current state. Allows passing nested values
*
* @param partialState - patch to apply to the state
*/
$patch(partialState: _DeepPartial<UnwrapRef<S>>): void;
/**
* Group multiple changes into one function. Useful when mutating objects like
* Sets or arrays and applying an object patch isn't practical, e.g. appending
* to an array. The function passed to `$patch()` **must be synchronous**.
*
* @param stateMutator - function that mutates `state`, cannot be asynchronous
*/
$patch<F extends (state: UnwrapRef<S>) => any>(stateMutator: ReturnType<F> extends Promise<any> ? never : F): void;
/**
* Resets the store to its initial state by building a new state object.
* TODO: make this options only
*/
$reset(): void;
/**
* Setups a callback to be called whenever the state changes. It also returns a function to remove the callback. Note
* that when calling `store.$subscribe()` inside of a component, it will be automatically cleaned up when the
* component gets unmounted unless `detached` is set to true.
*
* @param callback - callback passed to the watcher
* @param options - `watch` options + `detached` to detach the subscription from the context (usually a component)
* this is called from. Note that the `flush` option does not affect calls to `store.$patch()`.
* @returns function that removes the watcher
*/
$subscribe(callback: SubscriptionCallback<S>, options?: {
detached?: boolean;
} & WatchOptions): () => void;
/**
* Setups a callback to be called every time an action is about to get
* invoked. The callback receives an object with all the relevant information
* of the invoked action:
* - `store`: the store it is invoked on
* - `name`: The name of the action
* - `args`: The parameters passed to the action
*
* On top of these, it receives two functions that allow setting up a callback
* once the action finishes or when it fails.
*
* It also returns a function to remove the callback. Note than when calling
* `store.$onAction()` inside of a component, it will be automatically cleaned
* up when the component gets unmounted unless `detached` is set to true.
*
* @example
*
*```js
*store.$onAction(({ after, onError }) => {
* // Here you could share variables between all of the hooks as well as
* // setting up watchers and clean them up
* after((resolvedValue) => {
* // can be used to cleanup side effects
* . // `resolvedValue` is the value returned by the action, if it's a
* . // Promise, it will be the resolved value instead of the Promise
* })
* onError((error) => {
* // can be used to pass up errors
* })
*})
*```
*
* @param callback - callback called before every action
* @param detached - detach the subscription from the context this is called from
* @returns function that removes the watcher
*/
$onAction(callback: StoreOnActionListener<Id, S, G, A>, detached?: boolean): () => void;
/**
* Stops the associated effect scope of the store and remove it from the store
* registry. Plugins can override this method to cleanup any added effects.
* e.g. devtools plugin stops displaying disposed stores from devtools.
* Note this doesn't delete the state of the store, you have to do it manually with
* `delete pinia.state.value[store.$id]` if you want to. If you don't and the
* store is used again, it will reuse the previous state.
*/
$dispose(): void;
/* Excluded from this release type: _r */
}
/**
* Callback of a subscription
*/
export declare type SubscriptionCallback<S> = (
/**
* Object with information relative to the store mutation that triggered the
* subscription.
*/
mutation: SubscriptionCallbackMutation<S>,
/**
* State of the store when the subscription is triggered. Same as
* `store.$state`.
*/
state: UnwrapRef<S>) => void;
/**
* Context object passed to a subscription callback.
*/
export declare type SubscriptionCallbackMutation<S> = SubscriptionCallbackMutationDirect | SubscriptionCallbackMutationPatchObject<S> | SubscriptionCallbackMutationPatchFunction;
/**
* Base type for the context passed to a subscription callback. Internal type.
*/
export declare interface _SubscriptionCallbackMutationBase {
/**
* Type of the mutation.
*/
type: MutationType;
/**
* `id` of the store doing the mutation.
*/
storeId: string;
/**
* 🔴 DEV ONLY, DO NOT use for production code. Different mutation calls. Comes from
* https://vuejs.org/guide/extras/reactivity-in-depth.html#reactivity-debugging and allows to track mutations in
* devtools and plugins **during development only**.
*/
events?: DebuggerEvent[] | DebuggerEvent;
}
/**
* Context passed to a subscription callback when directly mutating the state of
* a store with `store.someState = newValue` or `store.$state.someState =
* newValue`.
*/
export declare interface SubscriptionCallbackMutationDirect extends _SubscriptionCallbackMutationBase {
type: MutationType.direct;
events: DebuggerEvent;
}
/**
* Context passed to a subscription callback when `store.$patch()` is called
* with a function.
*/
export declare interface SubscriptionCallbackMutationPatchFunction extends _SubscriptionCallbackMutationBase {
type: MutationType.patchFunction;
events: DebuggerEvent[];
}
/**
* Context passed to a subscription callback when `store.$patch()` is called
* with an object.
*/
export declare interface SubscriptionCallbackMutationPatchObject<S> extends _SubscriptionCallbackMutationBase {
type: MutationType.patchObject;
events: DebuggerEvent[];
/**
* Object passed to `store.$patch()`.
*/
payload: _DeepPartial<S>;
}
declare type ToComputedRefs<T> = {
[K in keyof T]: ToRef<T[K]> extends Ref<infer U> ? ComputedRef<U> : ToRef<T[K]>;
};
/**
* Type that enables refactoring through IDE.
* For internal use **only**
*/
export declare type _UnwrapAll<SS> = {
[K in keyof SS]: UnwrapRef<SS[K]>;
};
export { }
// Extensions of Vue types to be appended manually
// https://github.com/microsoft/rushstack/issues/2090
// https://github.com/microsoft/rushstack/issues/1709
// @ts-ignore: works on Vue 2, fails in Vue 3
declare module 'vue/types/vue' {
interface Vue {
/**
* Currently installed pinia instance.
*/
$pinia: Pinia
/**
* Cache of stores instantiated by the current instance. Used by map
* helpers. Used internally by Pinia.
*
* @internal
*/
_pStores?: Record<string, Store>
}
}
// @ts-ignore: works on Vue 2, fails in Vue 3
declare module 'vue/types/options' {
interface ComponentOptions<V> {
/**
* Pinia instance to install in your application. Should be passed to the
* root Vue.
*/
pinia?: Pinia
}
}
// TODO: figure out why it cannot be 'vue'
// @ts-ignore: works on Vue 3, fails in Vue 2
declare module '@vue/runtime-core' {
export interface ComponentCustomProperties {
/**
* Access to the application's Pinia
*/
$pinia: Pinia
/**
* Cache of stores instantiated by the current instance. Used by devtools to
* list currently used stores. Used internally by Pinia.
*
* @internal
*/
_pStores?: Record<string, StoreGeneric>
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

2004
node_modules/pinia/dist/pinia.mjs generated vendored

File diff suppressed because it is too large Load Diff

@ -0,0 +1,808 @@
/*!
* pinia v2.1.6
* (c) 2023 Eduardo San Martin Morote
* @license MIT
*/
'use strict';
var vueDemi = require('vue-demi');
/**
* setActivePinia must be called to handle SSR at the top of functions like
* `fetch`, `setup`, `serverPrefetch` and others
*/
let activePinia;
/**
* Sets or unsets the active pinia. Used in SSR and internally when calling
* actions and getters
*
* @param pinia - Pinia instance
*/
// @ts-expect-error: cannot constrain the type of the return
const setActivePinia = (pinia) => (activePinia = pinia);
/**
* Get the currently active pinia if there is any.
*/
const getActivePinia = () => (vueDemi.hasInjectionContext() && vueDemi.inject(piniaSymbol)) || activePinia;
const piniaSymbol = (/* istanbul ignore next */ Symbol());
function isPlainObject(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
o) {
return (o &&
typeof o === 'object' &&
Object.prototype.toString.call(o) === '[object Object]' &&
typeof o.toJSON !== 'function');
}
// type DeepReadonly<T> = { readonly [P in keyof T]: DeepReadonly<T[P]> }
// TODO: can we change these to numbers?
/**
* Possible types for SubscriptionCallback
*/
exports.MutationType = void 0;
(function (MutationType) {
/**
* Direct mutation of the state:
*
* - `store.name = 'new name'`
* - `store.$state.name = 'new name'`
* - `store.list.push('new item')`
*/
MutationType["direct"] = "direct";
/**
* Mutated the state with `$patch` and an object
*
* - `store.$patch({ name: 'newName' })`
*/
MutationType["patchObject"] = "patch object";
/**
* Mutated the state with `$patch` and a function
*
* - `store.$patch(state => state.name = 'newName')`
*/
MutationType["patchFunction"] = "patch function";
// maybe reset? for $state = {} and $reset
})(exports.MutationType || (exports.MutationType = {}));
const IS_CLIENT = typeof window !== 'undefined';
/**
* Creates a Pinia instance to be used by the application
*/
function createPinia() {
const scope = vueDemi.effectScope(true);
// NOTE: here we could check the window object for a state and directly set it
// if there is anything like it with Vue 3 SSR
const state = scope.run(() => vueDemi.ref({}));
let _p = [];
// plugins added before calling app.use(pinia)
let toBeInstalled = [];
const pinia = vueDemi.markRaw({
install(app) {
// this allows calling useStore() outside of a component setup after
// installing pinia's plugin
setActivePinia(pinia);
if (!vueDemi.isVue2) {
pinia._a = app;
app.provide(piniaSymbol, pinia);
app.config.globalProperties.$pinia = pinia;
toBeInstalled.forEach((plugin) => _p.push(plugin));
toBeInstalled = [];
}
},
use(plugin) {
if (!this._a && !vueDemi.isVue2) {
toBeInstalled.push(plugin);
}
else {
_p.push(plugin);
}
return this;
},
_p,
// it's actually undefined here
// @ts-expect-error
_a: null,
_e: scope,
_s: new Map(),
state,
});
return pinia;
}
/**
* Creates an _accept_ function to pass to `import.meta.hot` in Vite applications.
*
* @example
* ```js
* const useUser = defineStore(...)
* if (import.meta.hot) {
* import.meta.hot.accept(acceptHMRUpdate(useUser, import.meta.hot))
* }
* ```
*
* @param initialUseStore - return of the defineStore to hot update
* @param hot - `import.meta.hot`
*/
function acceptHMRUpdate(initialUseStore, hot) {
// strip as much as possible from iife.prod
{
return () => { };
}
}
const noop = () => { };
function addSubscription(subscriptions, callback, detached, onCleanup = noop) {
subscriptions.push(callback);
const removeSubscription = () => {
const idx = subscriptions.indexOf(callback);
if (idx > -1) {
subscriptions.splice(idx, 1);
onCleanup();
}
};
if (!detached && vueDemi.getCurrentScope()) {
vueDemi.onScopeDispose(removeSubscription);
}
return removeSubscription;
}
function triggerSubscriptions(subscriptions, ...args) {
subscriptions.slice().forEach((callback) => {
callback(...args);
});
}
const fallbackRunWithContext = (fn) => fn();
function mergeReactiveObjects(target, patchToApply) {
// Handle Map instances
if (target instanceof Map && patchToApply instanceof Map) {
patchToApply.forEach((value, key) => target.set(key, value));
}
// Handle Set instances
if (target instanceof Set && patchToApply instanceof Set) {
patchToApply.forEach(target.add, target);
}
// no need to go through symbols because they cannot be serialized anyway
for (const key in patchToApply) {
if (!patchToApply.hasOwnProperty(key))
continue;
const subPatch = patchToApply[key];
const targetValue = target[key];
if (isPlainObject(targetValue) &&
isPlainObject(subPatch) &&
target.hasOwnProperty(key) &&
!vueDemi.isRef(subPatch) &&
!vueDemi.isReactive(subPatch)) {
// NOTE: here I wanted to warn about inconsistent types but it's not possible because in setup stores one might
// start the value of a property as a certain type e.g. a Map, and then for some reason, during SSR, change that
// to `undefined`. When trying to hydrate, we want to override the Map with `undefined`.
target[key] = mergeReactiveObjects(targetValue, subPatch);
}
else {
// @ts-expect-error: subPatch is a valid value
target[key] = subPatch;
}
}
return target;
}
const skipHydrateSymbol = /* istanbul ignore next */ Symbol();
const skipHydrateMap = /*#__PURE__*/ new WeakMap();
/**
* Tells Pinia to skip the hydration process of a given object. This is useful in setup stores (only) when you return a
* stateful object in the store but it isn't really state. e.g. returning a router instance in a setup store.
*
* @param obj - target object
* @returns obj
*/
function skipHydrate(obj) {
return vueDemi.isVue2
? // in @vue/composition-api, the refs are sealed so defineProperty doesn't work...
/* istanbul ignore next */ skipHydrateMap.set(obj, 1) && obj
: Object.defineProperty(obj, skipHydrateSymbol, {});
}
/**
* Returns whether a value should be hydrated
*
* @param obj - target variable
* @returns true if `obj` should be hydrated
*/
function shouldHydrate(obj) {
return vueDemi.isVue2
? /* istanbul ignore next */ !skipHydrateMap.has(obj)
: !isPlainObject(obj) || !obj.hasOwnProperty(skipHydrateSymbol);
}
const { assign } = Object;
function isComputed(o) {
return !!(vueDemi.isRef(o) && o.effect);
}
function createOptionsStore(id, options, pinia, hot) {
const { state, actions, getters } = options;
const initialState = pinia.state.value[id];
let store;
function setup() {
if (!initialState && (!false )) {
/* istanbul ignore if */
if (vueDemi.isVue2) {
vueDemi.set(pinia.state.value, id, state ? state() : {});
}
else {
pinia.state.value[id] = state ? state() : {};
}
}
// avoid creating a state in pinia.state.value
const localState = vueDemi.toRefs(pinia.state.value[id]);
return assign(localState, actions, Object.keys(getters || {}).reduce((computedGetters, name) => {
computedGetters[name] = vueDemi.markRaw(vueDemi.computed(() => {
setActivePinia(pinia);
// it was created just before
const store = pinia._s.get(id);
// allow cross using stores
/* istanbul ignore next */
if (vueDemi.isVue2 && !store._r)
return;
// @ts-expect-error
// return getters![name].call(context, context)
// TODO: avoid reading the getter while assigning with a global variable
return getters[name].call(store, store);
}));
return computedGetters;
}, {}));
}
store = createSetupStore(id, setup, options, pinia, hot, true);
return store;
}
function createSetupStore($id, setup, options = {}, pinia, hot, isOptionsStore) {
let scope;
const optionsForPlugin = assign({ actions: {} }, options);
// watcher options for $subscribe
const $subscribeOptions = {
deep: true,
// flush: 'post',
};
// internal state
let isListening; // set to true at the end
let isSyncListening; // set to true at the end
let subscriptions = [];
let actionSubscriptions = [];
let debuggerEvents;
const initialState = pinia.state.value[$id];
// avoid setting the state for option stores if it is set
// by the setup
if (!isOptionsStore && !initialState && (!false )) {
/* istanbul ignore if */
if (vueDemi.isVue2) {
vueDemi.set(pinia.state.value, $id, {});
}
else {
pinia.state.value[$id] = {};
}
}
vueDemi.ref({});
// avoid triggering too many listeners
// https://github.com/vuejs/pinia/issues/1129
let activeListener;
function $patch(partialStateOrMutator) {
let subscriptionMutation;
isListening = isSyncListening = false;
if (typeof partialStateOrMutator === 'function') {
partialStateOrMutator(pinia.state.value[$id]);
subscriptionMutation = {
type: exports.MutationType.patchFunction,
storeId: $id,
events: debuggerEvents,
};
}
else {
mergeReactiveObjects(pinia.state.value[$id], partialStateOrMutator);
subscriptionMutation = {
type: exports.MutationType.patchObject,
payload: partialStateOrMutator,
storeId: $id,
events: debuggerEvents,
};
}
const myListenerId = (activeListener = Symbol());
vueDemi.nextTick().then(() => {
if (activeListener === myListenerId) {
isListening = true;
}
});
isSyncListening = true;
// because we paused the watcher, we need to manually call the subscriptions
triggerSubscriptions(subscriptions, subscriptionMutation, pinia.state.value[$id]);
}
const $reset = isOptionsStore
? function $reset() {
const { state } = options;
const newState = state ? state() : {};
// we use a patch to group all changes into one single subscription
this.$patch(($state) => {
assign($state, newState);
});
}
: /* istanbul ignore next */
noop;
function $dispose() {
scope.stop();
subscriptions = [];
actionSubscriptions = [];
pinia._s.delete($id);
}
/**
* Wraps an action to handle subscriptions.
*
* @param name - name of the action
* @param action - action to wrap
* @returns a wrapped action to handle subscriptions
*/
function wrapAction(name, action) {
return function () {
setActivePinia(pinia);
const args = Array.from(arguments);
const afterCallbackList = [];
const onErrorCallbackList = [];
function after(callback) {
afterCallbackList.push(callback);
}
function onError(callback) {
onErrorCallbackList.push(callback);
}
// @ts-expect-error
triggerSubscriptions(actionSubscriptions, {
args,
name,
store,
after,
onError,
});
let ret;
try {
ret = action.apply(this && this.$id === $id ? this : store, args);
// handle sync errors
}
catch (error) {
triggerSubscriptions(onErrorCallbackList, error);
throw error;
}
if (ret instanceof Promise) {
return ret
.then((value) => {
triggerSubscriptions(afterCallbackList, value);
return value;
})
.catch((error) => {
triggerSubscriptions(onErrorCallbackList, error);
return Promise.reject(error);
});
}
// trigger after callbacks
triggerSubscriptions(afterCallbackList, ret);
return ret;
};
}
const partialStore = {
_p: pinia,
// _s: scope,
$id,
$onAction: addSubscription.bind(null, actionSubscriptions),
$patch,
$reset,
$subscribe(callback, options = {}) {
const removeSubscription = addSubscription(subscriptions, callback, options.detached, () => stopWatcher());
const stopWatcher = scope.run(() => vueDemi.watch(() => pinia.state.value[$id], (state) => {
if (options.flush === 'sync' ? isSyncListening : isListening) {
callback({
storeId: $id,
type: exports.MutationType.direct,
events: debuggerEvents,
}, state);
}
}, assign({}, $subscribeOptions, options)));
return removeSubscription;
},
$dispose,
};
/* istanbul ignore if */
if (vueDemi.isVue2) {
// start as non ready
partialStore._r = false;
}
const store = vueDemi.reactive(partialStore);
// store the partial store now so the setup of stores can instantiate each other before they are finished without
// creating infinite loops.
pinia._s.set($id, store);
const runWithContext = (pinia._a && pinia._a.runWithContext) || fallbackRunWithContext;
// TODO: idea create skipSerialize that marks properties as non serializable and they are skipped
const setupStore = pinia._e.run(() => {
scope = vueDemi.effectScope();
return runWithContext(() => scope.run(setup));
});
// overwrite existing actions to support $onAction
for (const key in setupStore) {
const prop = setupStore[key];
if ((vueDemi.isRef(prop) && !isComputed(prop)) || vueDemi.isReactive(prop)) {
// mark it as a piece of state to be serialized
if (!isOptionsStore) {
// in setup stores we must hydrate the state and sync pinia state tree with the refs the user just created
if (initialState && shouldHydrate(prop)) {
if (vueDemi.isRef(prop)) {
prop.value = initialState[key];
}
else {
// probably a reactive object, lets recursively assign
// @ts-expect-error: prop is unknown
mergeReactiveObjects(prop, initialState[key]);
}
}
// transfer the ref to the pinia state to keep everything in sync
/* istanbul ignore if */
if (vueDemi.isVue2) {
vueDemi.set(pinia.state.value[$id], key, prop);
}
else {
pinia.state.value[$id][key] = prop;
}
}
// action
}
else if (typeof prop === 'function') {
// @ts-expect-error: we are overriding the function we avoid wrapping if
const actionValue = wrapAction(key, prop);
// this a hot module replacement store because the hotUpdate method needs
// to do it with the right context
/* istanbul ignore if */
if (vueDemi.isVue2) {
vueDemi.set(setupStore, key, actionValue);
}
else {
// @ts-expect-error
setupStore[key] = actionValue;
}
// list actions so they can be used in plugins
// @ts-expect-error
optionsForPlugin.actions[key] = prop;
}
else ;
}
// add the state, getters, and action properties
/* istanbul ignore if */
if (vueDemi.isVue2) {
Object.keys(setupStore).forEach((key) => {
vueDemi.set(store, key, setupStore[key]);
});
}
else {
assign(store, setupStore);
// allows retrieving reactive objects with `storeToRefs()`. Must be called after assigning to the reactive object.
// Make `storeToRefs()` work with `reactive()` #799
assign(vueDemi.toRaw(store), setupStore);
}
// use this instead of a computed with setter to be able to create it anywhere
// without linking the computed lifespan to wherever the store is first
// created.
Object.defineProperty(store, '$state', {
get: () => (pinia.state.value[$id]),
set: (state) => {
$patch(($state) => {
assign($state, state);
});
},
});
/* istanbul ignore if */
if (vueDemi.isVue2) {
// mark the store as ready before plugins
store._r = true;
}
// apply all plugins
pinia._p.forEach((extender) => {
/* istanbul ignore else */
{
assign(store, scope.run(() => extender({
store,
app: pinia._a,
pinia,
options: optionsForPlugin,
})));
}
});
// only apply hydrate to option stores with an initial state in pinia
if (initialState &&
isOptionsStore &&
options.hydrate) {
options.hydrate(store.$state, initialState);
}
isListening = true;
isSyncListening = true;
return store;
}
function defineStore(
// TODO: add proper types from above
idOrOptions, setup, setupOptions) {
let id;
let options;
const isSetupStore = typeof setup === 'function';
if (typeof idOrOptions === 'string') {
id = idOrOptions;
// the option store setup will contain the actual options in this case
options = isSetupStore ? setupOptions : setup;
}
else {
options = idOrOptions;
id = idOrOptions.id;
}
function useStore(pinia, hot) {
const hasContext = vueDemi.hasInjectionContext();
pinia =
// in test mode, ignore the argument provided as we can always retrieve a
// pinia instance with getActivePinia()
((process.env.NODE_ENV === 'test') && activePinia && activePinia._testing ? null : pinia) ||
(hasContext ? vueDemi.inject(piniaSymbol, null) : null);
if (pinia)
setActivePinia(pinia);
pinia = activePinia;
if (!pinia._s.has(id)) {
// creating the store registers it in `pinia._s`
if (isSetupStore) {
createSetupStore(id, setup, options, pinia);
}
else {
createOptionsStore(id, options, pinia);
}
}
const store = pinia._s.get(id);
// StoreGeneric cannot be casted towards Store
return store;
}
useStore.$id = id;
return useStore;
}
let mapStoreSuffix = 'Store';
/**
* Changes the suffix added by `mapStores()`. Can be set to an empty string.
* Defaults to `"Store"`. Make sure to extend the MapStoresCustomization
* interface if you are using TypeScript.
*
* @param suffix - new suffix
*/
function setMapStoreSuffix(suffix // could be 'Store' but that would be annoying for JS
) {
mapStoreSuffix = suffix;
}
/**
* Allows using stores without the composition API (`setup()`) by generating an
* object to be spread in the `computed` field of a component. It accepts a list
* of store definitions.
*
* @example
* ```js
* export default {
* computed: {
* // other computed properties
* ...mapStores(useUserStore, useCartStore)
* },
*
* created() {
* this.userStore // store with id "user"
* this.cartStore // store with id "cart"
* }
* }
* ```
*
* @param stores - list of stores to map to an object
*/
function mapStores(...stores) {
return stores.reduce((reduced, useStore) => {
// @ts-expect-error: $id is added by defineStore
reduced[useStore.$id + mapStoreSuffix] = function () {
return useStore(this.$pinia);
};
return reduced;
}, {});
}
/**
* Allows using state and getters from one store without using the composition
* API (`setup()`) by generating an object to be spread in the `computed` field
* of a component.
*
* @param useStore - store to map from
* @param keysOrMapper - array or object
*/
function mapState(useStore, keysOrMapper) {
return Array.isArray(keysOrMapper)
? keysOrMapper.reduce((reduced, key) => {
reduced[key] = function () {
return useStore(this.$pinia)[key];
};
return reduced;
}, {})
: Object.keys(keysOrMapper).reduce((reduced, key) => {
// @ts-expect-error
reduced[key] = function () {
const store = useStore(this.$pinia);
const storeKey = keysOrMapper[key];
// for some reason TS is unable to infer the type of storeKey to be a
// function
return typeof storeKey === 'function'
? storeKey.call(this, store)
: store[storeKey];
};
return reduced;
}, {});
}
/**
* Alias for `mapState()`. You should use `mapState()` instead.
* @deprecated use `mapState()` instead.
*/
const mapGetters = mapState;
/**
* Allows directly using actions from your store without using the composition
* API (`setup()`) by generating an object to be spread in the `methods` field
* of a component.
*
* @param useStore - store to map from
* @param keysOrMapper - array or object
*/
function mapActions(useStore, keysOrMapper) {
return Array.isArray(keysOrMapper)
? keysOrMapper.reduce((reduced, key) => {
// @ts-expect-error
reduced[key] = function (...args) {
return useStore(this.$pinia)[key](...args);
};
return reduced;
}, {})
: Object.keys(keysOrMapper).reduce((reduced, key) => {
// @ts-expect-error
reduced[key] = function (...args) {
return useStore(this.$pinia)[keysOrMapper[key]](...args);
};
return reduced;
}, {});
}
/**
* Allows using state and getters from one store without using the composition
* API (`setup()`) by generating an object to be spread in the `computed` field
* of a component.
*
* @param useStore - store to map from
* @param keysOrMapper - array or object
*/
function mapWritableState(useStore, keysOrMapper) {
return Array.isArray(keysOrMapper)
? keysOrMapper.reduce((reduced, key) => {
// @ts-ignore
reduced[key] = {
get() {
return useStore(this.$pinia)[key];
},
set(value) {
// it's easier to type it here as any
return (useStore(this.$pinia)[key] = value);
},
};
return reduced;
}, {})
: Object.keys(keysOrMapper).reduce((reduced, key) => {
// @ts-ignore
reduced[key] = {
get() {
return useStore(this.$pinia)[keysOrMapper[key]];
},
set(value) {
// it's easier to type it here as any
return (useStore(this.$pinia)[keysOrMapper[key]] = value);
},
};
return reduced;
}, {});
}
/**
* Creates an object of references with all the state, getters, and plugin-added
* state properties of the store. Similar to `toRefs()` but specifically
* designed for Pinia stores so methods and non reactive properties are
* completely ignored.
*
* @param store - store to extract the refs from
*/
function storeToRefs(store) {
// See https://github.com/vuejs/pinia/issues/852
// It's easier to just use toRefs() even if it includes more stuff
if (vueDemi.isVue2) {
// @ts-expect-error: toRefs include methods and others
return vueDemi.toRefs(store);
}
else {
store = vueDemi.toRaw(store);
const refs = {};
for (const key in store) {
const value = store[key];
if (vueDemi.isRef(value) || vueDemi.isReactive(value)) {
// @ts-expect-error: the key is state or getter
refs[key] =
// ---
vueDemi.toRef(store, key);
}
}
return refs;
}
}
/**
* Vue 2 Plugin that must be installed for pinia to work. Note **you don't need
* this plugin if you are using Nuxt.js**. Use the `buildModule` instead:
* https://pinia.vuejs.org/ssr/nuxt.html.
*
* @example
* ```js
* import Vue from 'vue'
* import { PiniaVuePlugin, createPinia } from 'pinia'
*
* Vue.use(PiniaVuePlugin)
* const pinia = createPinia()
*
* new Vue({
* el: '#app',
* // ...
* pinia,
* })
* ```
*
* @param _Vue - `Vue` imported from 'vue'.
*/
const PiniaVuePlugin = function (_Vue) {
// Equivalent of
// app.config.globalProperties.$pinia = pinia
_Vue.mixin({
beforeCreate() {
const options = this.$options;
if (options.pinia) {
const pinia = options.pinia;
// HACK: taken from provide(): https://github.com/vuejs/composition-api/blob/main/src/apis/inject.ts#L31
/* istanbul ignore else */
if (!this._provided) {
const provideCache = {};
Object.defineProperty(this, '_provided', {
get: () => provideCache,
set: (v) => Object.assign(provideCache, v),
});
}
this._provided[piniaSymbol] = pinia;
// propagate the pinia instance in an SSR friendly way
// avoid adding it to nuxt twice
/* istanbul ignore else */
if (!this.$pinia) {
this.$pinia = pinia;
}
pinia._a = this;
if (IS_CLIENT) {
// this allows calling useStore() outside of a component setup after
// installing pinia's plugin
setActivePinia(pinia);
}
}
else if (!this.$pinia && options.parent && options.parent.$pinia) {
this.$pinia = options.parent.$pinia;
}
},
destroyed() {
delete this._pStores;
},
});
};
exports.PiniaVuePlugin = PiniaVuePlugin;
exports.acceptHMRUpdate = acceptHMRUpdate;
exports.createPinia = createPinia;
exports.defineStore = defineStore;
exports.getActivePinia = getActivePinia;
exports.mapActions = mapActions;
exports.mapGetters = mapGetters;
exports.mapState = mapState;
exports.mapStores = mapStores;
exports.mapWritableState = mapWritableState;
exports.setActivePinia = setActivePinia;
exports.setMapStoreSuffix = setMapStoreSuffix;
exports.skipHydrate = skipHydrate;
exports.storeToRefs = storeToRefs;

7
node_modules/pinia/index.cjs generated vendored

@ -0,0 +1,7 @@
'use strict'
if (process.env.NODE_ENV === 'production') {
module.exports = require('./dist/pinia.prod.cjs')
} else {
module.exports = require('./dist/pinia.cjs')
}

7
node_modules/pinia/index.js generated vendored

@ -0,0 +1,7 @@
'use strict'
if (process.env.NODE_ENV === 'production') {
module.exports = require('./dist/pinia.prod.cjs')
} else {
module.exports = require('./dist/pinia.cjs')
}

100
node_modules/pinia/package.json generated vendored

@ -0,0 +1,100 @@
{
"name": "pinia",
"version": "2.1.6",
"description": "Intuitive, type safe and flexible Store for Vue",
"main": "index.js",
"module": "dist/pinia.mjs",
"unpkg": "dist/pinia.iife.js",
"jsdelivr": "dist/pinia.iife.js",
"types": "dist/pinia.d.ts",
"exports": {
".": {
"types": "./dist/pinia.d.ts",
"node": {
"import": {
"production": "./dist/pinia.prod.cjs",
"development": "./dist/pinia.mjs",
"default": "./dist/pinia.mjs"
},
"require": {
"production": "./dist/pinia.prod.cjs",
"development": "./dist/pinia.cjs",
"default": "./index.js"
}
},
"import": "./dist/pinia.mjs",
"require": "./index.js"
},
"./package.json": "./package.json",
"./dist/*": "./dist/*"
},
"sideEffects": false,
"author": {
"name": "Eduardo San Martin Morote",
"email": "posva13@gmail.com"
},
"funding": "https://github.com/sponsors/posva",
"files": [
"dist/*.js",
"dist/*.mjs",
"dist/*.cjs",
"dist/pinia.d.ts",
"index.js",
"index.cjs",
"LICENSE",
"README.md"
],
"keywords": [
"vue",
"vuex",
"store",
"pinia",
"piña",
"pigna",
"composition",
"api",
"setup",
"typed",
"typescript",
"ts",
"type",
"safe"
],
"license": "MIT",
"devDependencies": {
"@microsoft/api-extractor": "7.34.4",
"@vue/test-utils": "^2.4.0"
},
"dependencies": {
"@vue/devtools-api": "^6.5.0",
"vue-demi": ">=0.14.5"
},
"peerDependencies": {
"@vue/composition-api": "^1.4.0",
"typescript": ">=4.4.4",
"vue": "^2.6.14 || ^3.3.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
},
"@vue/composition-api": {
"optional": true
}
},
"repository": {
"type": "git",
"url": "git+https://github.com/vuejs/pinia.git"
},
"bugs": {
"url": "https://github.com/vuejs/pinia/issues"
},
"homepage": "https://github.com/vuejs/pinia#readme",
"scripts": {
"build": "rimraf dist && rollup -c ../../rollup.config.mjs --environment TARGET:pinia",
"build:dts": "api-extractor run --local --verbose && tail -n +3 ./src/globalExtensions.ts >> dist/pinia.d.ts",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s --commit-path . -l pinia -r 1",
"test:dts": "tsc -p ./test-dts/tsconfig.json",
"test": "yarn run build && yarn run build:dts && yarn test:dts"
}
}

21
node_modules/vue-demi/LICENSE generated vendored

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020-present, Anthony Fu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

228
node_modules/vue-demi/README.md generated vendored

@ -0,0 +1,228 @@
<p align="center">
<img src="https://github.com/vueuse/vue-demi/blob/main/assets/banner.png?raw=true" width="600"/>
<br>
<a href='https://www.npmjs.com/package/vue-demi'><img src='https://img.shields.io/npm/v/vue-demi?color=42b883' alt='npm'></a>
</p>
<p align="center">
<b>Vue Demi</b> (<i>half</i> in French) is a developing utility<br> allows you to write <b>Universal Vue Libraries</b> for Vue 2 & 3<br>
<i>See more details in <a href='https://antfu.me/posts/make-libraries-working-with-vue-2-and-3'>this blog post</a></i>
</p>
<br>
<br>
## Strategies
- `<=2.6`: exports from `vue` + `@vue/composition-api` with plugin auto installing.
- `2.7`: exports from `vue` (Composition API is built-in in Vue 2.7).
- `>=3.0`: exports from `vue`, with polyfill of Vue 2's `set` and `del` API.
## Usage
Install this as your plugin's dependency:
```bash
npm i vue-demi
# or
yarn add vue-demi
# or
pnpm i vue-demi
```
Add `vue` and `@vue/composition-api` to your plugin's peer dependencies to specify what versions you support.
```jsonc
{
"dependencies": {
"vue-demi": "latest"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^2.0.0 || >=3.0.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
},
"devDependencies": {
"vue": "^3.0.0" // or "^2.6.0" base on your preferred working environment
},
}
```
Import everything related to Vue from it, it will redirect to `vue@2` + `@vue/composition-api` or `vue@3` based on users' environments.
```ts
import { ref, reactive, defineComponent } from 'vue-demi'
```
Publish your plugin and all is done!
> When using with [Vite](https://vitejs.dev), you will need to opt-out the pre-bundling to get `vue-demi` work properly by
> ```js
> // vite.config.js
> export default defineConfig({
> optimizeDeps: {
> exclude: ['vue-demi']
> }
> })
> ```
### Extra APIs
`Vue Demi` provides extra APIs to help distinguish users' environments and to do some version-specific logic.
### `isVue2` `isVue3`
```ts
import { isVue2, isVue3 } from 'vue-demi'
if (isVue2) {
// Vue 2 only
} else {
// Vue 3 only
}
```
### `Vue2`
To avoid bringing in all the tree-shakable modules, we provide a `Vue2` export to support access to Vue 2's global API. (See [#41](https://github.com/vueuse/vue-demi/issues/41).)
```ts
import { Vue2 } from 'vue-demi'
if (Vue2) {
Vue2.config.ignoredElements.push('x-foo')
}
```
### `install()`
Composition API in Vue 2 is provided as a plugin and needs to be installed on the Vue instance before using. Normally, `vue-demi` will try to install it automatically. For some usages where you might need to ensure the plugin gets installed correctly, the `install()` API is exposed to as a safe version of `Vue.use(CompositionAPI)`. `install()` in the Vue 3 environment will be an empty function (no-op).
```ts
import { install } from 'vue-demi'
install()
```
## CLI
### Manually Switch Versions
To explicitly switch the redirecting version, you can use these commands in your project's root.
```bash
npx vue-demi-switch 2
# or
npx vue-demi-switch 3
```
### Package Aliasing
If you would like to import `vue` under an alias, you can use the following command
```bash
npx vue-demi-switch 2 vue2
# or
npx vue-demi-switch 3 vue3
```
Then `vue-demi` will redirect APIs from the alias name you specified, for example:
```ts
import * as Vue from 'vue3'
var isVue2 = false
var isVue3 = true
var Vue2 = undefined
export * from 'vue3'
export {
Vue,
Vue2,
isVue2,
isVue3,
}
```
### Auto Fix
If the `postinstall` hook doesn't get triggered or you have updated the Vue version, try to run the following command to resolve the redirecting.
```bash
npx vue-demi-fix
```
### Isomorphic Testings
You can support testing for both versions by adding npm alias in your dev dependencies. For example:
```json
{
"scripts": {
"test:2": "vue-demi-switch 2 vue2 && jest",
"test:3": "vue-demi-switch 3 && jest",
},
"devDependencies": {
"vue": "^3.0.0",
"vue2": "npm:vue@2"
},
}
```
or
```json
{
"scripts": {
"test:2": "vue-demi-switch 2 && jest",
"test:3": "vue-demi-switch 3 vue3 && jest",
},
"devDependencies": {
"vue": "^2.6.0",
"vue3": "npm:vue@3"
},
}
```
## Examples
See [examples](./examples).
## Who is using this?
- [VueUse](https://github.com/vueuse/vueuse) - Collection of Composition API utils
- [@vue/apollo-composable](https://github.com/vuejs/vue-apollo/tree/v4/packages/vue-apollo-composable) - Apollo GraphQL functions for Vue Composition API
- [vuelidate](https://github.com/vuelidate/vuelidate) - Simple, lightweight model-based validation
- [vue-composition-test-utils](https://github.com/ariesjia/vue-composition-test-utils) - Simple vue composition api unit test utilities
- [vue-use-stripe](https://github.com/frandiox/vue-use-stripe) - Stripe Elements wrapper for Vue.js
- [@opd/g2plot-vue](https://github.com/open-data-plan/g2plot-vue) - G2plot for vue
- [vue-echarts](https://github.com/ecomfe/vue-echarts) - Vue.js component for Apache ECharts.
- [fluent-vue](https://github.com/Demivan/fluent-vue) - Vue.js integration for [Fluent.js](https://github.com/projectfluent/fluent.js) - JavaScript implementation of [Project Fluent](https://projectfluent.org)
- [vue-datatable-url-sync](https://github.com/socotecio/vue-datatable-url-sync) - Synchronize datatable options and filters with the url to keep user preference even after refresh or navigation
- [vue-insta-stories](https://github.com/UnevenSoftware/vue-insta-stories) - Instagram stories in your vue projects.
- [vue-tiny-validate](https://github.com/FrontLabsOfficial/vue-tiny-validate) - Tiny Vue Validate Composition
- [v-perfect-signature](https://github.com/wobsoriano/v-perfect-signature) - Pressure-sensitive signature drawing for Vue 2 and 3
- [vue-winbox](https://github.com/wobsoriano/vue-winbox) - A wrapper component for WinBox.js that adds the ability to mount Vue components.
- [vue-word-highlighter](https://github.com/kawamataryo/vue-word-highlighter) - The word highlighter library for Vue 2 and Vue 3
- [vue-chart-3](https://github.com/victorgarciaesgi/vue-chart-3) - Vue.js component for Chart.js
- [json-editor-vue](https://github.com/cloydlau/json-editor-vue) - JSON editor & viewer for Vue 2 and 3.
- [kidar-echarts](https://github.com/kidarjs/kidar-echarts) - A simpler echarts component for Vue 2 and 3.
- [vue3-sketch-ruler](https://github.com/kakajun/vue3-sketch-ruler) - The zoom operation used for page presentation for Vue 2 and 3( Replace render function with template )
- [vue-rough-notation](https://github.com/Leecason/vue-rough-notation) - RoughNotation wrapper component for Vue 2 and 3.
- [vue-request](https://github.com/AttoJS/vue-request) - Vue composition API for data fetching, supports SWR, polling, error retry, cache request, pagination, etc.
- [vue3-lazyload](https://github.com/murongg/vue3-lazyload) - A vue3.x image lazyload plugin.
- [vue-codemirror6](https://github.com/logue/vue-codemirror6) - CodeMirror6 component for Vue2 and 3.
> open a PR to add your library ;)
## Underhood
See [the blog post](https://antfu.me/posts/make-libraries-working-with-vue-2-and-3/#-introducing-vue-demi).
## License
MIT License © 2020 [Anthony Fu](https://github.com/antfu)

@ -0,0 +1,3 @@
#!/usr/bin/env node
'use strict'
require('../scripts/postinstall')

@ -0,0 +1,3 @@
#!/usr/bin/env node
'use strict'
require('../scripts/switch-cli')

@ -0,0 +1,32 @@
var Vue = require('vue')
var VueCompositionAPI = require('@vue/composition-api')
function install(_vue) {
var vueLib = _vue || Vue
if (vueLib && 'default' in vueLib) {
vueLib = vueLib.default
}
if (vueLib && !vueLib['__composition_api_installed__']) {
if (VueCompositionAPI && 'default' in VueCompositionAPI)
vueLib.use(VueCompositionAPI.default)
else if (VueCompositionAPI)
vueLib.use(VueCompositionAPI)
}
}
install(Vue)
Object.keys(VueCompositionAPI).forEach(function(key) {
exports[key] = VueCompositionAPI[key]
})
exports.Vue = Vue
exports.Vue2 = Vue
exports.isVue2 = true
exports.isVue3 = false
exports.install = install
exports.version = Vue.version
// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance()
exports.hasInjectionContext = () => !!VueCompositionAPI.getCurrentInstance()

@ -0,0 +1,33 @@
import Vue from 'vue'
import type { PluginFunction, PluginObject } from 'vue'
declare const isVue2: boolean
declare const isVue3: boolean
declare const Vue2: typeof Vue | undefined
declare const version: string
declare const install: (vue?: typeof Vue) => void
/**
* @deprecated To avoid bringing in all the tree-shakable modules, this API has been deprecated. Use `Vue2` or named exports instead.
* Refer to https://github.com/vueuse/vue-demi/issues/41
*/
declare const V: typeof Vue
/**
* DebuggerEvent is a Vue 3 development only feature. This type cannot exist in Vue 2.
*/
export declare type DebuggerEvent = never
// accept no generic because Vue 3 doesn't accept any
// https://github.com/vuejs/vue-next/pull/2758/
export declare type Plugin = PluginObject<any> | PluginFunction<any>
export type { VNode } from 'vue'
export * from '@vue/composition-api'
export {
V as Vue,
Vue2,
isVue2,
isVue3,
version,
install,
}
export declare function hasInjectionContext(): boolean

@ -0,0 +1,115 @@
var VueDemi = (function (VueDemi, Vue, VueCompositionAPI) {
if (VueDemi.install) {
return VueDemi
}
if (!Vue) {
console.error('[vue-demi] no Vue instance found, please be sure to import `vue` before `vue-demi`.')
return VueDemi
}
// Vue 2.7
if (Vue.version.slice(0, 4) === '2.7.') {
for (var key in Vue) {
VueDemi[key] = Vue[key]
}
VueDemi.isVue2 = true
VueDemi.isVue3 = false
VueDemi.install = function () {}
VueDemi.Vue = Vue
VueDemi.Vue2 = Vue
VueDemi.version = Vue.version
VueDemi.warn = Vue.util.warn
VueDemi.hasInjectionContext = () => !!VueDemi.getCurrentInstance()
function createApp(rootComponent, rootProps) {
var vm
var provide = {}
var app = {
config: Vue.config,
use: Vue.use.bind(Vue),
mixin: Vue.mixin.bind(Vue),
component: Vue.component.bind(Vue),
provide: function (key, value) {
provide[key] = value
return this
},
directive: function (name, dir) {
if (dir) {
Vue.directive(name, dir)
return app
} else {
return Vue.directive(name)
}
},
mount: function (el, hydrating) {
if (!vm) {
vm = new Vue(Object.assign({ propsData: rootProps }, rootComponent, { provide: Object.assign(provide, rootComponent.provide) }))
vm.$mount(el, hydrating)
return vm
} else {
return vm
}
},
unmount: function () {
if (vm) {
vm.$destroy()
vm = undefined
}
},
}
return app
}
VueDemi.createApp = createApp
}
// Vue 2.6.x
else if (Vue.version.slice(0, 2) === '2.') {
if (VueCompositionAPI) {
for (var key in VueCompositionAPI) {
VueDemi[key] = VueCompositionAPI[key]
}
VueDemi.isVue2 = true
VueDemi.isVue3 = false
VueDemi.install = function () {}
VueDemi.Vue = Vue
VueDemi.Vue2 = Vue
VueDemi.version = Vue.version
VueDemi.hasInjectionContext = () => !!VueDemi.getCurrentInstance()
} else {
console.error('[vue-demi] no VueCompositionAPI instance found, please be sure to import `@vue/composition-api` before `vue-demi`.')
}
}
// Vue 3
else if (Vue.version.slice(0, 2) === '3.') {
for (var key in Vue) {
VueDemi[key] = Vue[key]
}
VueDemi.isVue2 = false
VueDemi.isVue3 = true
VueDemi.install = function () {}
VueDemi.Vue = Vue
VueDemi.Vue2 = undefined
VueDemi.version = Vue.version
VueDemi.set = function (target, key, val) {
if (Array.isArray(target)) {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
return val
}
target[key] = val
return val
}
VueDemi.del = function (target, key) {
if (Array.isArray(target)) {
target.splice(key, 1)
return
}
delete target[key]
}
} else {
console.error('[vue-demi] Vue version ' + Vue.version + ' is unsupported.')
}
return VueDemi
})(
(this.VueDemi = this.VueDemi || (typeof VueDemi !== 'undefined' ? VueDemi : {})),
this.Vue || (typeof Vue !== 'undefined' ? Vue : undefined),
this.VueCompositionAPI || (typeof VueCompositionAPI !== 'undefined' ? VueCompositionAPI : undefined)
);

@ -0,0 +1,49 @@
import Vue from 'vue'
import VueCompositionAPI, { getCurrentInstance } from '@vue/composition-api/dist/vue-composition-api.mjs'
function install(_vue) {
_vue = _vue || Vue
if (_vue && !_vue['__composition_api_installed__'])
_vue.use(VueCompositionAPI)
}
install(Vue)
var isVue2 = true
var isVue3 = false
var Vue2 = Vue
var version = Vue.version
/**VCA-EXPORTS**/
export * from '@vue/composition-api/dist/vue-composition-api.mjs'
/**VCA-EXPORTS**/
export {
Vue,
Vue2,
isVue2,
isVue3,
version,
install,
}
// Vue 3 components mock
function createMockComponent(name) {
return {
setup() {
throw new Error('[vue-demi] ' + name + ' is not supported in Vue 2. It\'s provided to avoid compiler errors.')
}
}
}
export var Fragment = /*#__PURE__*/ createMockComponent('Fragment')
export var Transition = /*#__PURE__*/ createMockComponent('Transition')
export var TransitionGroup = /*#__PURE__*/ createMockComponent('TransitionGroup')
export var Teleport = /*#__PURE__*/ createMockComponent('Teleport')
export var Suspense = /*#__PURE__*/ createMockComponent('Suspense')
export var KeepAlive = /*#__PURE__*/ createMockComponent('KeepAlive')
// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance()
export function hasInjectionContext() {
return !!getCurrentInstance()
}

@ -0,0 +1,58 @@
var VueModule = require('vue')
// get the real Vue https://github.com/vueuse/vue-demi/issues/192
var Vue = VueModule.default || VueModule
exports.Vue = Vue
exports.Vue2 = Vue
exports.isVue2 = true
exports.isVue3 = false
exports.install = function () {}
exports.warn = Vue.util.warn
// createApp polyfill
exports.createApp = function (rootComponent, rootProps) {
var vm
var provide = {}
var app = {
config: Vue.config,
use: Vue.use.bind(Vue),
mixin: Vue.mixin.bind(Vue),
component: Vue.component.bind(Vue),
provide: function (key, value) {
provide[key] = value
return this
},
directive: function (name, dir) {
if (dir) {
Vue.directive(name, dir)
return app
} else {
return Vue.directive(name)
}
},
mount: function (el, hydrating) {
if (!vm) {
vm = new Vue(Object.assign({ propsData: rootProps }, rootComponent, { provide: Object.assign(provide, rootComponent.provide) }))
vm.$mount(el, hydrating)
return vm
} else {
return vm
}
},
unmount: function () {
if (vm) {
vm.$destroy()
vm = undefined
}
},
}
return app
}
Object.keys(VueModule).forEach(function (key) {
exports[key] = VueModule[key]
})
// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance()
exports.hasInjectionContext = () => !!VueModule.getCurrentInstance()

@ -0,0 +1,38 @@
import Vue from 'vue'
import type { PluginFunction, PluginObject, VueConstructor, Directive, InjectionKey, Component } from 'vue'
declare const isVue2: boolean
declare const isVue3: boolean
declare const Vue2: typeof Vue | undefined
declare const version: string
declare const install: (vue?: typeof Vue) => void
export declare function warn(msg: string, vm?: Component | null): void
/**
* @deprecated To avoid bringing in all the tree-shakable modules, this API has been deprecated. Use `Vue2` or named exports instead.
* Refer to https://github.com/vueuse/vue-demi/issues/41
*/
declare const V: typeof Vue
// accept no generic because Vue 3 doesn't accept any
// https://github.com/vuejs/vue-next/pull/2758/
export declare type Plugin = PluginObject<any> | PluginFunction<any>
export type { VNode } from 'vue'
export * from 'vue'
export { V as Vue, Vue2, isVue2, isVue3, version, install }
// #region createApp polyfill
export interface App<T = any> {
config: VueConstructor['config']
use: VueConstructor['use']
mixin: VueConstructor['mixin']
component: VueConstructor['component']
directive(name: string): Directive | undefined
directive(name: string, directive: Directive): this
provide<T>(key: InjectionKey<T> | string, value: T): this
mount: Vue['$mount']
unmount: Vue['$destroy']
}
export declare function createApp(rootComponent: any, rootProps?: any): App
// #endregion
export declare function hasInjectionContext(): boolean

@ -0,0 +1,80 @@
import Vue from 'vue'
import { getCurrentInstance } from 'vue'
var isVue2 = true
var isVue3 = false
var Vue2 = Vue
var warn = Vue.util.warn
function install() {}
// createApp polyfill
export function createApp(rootComponent, rootProps) {
var vm
var provide = {}
var app = {
config: Vue.config,
use: Vue.use.bind(Vue),
mixin: Vue.mixin.bind(Vue),
component: Vue.component.bind(Vue),
provide: function (key, value) {
provide[key] = value
return this
},
directive: function (name, dir) {
if (dir) {
Vue.directive(name, dir)
return app
} else {
return Vue.directive(name)
}
},
mount: function (el, hydrating) {
if (!vm) {
vm = new Vue(Object.assign({ propsData: rootProps }, rootComponent, { provide: Object.assign(provide, rootComponent.provide) }))
vm.$mount(el, hydrating)
return vm
} else {
return vm
}
},
unmount: function () {
if (vm) {
vm.$destroy()
vm = undefined
}
},
}
return app
}
export {
Vue,
Vue2,
isVue2,
isVue3,
install,
warn
}
// Vue 3 components mock
function createMockComponent(name) {
return {
setup() {
throw new Error('[vue-demi] ' + name + ' is not supported in Vue 2. It\'s provided to avoid compiler errors.')
}
}
}
export var Fragment = /*#__PURE__*/ createMockComponent('Fragment')
export var Transition = /*#__PURE__*/ createMockComponent('Transition')
export var TransitionGroup = /*#__PURE__*/ createMockComponent('TransitionGroup')
export var Teleport = /*#__PURE__*/ createMockComponent('Teleport')
export var Suspense = /*#__PURE__*/ createMockComponent('Suspense')
export var KeepAlive = /*#__PURE__*/ createMockComponent('KeepAlive')
export * from 'vue'
// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance()
export function hasInjectionContext() {
return !!getCurrentInstance()
}

@ -0,0 +1,32 @@
var Vue = require('vue')
var VueCompositionAPI = require('@vue/composition-api')
function install(_vue) {
var vueLib = _vue || Vue
if (vueLib && 'default' in vueLib) {
vueLib = vueLib.default
}
if (vueLib && !vueLib['__composition_api_installed__']) {
if (VueCompositionAPI && 'default' in VueCompositionAPI)
vueLib.use(VueCompositionAPI.default)
else if (VueCompositionAPI)
vueLib.use(VueCompositionAPI)
}
}
install(Vue)
Object.keys(VueCompositionAPI).forEach(function(key) {
exports[key] = VueCompositionAPI[key]
})
exports.Vue = Vue
exports.Vue2 = Vue
exports.isVue2 = true
exports.isVue3 = false
exports.install = install
exports.version = Vue.version
// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance()
exports.hasInjectionContext = () => !!VueCompositionAPI.getCurrentInstance()

@ -0,0 +1,33 @@
import Vue from 'vue'
import type { PluginFunction, PluginObject } from 'vue'
declare const isVue2: boolean
declare const isVue3: boolean
declare const Vue2: typeof Vue | undefined
declare const version: string
declare const install: (vue?: typeof Vue) => void
/**
* @deprecated To avoid bringing in all the tree-shakable modules, this API has been deprecated. Use `Vue2` or named exports instead.
* Refer to https://github.com/vueuse/vue-demi/issues/41
*/
declare const V: typeof Vue
/**
* DebuggerEvent is a Vue 3 development only feature. This type cannot exist in Vue 2.
*/
export declare type DebuggerEvent = never
// accept no generic because Vue 3 doesn't accept any
// https://github.com/vuejs/vue-next/pull/2758/
export declare type Plugin = PluginObject<any> | PluginFunction<any>
export type { VNode } from 'vue'
export * from '@vue/composition-api'
export {
V as Vue,
Vue2,
isVue2,
isVue3,
version,
install,
}
export declare function hasInjectionContext(): boolean

@ -0,0 +1,49 @@
import Vue from 'vue'
import VueCompositionAPI, { getCurrentInstance } from '@vue/composition-api/dist/vue-composition-api.mjs'
function install(_vue) {
_vue = _vue || Vue
if (_vue && !_vue['__composition_api_installed__'])
_vue.use(VueCompositionAPI)
}
install(Vue)
var isVue2 = true
var isVue3 = false
var Vue2 = Vue
var version = Vue.version
/**VCA-EXPORTS**/
export * from '@vue/composition-api/dist/vue-composition-api.mjs'
/**VCA-EXPORTS**/
export {
Vue,
Vue2,
isVue2,
isVue3,
version,
install,
}
// Vue 3 components mock
function createMockComponent(name) {
return {
setup() {
throw new Error('[vue-demi] ' + name + ' is not supported in Vue 2. It\'s provided to avoid compiler errors.')
}
}
}
export var Fragment = /*#__PURE__*/ createMockComponent('Fragment')
export var Transition = /*#__PURE__*/ createMockComponent('Transition')
export var TransitionGroup = /*#__PURE__*/ createMockComponent('TransitionGroup')
export var Teleport = /*#__PURE__*/ createMockComponent('Teleport')
export var Suspense = /*#__PURE__*/ createMockComponent('Suspense')
export var KeepAlive = /*#__PURE__*/ createMockComponent('KeepAlive')
// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance()
export function hasInjectionContext() {
return !!getCurrentInstance()
}

@ -0,0 +1,29 @@
var Vue = require('vue')
Object.keys(Vue).forEach(function(key) {
exports[key] = Vue[key]
})
exports.set = function(target, key, val) {
if (Array.isArray(target)) {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
return val
}
target[key] = val
return val
}
exports.del = function(target, key) {
if (Array.isArray(target)) {
target.splice(key, 1)
return
}
delete target[key]
}
exports.Vue = Vue
exports.Vue2 = undefined
exports.isVue2 = false
exports.isVue3 = true
exports.install = function(){}

@ -0,0 +1,22 @@
import * as Vue from 'vue'
declare const isVue2: boolean
declare const isVue3: boolean
declare const Vue2: any
declare const install: (vue?: any) => void
/**
* @deprecated To avoid bringing in all the tree-shakable modules, this API has been deprecated. Use `Vue2` or named exports instead.
* Refer to https://github.com/vueuse/vue-demi/issues/41
*/
declare const V: typeof Vue
export function set<T>(target: any, key: any, val: T): T
export function del(target: any, key: any): void
export * from 'vue'
export {
V as Vue,
Vue2,
isVue2,
isVue3,
install,
}

@ -0,0 +1,34 @@
import * as Vue from 'vue'
var isVue2 = false
var isVue3 = true
var Vue2 = undefined
function install() {}
export function set(target, key, val) {
if (Array.isArray(target)) {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
return val
}
target[key] = val
return val
}
export function del(target, key) {
if (Array.isArray(target)) {
target.splice(key, 1)
return
}
delete target[key]
}
export * from 'vue'
export {
Vue,
Vue2,
isVue2,
isVue3,
install,
}

@ -0,0 +1,47 @@
{
"name": "vue-demi",
"version": "0.14.6",
"engines": {
"node": ">=12"
},
"repository": "https://github.com/antfu/vue-demi.git",
"funding": "https://github.com/sponsors/antfu",
"license": "MIT",
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
"main": "lib/index.cjs",
"jsdelivr": "lib/index.iife.js",
"unpkg": "lib/index.iife.js",
"module": "lib/index.mjs",
"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"require": "./lib/index.cjs",
"import": "./lib/index.mjs",
"browser": "./lib/index.mjs"
},
"./*": "./*"
},
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"files": [
"lib",
"bin",
"scripts"
],
"scripts": {
"postinstall": "node ./scripts/postinstall.js",
"release": "npx bumpp --tag --commit --push && npm publish"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save