Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jinli gu
Litemall
Commits
104523c6
Commit
104523c6
authored
Apr 19, 2019
by
Junling Bu
Browse files
doc
parents
70c31ee4
4ee32ff6
Changes
153
Show whitespace changes
Inline
Side-by-side
litemall-vue/src/views/user/user-information-set/index.vue
0 → 100755
View file @
104523c6
<
template
>
<div
class=
"user_information"
>
<van-cell-group>
<van-cell
title=
"头像"
class=
"cell_middle"
>
<van-uploader
:afterRead=
"avatarAfterRead"
>
<div
class=
"user_avatar_upload"
>
<img
:src=
"avatar + '?x-oss-process=image/resize,m_fill,h_50,w_50'"
alt=
"你的头像"
v-if=
"avatar"
>
<van-icon
name=
"camera_full"
v-else
></van-icon>
</div>
</van-uploader>
</van-cell>
<!--
<van-cell
title=
"背景图"
to=
"/user/information/setbg"
isLink
></van-cell>
-->
<!--
<van-cell
title=
"昵称"
to=
"/user/information/setNickname"
:value=
"nickName"
isLink
/>
-->
<!--
<van-cell
title=
"性别"
:value=
"genderText"
@
click=
"showSex = true"
isLink
/>
-->
<!--
<van-cell
title=
"密码设置"
to=
"/user/information/setPassword"
isLink
/>
-->
<!--
<van-cell
title=
"手机号"
to=
"/user/information/setMobile"
:value=
"mobile"
isLink
></van-cell>
-->
<van-cell
title=
"背景图"
isLink
></van-cell>
<van-cell
title=
"昵称"
:value=
"nickName"
isLink
/>
<van-cell
title=
"性别"
isLink
/>
<!--
<van-cell
title=
"密码设置"
to=
"/user/information/setPassword"
isLink
/>
-->
<van-cell
title=
"手机号"
:value=
"mobile"
isLink
></van-cell>
</van-cell-group>
<van-button
class=
"bottom_btn"
@
click=
"loginOut"
type=
"primary"
bottomAction
>
退出登录
</van-button>
<van-popup
v-model=
"showSex"
position=
"bottom"
>
<van-picker
showToolbar
:columns=
"sexColumns"
title=
"选择性别"
@
cancel=
"showSex = false"
@
confirm=
"onSexConfirm"
/>
</van-popup>
</div>
</
template
>
<
script
>
import
{
Uploader
,
Picker
,
Popup
,
Button
}
from
'
vant
'
;
import
{
USER_PROFILE
}
from
'
@/api/user
'
;
import
{
removeLocalStorage
}
from
'
core/utils/local-storage
'
;
import
{
getLocalStorage
}
from
'
core/utils/local-storage
'
;
export
default
{
data
()
{
return
{
sexColumns
:
[
{
values
:
[
'
保密
'
,
'
男
'
,
'
女
'
],
defaultIndex
:
0
}
],
showSex
:
false
,
avatar
:
''
,
nickName
:
''
,
gender
:
-
1
,
mobile
:
''
};
},
computed
:
{
genderText
()
{
const
text
=
[
'
保密
'
,
'
男
'
,
'
女
'
];
return
text
[
this
.
gender
]
||
''
;
}
},
created
()
{
this
.
getUserInfo
();
},
methods
:
{
avatarAfterRead
(
file
)
{
console
.
log
(
file
);
},
onSexConfirm
(
value
,
index
)
{
this
.
$reqPut
(
USER_PROFILE
,
{
gender
:
index
[
0
]
}).
then
(
res
=>
{
this
.
gender
=
res
.
data
.
data
.
gender
;
this
.
showSex
=
false
;
});
},
getUserInfo
()
{
const
infoData
=
getLocalStorage
(
'
nickName
'
,
'
background_image
'
,
'
avatar
'
);
// debugger;
this
.
avatar
=
infoData
.
avatar
;
this
.
nickName
=
infoData
.
nickName
;
// this.gender = infoData.gender;
// this.mobile = infoData.mobile;
},
loginOut
()
{
removeLocalStorage
(
'
Authorization
'
,
// 'user_id',
'
avatar
'
,
// 'background_image',
'
nickName
'
);
this
.
$router
.
push
({
name
:
'
home
'
});
}
},
components
:
{
[
Button
.
name
]:
Button
,
[
Uploader
.
name
]:
Uploader
,
[
Picker
.
name
]:
Picker
,
[
Popup
.
name
]:
Popup
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
.user_information
{
.user_avatar_upload
{
position
:
relative
;
width
:
50px
;
height
:
50px
;
border
:
1px
solid
$border-color
;
img
{
max-width
:
100%
;
max-height
:
100%
;
}
i
{
position
:
absolute
;
top
:
50%
;
left
:
50%
;
transform
:
translate
(
-50%
,
-50%
);
font-size
:
20px
;
color
:
$border-color
;
}
}
}
</
style
>
litemall-vue/src/views/user/user-information-set/set-bg/index.vue
0 → 100755
View file @
104523c6
<
template
>
<div>
set mobile
</div>
</
template
>
<
script
>
export
default
{};
</
script
>
litemall-vue/src/views/user/user-information-set/set-mobile/index.vue
0 → 100755
View file @
104523c6
<
template
>
<div>
<van-cell-group>
<van-field
label=
"登录密码"
v-model=
"password"
type=
"password"
placeholder=
"请输入登录密码"
:error=
"!!$vuelidation.error('password')"
/>
<van-field
label=
"新手机号"
v-model=
"new_mobile"
placeholder=
"请输入新手机号"
:error=
"!!$vuelidation.error('new_mobile')"
/>
<van-field
label=
"验证码"
v-model=
"code"
@
click-icon=
"getCode"
placeholder=
"请输入验证码"
>
<span
slot=
"icon"
class=
"verifi_code red"
:class=
"
{verifi_code_counting: counting}"
@click="getCode">
<countdown
v-if=
"counting"
:time=
"60000"
@
countdownend=
"countdownend"
>
<template
slot-scope=
"props"
>
{{
+
props
.
seconds
||
60
}}
秒后获取
</
template
>
</countdown>
<span
v-else
>
获取验证码
</span>
</span>
</van-field>
</van-cell-group>
<div
class=
"bottom_btn"
>
<van-button
size=
"large"
type=
"danger"
@
click=
"saveMobile"
>
保存
</van-button>
</div>
</div>
</template>
<
script
>
import
{
USER_SENDCODE
}
from
'
@/api/user
'
;
import
{
Field
}
from
'
vant
'
;
export
default
{
data
:
()
=>
({
password
:
''
,
new_mobile
:
''
,
code
:
''
,
counting
:
false
}),
vuelidation
:
{
data
:
{
password
:
{
required
:
true
},
new_mobile
:
{
required
:
true
,
mobile
:
true
}
}
},
methods
:
{
getCode
()
{
if
(
!
this
.
counting
&&
this
.
vuelidat
())
{
this
.
$reqPost
(
USER_SENDCODE
,
{
mobile
:
this
.
new_mobile
,
operation
:
'
changeMobile
'
}).
then
(()
=>
{
this
.
$toast
.
success
(
'
发送成功
'
);
this
.
counting
=
true
;
});
}
},
countdownend
()
{
this
.
counting
=
false
;
},
vuelidat
()
{
this
.
$vuelidation
.
valid
();
if
(
this
.
$vuelidation
.
error
(
'
new_mobile
'
))
{
const
msg
=
this
.
$vuelidation
.
error
(
'
new_mobile
'
);
this
.
$toast
(
msg
==
'
Required
'
?
'
请输入手机号
'
:
msg
);
return
false
;
}
return
true
;
},
saveMobile
()
{
console
.
log
(
'
保存手机号
'
);
}
},
components
:
{
[
Field
.
name
]:
Field
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
@import
'../../../../assets/scss/var'
;
@import
'../../../../assets/scss/mixin'
;
.bottom_btn
{
padding
:
30px
15px
0
15px
;
}
.verifi_code
{
@include
one-border
;
padding-left
:
10px
;
&
::after
{
border-bottom
:
0
;
border-left
:
1px
solid
$border-color
;
}
&
_counting
{
color
:
$font-color-gray
;
}
}
</
style
>
litemall-vue/src/views/user/user-information-set/set-nickname/index.vue
0 → 100755
View file @
104523c6
<
template
>
<div
class=
"set_nickname"
>
<van-cell-group>
<van-field
v-model=
"nickName"
label=
"昵称"
:error=
"!!$vuelidation.error('nickName')"
/>
</van-cell-group>
<div
class=
"bottom_btn"
>
<van-button
size=
"large"
type=
"danger"
@
click=
"saveNick"
>
保存
</van-button>
</div>
</div>
</
template
>
<
script
>
import
{
USER_PROFILE
}
from
'
@/api/user
'
;
import
{
Field
}
from
'
vant
'
;
export
default
{
data
()
{
return
{
nickName
:
''
};
},
created
()
{
this
.
getNick
();
},
methods
:
{
getNick
()
{
this
.
nickName
=
localStorage
.
getItem
(
'
nickName
'
)
||
''
;
},
saveNick
()
{
if
(
true
)
{
this
.
$reqPut
(
USER_PROFILE
,
{
nickName
:
this
.
nickName
})
.
then
(
res
=>
{
localStorage
.
setItem
(
'
nickName
'
,
res
.
data
.
data
.
nickName
);
return
this
.
$dialog
.
alert
({
message
:
'
保存成功
'
});
})
.
then
(()
=>
{
this
.
$router
.
go
(
-
1
);
});
}
}
},
components
:
{
[
Field
.
name
]:
Field
}
};
</
script
>
<
style
scoped
>
.bottom_btn
{
padding
:
30px
15px
0
15px
;
}
</
style
>
litemall-vue/src/views/user/user-information-set/set-password/index.vue
0 → 100755
View file @
104523c6
<
template
>
<div>
<van-cell-group>
<van-field
label=
"原密码"
v-model=
"password"
type=
"password"
placeholder=
"请输入原密码"
:error=
"!!$vuelidation.error('password')"
/>
<van-field
label=
"新密码"
v-model=
"new_password"
type=
"password"
placeholder=
"请输入新密码"
:error=
"!!$vuelidation.error('new_password')"
/>
<van-field
label=
"确认密码"
v-model=
"repeat_password"
type=
"password"
placeholder=
"请再次输入密码"
:error=
"!!$vuelidation.error('repeat_password')"
/>
</van-cell-group>
<div
class=
"bottom_btn"
>
<van-button
size=
"large"
type=
"danger"
@
click=
"modifypassword"
>
保存
</van-button>
</div>
</div>
</
template
>
<
script
>
import
{
USER_MODIFY_PASSWORD
,
USER_LOGOUT
}
from
'
@/api/user
'
;
import
{
removeLocalStorage
}
from
'
core/utils/local-storage
'
;
import
{
Field
}
from
'
vant
'
;
export
default
{
data
:
()
=>
({
password
:
''
,
new_password
:
''
,
repeat_password
:
''
}),
methods
:
{
modifypassword
()
{
if
(
this
.
passwordValid
())
{
this
.
$reqPut
(
USER_MODIFY_PASSWORD
,
{
old_password
:
this
.
password
,
new_password
:
this
.
new_password
})
.
then
(()
=>
this
.
$dialog
.
alert
({
message
:
'
保存成功, 请重新登录.
'
}))
.
then
(()
=>
this
.
$reqGet
(
USER_LOGOUT
))
.
then
(()
=>
{
removeLocalStorage
(
'
Authorization
'
,
'
user_id
'
,
'
avatar
'
,
'
background_image
'
,
'
nickName
'
);
this
.
$router
.
replace
({
name
:
'
login
'
});
});
}
},
passwordValid
()
{
if
(
this
.
new_password
!=
this
.
repeat_password
)
{
this
.
$toast
(
'
密码不一致, 请再次确认密码
'
);
return
false
;
}
return
true
;
}
},
components
:
{
[
Field
.
name
]:
Field
}
};
</
script
>
<
style
scoped
>
.bottom_btn
{
padding
:
30px
15px
0
15px
;
}
</
style
>
litemall-vue/src/vue/components/Tabbar/index.vue
0 → 100755
View file @
104523c6
<
template
>
<van-tabbar
v-model=
"active"
style=
"z-index: 1999"
>
<van-tabbar-item
v-for=
"(tab, index) in tabbar"
:icon=
"tab.icon"
:to=
"tab.path"
:dot=
"tab.dot"
:info=
"tab.info"
:key=
"index"
>
{{
tab
.
name
}}
</van-tabbar-item>
</van-tabbar>
</
template
>
<
script
>
import
{
Tabbar
,
TabbarItem
}
from
'
vant
'
;
export
default
{
data
()
{
return
{
active
:
0
,
tabbar
:
[
{
name
:
'
精选
'
,
path
:
'
/
'
,
pathName
:
'
home
'
,
icon
:
'
compass-full
'
,
dot
:
false
,
info
:
''
},
{
name
:
'
分类
'
,
path
:
'
/items
'
,
pathName
:
'
class
'
,
icon
:
'
class-full
'
,
dot
:
false
,
info
:
''
},
{
name
:
'
购物车
'
,
path
:
'
/order
'
,
pathName
:
'
cart
'
,
icon
:
'
cart-full
'
,
dot
:
false
,
info
:
''
},
{
name
:
'
我的
'
,
path
:
'
/user
'
,
pathName
:
'
user
'
,
icon
:
'
wode
'
,
dot
:
false
,
info
:
''
}
]
};
},
watch
:
{
$route
:
'
changeActive
'
},
created
()
{
const
toName
=
this
.
$route
.
name
;
this
.
setActive
(
toName
);
},
methods
:
{
changeActive
({
name
})
{
this
.
setActive
(
name
);
},
setActive
(
name
)
{
this
.
tabbar
.
forEach
((
tab
,
i
)
=>
{
if
(
tab
.
pathName
==
name
)
{
this
.
active
=
i
;
return
false
;
}
});
}
},
components
:
{
[
Tabbar
.
name
]:
Tabbar
,
[
TabbarItem
.
name
]:
TabbarItem
}
};
</
script
>
litemall-vue/src/vue/components/_directive/scrollMore.js
0 → 100755
View file @
104523c6
import
{
debounce
}
from
'
lodash
'
;
import
scroll
from
'
core/utils/scroll
'
;
const
CONTEXT
=
'
$scrollArrow
'
;
const
OFFSET
=
30
;
// 绑定事件
function
startBind
(
el
)
{
const
context
=
el
[
CONTEXT
];
context
.
vm
.
$nextTick
(()
=>
{
if
(
scroll
.
isAttached
(
el
))
{
doBindEvent
.
call
(
el
[
CONTEXT
]);
}
});
}
// 绑定事件到元素上
// 读取基本的控制变量
function
doBindEvent
()
{
if
(
this
.
el
[
CONTEXT
].
binded
)
{
return
;
}
this
.
el
[
CONTEXT
].
binded
=
true
;
this
.
scrollEventListener
=
debounce
(
handleScrollEvent
.
bind
(
this
),
100
);
// this.scrollEventTarget = this.el;
// var disabledExpr = this.el.getAttribute('waterfall-disabled');
// var disabled = false;
// if (disabledExpr) {
// this.vm.$watch(disabledExpr, (value) => {
// this.disabled = value;
// this.scrollEventListener();
// });
// disabled = Boolean(this.vm[disabledExpr]);
// }
// this.disabled = disabled;
const
offset
=
this
.
el
.
getAttribute
(
'
scroll-offset
'
);
this
.
offset
=
Number
(
offset
)
||
OFFSET
;
this
.
el
.
addEventListener
(
'
scroll
'
,
this
.
scrollEventListener
);
// this.scrollEventListener();
}
// 处理滚动函数
function
handleScrollEvent
()
{
const
element
=
this
.
el
;
// 已被禁止的滚动处理
// if (this.disabled) return;
const
targetScrollLeft
=
scroll
.
getScrollLeft
(
element
);
const
targetVisibleWidth
=
scroll
.
getVisibleWidth
(
element
);
// 滚动元素可视区域下边沿到滚动元素元素最顶上 距离
const
targetRight
=
targetScrollLeft
+
targetVisibleWidth
;
// 如果无元素高度,考虑为元素隐藏,直接返回
if
(
!
targetVisibleWidth
)
return
;
// 判断是否到了最右边
const
isRightOver
=
element
.
scrollWidth
-
targetRight
<
this
.
offset
;
// 判断是否到了最左边
const
isLeftOver
=
targetScrollLeft
<
this
.
offset
;
this
.
cb
&&
this
.
cb
({
target
:
element
,
isRightOver
,
isLeftOver
});
// // 判断是否到了顶
// let needLoadMoreToUpper = targetScrollTop < this.offset;
// if (needLoadMoreToUpper) {
// this.cb.upper && this.cb.upper({
// target: scrollEventTarget,
// top: targetScrollTop
// });
// }
}
// 确认何时绑事件监听函数
function
doCheckStartBind
(
el
)
{
const
context
=
el
[
CONTEXT
];
if
(
context
.
vm
.
_isMounted
)
{
startBind
(
el
);
}
else
{
context
.
vm
.
$on
(
'
hook:mounted
'
,
()
=>
{
startBind
(
el
);
});
}
}
export
default
{
bind
(
el
,
binding
,
vnode
)
{
if
(
!
el
[
CONTEXT
])
{
el
[
CONTEXT
]
=
{
el
,
vm
:
vnode
.
context
,
cb
:
{}
};
}
el
[
CONTEXT
].
cb
=
binding
.
value
;
doCheckStartBind
(
el
);
},
update
(
el
)
{
const
context
=
el
[
CONTEXT
];
context
.
scrollEventListener
&&
context
.
scrollEventListener
();
}
};
litemall-vue/src/vue/components/field-group/index.vue
0 → 100755
View file @
104523c6
<
template
>
<div
class=
"field_group"
>
<slot></slot>
</div>
</
template
>
<
script
>
export
default
{
name
:
'
md-field-group
'
};
</
script
>
<
style
lang=
"scss"
scoped
>
.field_group
{
padding-left
:
15px
;
padding-right
:
15px
;
>
div
{
margin-bottom
:
15px
;
&
:last-child
{
margin-bottom
:
0
;
}
}
}
</
style
>
litemall-vue/src/vue/components/field/index.vue
0 → 100755
View file @
104523c6
<
template
>
<div
class=
"md_field"
:class=
"
{md_field_hasIcon: !!icon, md_field_isError: isError}">
<van-icon
v-if=
"icon"
:name=
"icon"
class=
"md_feld_icon"
/>
<div
class=
"md_field_control"
>
<input
:type=
"type"
v-on=
"listeners"
v-bind=
"$attrs"
:value=
"value"
>
</div>
<div>
<slot
name=
"rightIcon"
>
<van-icon
:name=
"rightIcon"
@
click=
"rightClick"
v-show=
"value"
/>
</slot>
</div>
</div>
</
template
>
<
script
>
export
default
{
name
:
'
md-field
'
,
props
:
{
value
:
{},
type
:
{
type
:
String
,
default
:
'
text
'
},
rightIcon
:
String
,
icon
:
String
,
isError
:
Boolean
},
computed
:
{
listeners
()
{
return
{
...
this
.
$listeners
,
input
:
this
.
onInput
};
}
},
methods
:
{
onInput
(
event
)
{
this
.
$emit
(
'
input
'
,
event
.
target
.
value
);
},
rightClick
(
event
)
{
this
.
$emit
(
'
right-click
'
,
event
);
}
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
.md_field
{
position
:
relative
;
border
:
1px
solid
$border-color
;
border-radius
:
5px
;
padding-top
:
10px
;
padding-bottom
:
10px
;
padding-left
:
10px
;
display
:
table
;
width
:
100%
;
box-sizing
:
border-box
;
background-color
:
#fff
;
>
div
{
display
:
table-cell
;
}
>
.md_field_control
{
padding-right
:
10px
;
box-sizing
:
border-box
;
input
{
border
:
0
;
line-height
:
14px
;
font-size
:
14px
;
width
:
100%
;
}
}
.md_feld_icon
{
position
:
absolute
;
top
:
50%
;
left
:
10px
;
transform
:
translate
(
0
,
-50%
);
}
}
.md_field_hasIcon
{
padding-left
:
40px
;
}
.md_field_isError
{
color
:
$red
;
background-color
:
#fcf5f5
;
border
:
1px
solid
$red
;
input
{
color
:
$red
;
background-color
:
#fcf5f5
;
}
input
:
-
webkit-autofill
{
-webkit-box-shadow
:
0
0
0
1000px
#fcf5f5
inset
!
important
;
}
}
</
style
>
litemall-vue/src/vue/components/infinity-scroll/index.vue
0 → 100644
View file @
104523c6
<
template
>
<van-list
v-model=
"loading"
:finished=
"finished"
:offset=
"100"
@
load=
"loadMore"
v-bind=
"$attrs"
v-on=
"$listeners"
:immediate-check=
"false"
>
<is-empty
v-if=
"isEmpty"
>
{{
emptyText
}}
</is-empty>
<slot
v-else
></slot>
<div
v-if=
"finished"
class=
"text-center nomore"
>
{{
onMoreText
}}
</div>
</van-list>
</
template
>
<
script
>
import
{
List
}
from
'
vant
'
;
import
{
get
}
from
'
lodash
'
;
import
IsEmpty
from
'
@/vue/components/is-empty
'
;
import
loadMore
from
'
@/vue/mixin/load-more
'
;
const
DEFAULT_CONFIG
=
{
params
:
{},
headers
:
{}
};
export
default
{
name
:
'
infinity-scroll
'
,
mixins
:
[
loadMore
],
props
:
{
apiUrl
:
{
type
:
String
,
required
:
true
},
resKey
:
{
type
:
String
,
default
:
'
data.goodsList
'
},
pageKey
:
{
type
:
String
,
default
:
'
data.page
'
},
emptyText
:
{
type
:
String
,
default
:
'
抱歉,找不到结果~
'
},
onMoreText
:
{
type
:
String
,
default
:
'
没有更多了~
'
},
perPage
:
Number
,
beforeRequest
:
Function
},
created
()
{
this
.
resetInit
();
},
methods
:
{
beforeInitData
()
{
return
this
.
beforeRequest
?
this
.
beforeRequest
()
:
DEFAULT_CONFIG
;
},
async
initData
()
{
const
{
params
=
{},
headers
=
{}
}
=
this
.
beforeInitData
();
const
prePage
=
this
.
perPage
||
this
.
pages
.
perPage
;
console
.
log
(
params
);
console
.
log
(
headers
);
const
res
=
await
this
.
$reqGet
(
'
/wx/goods/list
'
,
{
// 'per-page': prePage,
page
:
this
.
pages
.
currPage
,
size
:
100
,
categoryId
:
params
.
cid
// ...params
},
headers
);
await
this
.
sleep
(
1000
);
const
items
=
get
(
res
.
data
,
this
.
resKey
,
[]);
const
page
=
get
(
res
.
data
,
this
.
pageKey
,
null
);
this
.
$emit
(
'
onLoad
'
,
items
);
return
page
;
},
sleep
(
time
)
{
return
new
Promise
(
resolve
=>
{
setTimeout
(
resolve
,
time
);
});
}
},
components
:
{
IsEmpty
,
[
List
.
name
]:
List
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
.nomore
{
padding
:
10px
0
;
color
:
$font-color-gray
;
}
</
style
>
litemall-vue/src/vue/components/is-empty/index.vue
0 → 100644
View file @
104523c6
<
template
>
<div
class=
"is_empty"
>
<div>
<img
src=
"../../../assets/images/is_empty.png"
alt=
"无商品"
width=
"20%"
>
</div>
<div>
<slot></slot>
</div>
</div>
</
template
>
<
script
>
export
default
{
name
:
'
is-empty
'
};
</
script
>
<
style
lang=
"scss"
scoped
>
.is_empty
{
text-align
:
center
;
color
:
$font-color-gray
;
padding-top
:
100px
;
>
div
{
margin-bottom
:
20px
;
}
}
</
style
>
litemall-vue/src/vue/components/item-card-hori/index.vue
0 → 100644
View file @
104523c6
<
template
>
<div
class=
"item_card_H_wrap one_border"
@
click=
"OnClick"
>
<div
class=
"clearfix"
>
<div
class=
"item_card_image float-l"
>
<div
v-if=
"$slots.leftTopIcon"
class=
"leftTopIcon"
>
<slot
name=
"leftTopIcon"
></slot>
</div>
<div
v-if=
"$slots.mask"
class=
"item_img_mask"
>
<slot
name=
"mask"
></slot>
</div>
<img
v-lazy=
"goods.picUrl"
>
<div
class=
"item_image_desc"
>
{{
goodsStatusToMe
}}
</div>
</div>
<!--
{{
goods
}}
-->
<div
class=
"item_card_info"
>
<div
class=
"item_card_name"
>
<van-tag
plain
type=
"danger"
v-if=
"goods.is_haitao"
>
海淘
</van-tag>
<span
v-if=
"$slots.icon"
class=
"item_card_icon"
>
<slot
name=
"icon"
></slot>
</span>
{{
goods
.
name
}}
</div>
<div
class=
"item_card_info_desc"
>
{{
goods
.
brief
}}
</div>
<div
class=
"item_card_footer"
>
<div
class=
"footer_price"
>
<span>
{{
goods
.
retailPrice
*
100
|
yuan
}}
</span>
<span
class=
"marketPrice"
v-if=
"goods.counterPrice"
>
{{
goods
.
counterPrice
*
100
|
yuan
}}
</span>
</div>
<div
class=
"footer_desc"
v-if=
"$slots.footer"
>
<slot
name=
"footer"
></slot>
</div>
</div>
</div>
</div>
</div>
</
template
>
<
script
>
import
item_mix
from
'
@/vue/mixin/item-card
'
;
export
default
{
name
:
'
item-card-hori
'
,
mixins
:
[
item_mix
]
};
</
script
>
<
style
lang=
"scss"
scoped
>
.item_card_H_wrap
{
padding
:
15px
10px
;
}
.item_card_image
{
position
:
relative
;
padding-top
:
5px
;
width
:
90px
;
height
:
90px
;
text-align
:
center
;
img
{
display
:
inline-block
;
max-height
:
100%
;
max-width
:
100%
;
}
.leftTopIcon
{
position
:
absolute
;
left
:
0
;
top
:
0
;
max-width
:
50%
;
text-align
:
left
;
}
.item_image_desc
{
position
:
absolute
;
bottom
:
0
;
background-color
:
rgba
(
244
,
133
,
145
,
0
.8
);
width
:
100%
;
color
:
#fff
;
font-size
:
12px
;
}
.item_img_mask
{
position
:
absolute
;
top
:
50%
;
left
:
50%
;
z-index
:
2
;
transform
:
translate
(
-50%
,
-50%
);
width
:
70px
;
height
:
70px
;
overflow
:
hidden
;
}
}
.item_card_info
{
position
:
relative
;
margin-left
:
110px
;
height
:
100px
;
.item_card_name
{
font-size
:
12px
;
margin-bottom
:
10px
;
overflow
:
hidden
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
}
.item_card_name
.item_card_icon
{
width
:
25px
;
height
:
14px
;
vertical-align
:
middle
;
display
:
inline-block
;
background-repeat
:
no-repeat
;
}
.isHaiTao
{
background-image
:
url(http://mamaqunaer.oss-cn-shanghai.aliyuncs.com/20171121/xMACDPN2Bz.png)
;
}
.item_card_info_desc
{
font-size
:
12px
;
color
:
$font-color-gray
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
display
:
-
webkit-box
;
-webkit-box-orient
:
vertical
;
-webkit-line-clamp
:
3
;
}
.item_card_icon
img
{
max-height
:
100%
;
max-width
:
100%
;
}
.item_card_footer
{
position
:
absolute
;
bottom
:
0
;
left
:
0
;
right
:
0
;
display
:
flex
;
.footer_price
{
color
:
$red
;
margin-right
:
5px
;
}
.footer_price
.marketPrice
{
color
:
$font-color-gray
;
font-size
:
12px
;
text-decoration
:
line-through
;
margin-left
:
5px
;
}
.footer_desc
{
flex
:
1
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
}
}
</
style
>
litemall-vue/src/vue/components/item-card-vert/index.vue
0 → 100644
View file @
104523c6
<
template
>
<div
class=
"item_card_V_wrap"
@
click=
"OnClick"
>
<div
class=
"item_card_image"
>
<div
v-if=
"$slots.leftTopIcon"
class=
"leftTopIcon"
>
<slot
name=
"leftTopIcon"
></slot>
</div>
<div
v-if=
"$slots.mask"
class=
"item_img_mask"
>
<slot
name=
"mask"
></slot>
</div>
<img
v-lazy=
"goods.pic_url"
>
<div
class=
"item_image_desc"
>
{{
goodsStatusToMe
}}
</div>
</div>
<div
class=
"item_card_name"
>
<van-tag
plain
type=
"danger"
v-if=
"goods.is_haitao"
>
海淘
</van-tag>
<span
v-if=
"$slots.icon"
class=
"item_card_icon"
>
<slot
name=
"icon"
></slot>
</span>
{{
goods
.
name
}}
</div>
<div
class=
"item_card_price"
>
{{
goods
.
retailPrice
|
yuan
}}
</div>
</div>
</
template
>
<
script
>
import
item_mix
from
'
@/vue/mixin/item-card
'
;
export
default
{
name
:
'
item-card-vert
'
,
mixins
:
[
item_mix
]
};
</
script
>
<
style
lang=
"scss"
scoped
>
.item_card_V_wrap
{
display
:
inline-block
;
flex
:
1
;
width
:
90px
;
margin
:
0
10px
;
}
.item_card_image
{
position
:
relative
;
width
:
100%
;
height
:
90px
;
margin-bottom
:
5px
;
text-align
:
center
;
.leftTopIcon
{
position
:
absolute
;
left
:
0
;
top
:
0
;
z-index
:
3
;
max-width
:
50%
;
text-align
:
left
;
}
img
{
display
:
inline-block
;
max-height
:
100%
;
max-width
:
100%
;
}
.item_image_desc
{
position
:
absolute
;
bottom
:
0
;
background-color
:
rgba
(
244
,
133
,
145
,
0
.8
);
width
:
100%
;
color
:
#fff
;
font-size
:
12px
;
}
.item_img_mask
{
position
:
absolute
;
top
:
50%
;
left
:
50%
;
z-index
:
2
;
transform
:
translate
(
-50%
,
-50%
);
width
:
70px
;
height
:
70px
;
overflow
:
hidden
;
}
}
.item_card_name
{
line-height
:
16px
;
font-size
:
12px
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
display
:
-
webkit-box
;
-webkit-box-orient
:
vertical
;
-webkit-line-clamp
:
2
;
text-align
:
center
;
}
.item_card_icon
{
width
:
30px
;
height
:
14px
;
vertical-align
:
middle
;
display
:
inline-block
;
background-repeat
:
no-repeat
;
background-size
:
100%
100%
;
}
.item_card_icon
img
{
max-height
:
100%
;
max-width
:
100%
;
}
.isHaiTao
{
background-image
:
url(http://www-dev.mamaqunaer.com/images/common/icon_menu_bdt.png)
;
}
.item_card_price
{
text-align
:
center
;
color
:
$red
;
}
</
style
>
litemall-vue/src/vue/components/item-group/index.vue
0 → 100644
View file @
104523c6
<
template
>
<div
class=
"items_group"
>
<van-cell-group
v-if=
"setting && !!setting.title"
>
<van-cell>
<slot
v-if=
"$slots.title_right"
name=
"title_right"
></slot>
<template
slot=
"icon"
>
<van-icon
class=
"van-cell__left-icon"
v-if=
"setting.icon"
:style=
"
{color: setting.title_color}" :name="setting.icon"/>
</
template
>
<
template
slot=
"title"
>
<span
class=
"group_title"
:style=
"
{color: setting.title_color}">
{{
setting
.
title
}}
</span>
<slot
name=
"title-desc"
>
<span
class=
"group_title_desc"
>
{{
setting
.
title_desc
}}
</span>
</slot>
</
template
>
</van-cell>
</van-cell-group>
<div
class=
"group_banner"
v-if=
"setting && setting.banner"
>
<img
v-lazy=
"setting.banner"
alt=
"海报"
width=
"100%"
>
</div>
<div
class=
"item_scroll_box"
v-if=
"setting.style"
>
<div
class=
"item_scroll"
v-scrollArrow=
"scrollMore"
>
<div
class=
"item_scroll_wrap"
:style=
"{width: scrollWidth}"
>
<slot></slot>
</div>
</div>
<transition
name=
"fade"
>
<van-icon
name=
"arrow"
v-show=
"leftOver && isShowArrow"
class=
"items_arrow right_arrow"
/>
</transition>
<transition
name=
"fade"
>
<van-icon
name=
"arrow-left"
v-show=
"rightOver && isShowArrow"
class=
"items_arrow left_arrow"
/>
</transition>
</div>
<div
v-else
>
<slot></slot>
</div>
</div>
</template>
<
script
>
import
ItemCardVert
from
'
../item-card-vert/
'
;
import
ItemCardHori
from
'
../item-card-hori/
'
;
import
{
Cell
,
CellGroup
,
Icon
}
from
'
vant
'
;
import
scrollArrow
from
'
../_directive/scrollMore
'
;
export
default
{
name
:
'
item-group
'
,
props
:
{
setting
:
{
type
:
Object
,
default
:
()
=>
({})
},
col
:
{
type
:
Number
,
default
:
3
}
},
data
()
{
const
clientW
=
document
.
body
.
clientWidth
||
document
.
documentElement
.
clientWidth
,
col
=
this
.
col
,
itemW
=
Math
.
floor
(
clientW
/
col
),
itemsLen
=
this
.
setting
.
item_len
;
return
{
itemW
,
scrollWidth
:
`
${
itemW
*
itemsLen
}
px`
,
rightOver
:
false
,
leftOver
:
true
,
isShowArrow
:
itemsLen
>
col
};
},
methods
:
{
scrollMore
(
obj
)
{
this
.
rightOver
=
!
obj
.
isLeftOver
;
this
.
leftOver
=
!
obj
.
isRightOver
;
}
},
directives
:
{
scrollArrow
},
components
:
{
[
Cell
.
name
]:
Cell
,
[
CellGroup
.
name
]:
CellGroup
,
[
Icon
.
name
]:
Icon
,
[
ItemCardVert
.
name
]:
ItemCardVert
,
[
ItemCardHori
.
name
]:
ItemCardHori
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
.items_group
{
background-color
:
#fff
;
}
.group_title
{
font-weight
:
700
;
}
.group_title_desc
{
font-size
:
12px
;
color
:
$font-color-gray
;
}
.group_banner
img
{
max-height
:
200px
;
display
:
block
;
}
.item_scroll_box
{
position
:
relative
;
width
:
100%
;
padding
:
10px
0
;
}
.item_scroll
{
width
:
100%
;
overflow-y
:
hidden
;
overflow-x
:
scroll
;
}
.item_scroll_wrap
{
display
:
flex
;
}
.items_arrow
{
position
:
absolute
;
top
:
50%
;
transform
:
translate
(
0
,
-50%
);
font-size
:
18px
;
}
.left_arrow
{
left
:
0
;
}
.right_arrow
{
right
:
0
;
}
.fade-enter
,
.fade-leave-to
{
opacity
:
0
;
}
.fade-enter-active
,
.fade-leave-active
{
transition
:
all
0
.3s
;
}
.fade-enter-to
,
.fade-leave
{
opacity
:
1
;
}
</
style
>
litemall-vue/src/vue/components/md-kefu/index.vue
0 → 100755
View file @
104523c6
<
template
>
<div
class=
"contact_popup"
>
<div
class=
"contact_box contact_top"
>
<div>
微信长按识别店主二维码
</div>
<div><img
src=
"../../../assets/images/qc_code.png"
alt=
"店主二维码"
></div>
</div>
<div
class=
"contact_box"
>
<div><van-icon
name=
"phone"
/>
{{
mobile
}}
</div>
<div
class=
"contact_btn"
><a
:href=
"'tel:' + mobile"
>
联系店家
</a></div>
</div>
</div>
</
template
>
<
script
>
export
default
{
name
:
'
md-kefu
'
,
props
:
{
qcCode
:
String
,
mobile
:
String
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
.contact_popup
{
white-space
:
nowrap
;
background-color
:
$bg-color
;
text-align
:
center
;
border-radius
:
5px
;
.contact_box
{
padding
:
20px
30px
;
>
div
:first-child
{
margin-bottom
:
20px
;
}
}
.contact_top
{
@include
one-border
;
&
::after
{
border-bottom-color
:
#999
;
}
}
.contact_btn
{
border
:
1px
solid
$red
;
width
:
80%
;
margin
:
0
auto
;
color
:
#fff
;
background-color
:
$red
;
padding
:
5px
0
;
border-radius
:
3px
;
a
{
color
:
#fff
;
display
:
block
;
}
}
img
{
max-width
:
100%
;
max-height
:
100%
;
}
}
</
style
>
litemall-vue/src/vue/components/spinner/index.js
0 → 100644
View file @
104523c6
import
spinner
from
'
./spinner
'
;
export
default
spinner
;
litemall-vue/src/vue/components/spinner/spinner.vue
0 → 100644
View file @
104523c6
<
template
>
<div>
<div
class=
"lds-ball"
>
<div></div>
</div>
</div>
</
template
>
<
script
>
export
default
{};
</
script
>
litemall-vue/src/vue/event-bus/index.js
0 → 100644
View file @
104523c6
export
default
{
install
(
Vue
)
{
Vue
.
prototype
.
$bus
=
new
Vue
({
data
()
{
return
{
item_list
:
[]
};
},
created
()
{
this
.
$on
(
'
item_list
'
,
val
=>
{
const
isArr
=
Array
.
isArray
(
val
);
if
(
isArr
)
{
this
.
item_list
=
val
;
}
else
{
throw
Error
(
'
item_list必须为数组
'
);
}
});
}
});
}
};
litemall-vue/src/vue/filter/index.js
0 → 100755
View file @
104523c6
import
dayjs
from
'
dayjs
'
;
import
{
isNumber
}
from
'
lodash
'
;
export
const
dateFormat
=
(
value
,
format
=
'
YYYY-MM-DD
'
)
=>
value
?
dayjs
(
value
*
1000
).
format
(
format
)
:
''
;
export
const
yuan
=
value
=>
isNumber
(
value
)
?
`¥
${(
value
/
100
).
toFixed
(
2
)}
`
:
value
;
export
default
{
install
(
Vue
)
{
Vue
.
filter
(
'
yuan
'
,
yuan
);
Vue
.
filter
(
'
dateFormat
'
,
dateFormat
);
}
};
litemall-vue/src/vue/mixin/get-shop-info.js
0 → 100644
View file @
104523c6
import
{
SHOPINFO
}
from
'
@/api/shop
'
;
export
default
{
methods
:
{
getShopInfo
(...
keys
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
const
id
=
window
.
sessionStorage
.
getItem
(
'
id
'
);
if
(
id
===
null
)
{
const
shop_id
=
this
.
$util
.
getLocationParam
(
'
shop_id
'
);
this
.
$reqGet
(
`
${
SHOPINFO
}
/
${
shop_id
}
`
)
.
then
(
res
=>
{
const
{
data
}
=
res
.
data
;
this
.
$util
.
setSessionStorage
(
data
);
resolve
(
data
);
})
.
catch
(
reject
);
}
else
{
resolve
(
this
.
$util
.
getSessionStorage
(...
keys
));
}
});
}
}
};
Prev
1
…
3
4
5
6
7
8
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment