Skip to content

Commit 0629e80

Browse files
authored
Vue 3 upgrade (#951)
1 parent e46a438 commit 0629e80

File tree

89 files changed

+882
-640
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+882
-640
lines changed

package.json

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,17 @@
1717
"@tailwindcss/forms": "^0.5.3",
1818
"@tailwindcss/typography": "^0.5.9",
1919
"@types/node": "^24.0.1",
20-
"@vitejs/plugin-vue2": "^2.2.0",
21-
"@vueuse/core": "^11.1.0",
22-
"@vueuse/integrations": "^10.11.0",
20+
"@vitejs/plugin-vue": "^6.0.1",
21+
"@vueuse/core": "^13.6.0",
22+
"@vueuse/integrations": "^13.6.0",
2323
"autoprefixer": "^10.4.15",
24-
"cross-env": "^7.0.3",
24+
"cross-env": "^10.0.0",
2525
"dotenv": "^17.2.0",
2626
"graphql": "^16.8.1",
2727
"graphql-combine-query": "indykoning/graphql-combine-query#feature/add-allowed-duplicates",
2828
"graphql-tag": "^2.12.6",
29-
"instantsearch.js": "^4.75.7",
30-
"laravel-vite-plugin": "^1.0.5",
29+
"instantsearch.js": "^4.79.2",
30+
"laravel-vite-plugin": "^2.0.0",
3131
"lighthouse": "^12.8.2",
3232
"playwright-lighthouse": "^4.0.0",
3333
"postcss": "^8.4.29",
@@ -38,14 +38,12 @@
3838
"tailwind-scrollbar-hide": "^1.1.7",
3939
"tailwindcss": "^3.4",
4040
"universal-cookie": "^7.1.4",
41-
"vite": "^5.0",
42-
"vue": "^2.7",
43-
"vue-clickaway": "^2.2.2",
41+
"vite": "^7.0",
42+
"vue": "^3.5",
43+
"vue3-click-away": "^1.2.4",
4444
"vue-cookies": "^1.8.2",
4545
"vue-instantsearch": "^4.19.13",
46-
"vue-template-compiler": "^2.7.14",
47-
"vue-turbolinks": "^2.2.2",
48-
"vue2-teleport": "^1.1.4"
46+
"vue-turbolinks": "^2.2.2"
4947
},
5048
"dependencies": {},
5149
"workspaces": [

resources/js/callbacks.js

Lines changed: 88 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,112 @@
1+
import { useEventListener } from '@vueuse/core'
12
import { cart, clear as clearCart } from './stores/useCart'
23
import { fillFromGraphqlResponse as updateOrder } from './stores/useOrder'
34
import { runAfterPlaceOrderHandlers, runBeforePaymentMethodHandlers, runBeforePlaceOrderHandlers } from './stores/usePaymentHandlers'
45
import { refresh as refreshUser, token } from './stores/useUser'
56

6-
Vue.prototype.scrollToElement = (selector, offset = 0) => {
7-
let el = window.document.querySelector(selector)
8-
if (el) {
9-
window.scrollTo({
10-
top: el.offsetTop - offset,
11-
behavior: 'smooth',
12-
})
13-
}
14-
}
15-
16-
Vue.prototype.getCheckoutStep = (stepName) => {
17-
return config.checkout_steps?.indexOf(stepName)
18-
}
19-
20-
Vue.prototype.submitPartials = async function (form, sequential = false) {
21-
let promises = []
22-
for (const element of form.querySelectorAll('[partial-submit]')) {
23-
const partialFn = element?.getAttribute('partial-submit')
24-
if (!partialFn || !element?.__vue__) {
25-
continue
7+
document.addEventListener('vue:loaded', function (event) {
8+
const vue = event.detail.vue
9+
vue.config.globalProperties.scrollToElement = (selector, offset = 0) => {
10+
let el = window.document.querySelector(selector)
11+
if (el) {
12+
window.scrollTo({
13+
top: el.offsetTop - offset,
14+
behavior: 'smooth',
15+
})
2616
}
17+
}
2718

28-
const createdPromise = element.__vue__[partialFn]().then((result) => {
29-
if (result === false) {
30-
throw new Error()
19+
vue.config.globalProperties.getCheckoutStep = (stepName) => {
20+
return config.checkout_steps?.indexOf(stepName)
21+
}
22+
23+
vue.config.globalProperties.submitPartials = async function (form, sequential = false) {
24+
let promises = []
25+
for (const element of form.querySelectorAll('[partial-submit]')) {
26+
if (!element.__vnode.props.onPartialSubmit) {
27+
continue
3128
}
32-
})
3329

34-
if (sequential) {
35-
await createdPromise
30+
const createdPromise = element.__vnode.props.onPartialSubmit().then((result) => {
31+
if (result === false) {
32+
throw new Error()
33+
}
34+
})
35+
36+
if (sequential) {
37+
await createdPromise
38+
}
39+
40+
promises.push(createdPromise)
3641
}
3742

38-
promises.push(createdPromise)
43+
return await Promise.all(promises)
3944
}
4045

41-
return await Promise.all(promises)
42-
}
43-
44-
Vue.prototype.checkResponseForExpiredCart = async function (variables, response) {
45-
if (
46-
response?.errors?.some(
47-
(error) =>
48-
error.extensions?.category === 'graphql-no-such-entity' &&
49-
// Untested, but something like this is maybe a better idea as
50-
// we're using a lot of different mutations in the checkout.
51-
error.path.some((path) => path.toLowerCase().includes('cart')),
52-
)
53-
) {
54-
Notify(window.config.translations.errors.cart_expired, 'error')
55-
clearCart()
56-
if (token.value !== undefined) {
57-
// If the cart has expired, check if the session is not expired
58-
refreshUser()
46+
vue.config.globalProperties.checkResponseForExpiredCart = async function (variables, response) {
47+
if (
48+
response?.errors?.some(
49+
(error) =>
50+
error.extensions?.category === 'graphql-no-such-entity' &&
51+
// Untested, but something like this is maybe a better idea as
52+
// we're using a lot of different mutations in the checkout.
53+
error.path.some((path) => path.toLowerCase().includes('cart')),
54+
)
55+
) {
56+
Notify(window.config.translations.errors.cart_expired, 'error')
57+
clearCart()
58+
if (token.value !== undefined) {
59+
// If the cart has expired, check if the session is not expired
60+
refreshUser()
61+
}
62+
63+
return true
5964
}
6065

61-
return true
66+
await vue.config.globalProperties.updateCart(variables, response)
67+
68+
return false
6269
}
6370

64-
await Vue.prototype.updateCart(variables, response)
71+
vue.config.globalProperties.updateCart = async function (data, response) {
72+
if (!response?.data) {
73+
return response?.data
74+
}
75+
cart.value =
76+
Object.values(response.data)
77+
.map((queryResponse) => (queryResponse && 'cart' in queryResponse ? queryResponse.cart : queryResponse))
78+
.findLast((queryResponse) => queryResponse?.is_virtual !== undefined) ?? cart.value
6579

66-
return false
67-
}
80+
window.$emit('cart-updated', {
81+
cart: cart,
82+
})
6883

69-
Vue.prototype.updateCart = async function (data, response) {
70-
if (!response?.data) {
71-
return response?.data
72-
}
73-
cart.value =
74-
Object.values(response.data)
75-
.map((queryResponse) => (queryResponse && 'cart' in queryResponse ? queryResponse.cart : queryResponse))
76-
.findLast((queryResponse) => queryResponse?.is_virtual !== undefined) ?? cart.value
77-
78-
document.dispatchEvent(
79-
new CustomEvent('cart-updated', {
80-
detail: {
81-
cart: cart,
82-
},
83-
}),
84-
)
85-
86-
return response.data
87-
}
88-
89-
Vue.prototype.updateOrder = async function (data, response) {
90-
await updateOrder(data, response)
91-
92-
return response.data
93-
}
94-
95-
Vue.prototype.handleBeforePaymentMethodHandlers = runBeforePaymentMethodHandlers
96-
Vue.prototype.handleBeforePlaceOrderHandlers = runBeforePlaceOrderHandlers
97-
98-
Vue.prototype.handlePlaceOrder = async function (data, response) {
99-
if (!response?.data) {
100-
return response?.data
84+
return response.data
10185
}
10286

103-
if (!response?.data?.placeOrder?.orderV2 && response?.data?.placeOrder?.errors) {
104-
const message = response.data.placeOrder.errors.find(() => true).message
105-
Notify(message, 'error')
106-
throw new Error(message)
87+
vue.config.globalProperties.updateOrder = async function (data, response) {
88+
await updateOrder(data, response)
89+
90+
return response.data
10791
}
10892

109-
await updateOrder(data, response)
110-
await runAfterPlaceOrderHandlers(response, this)
93+
vue.config.globalProperties.handleBeforePaymentMethodHandlers = runBeforePaymentMethodHandlers
94+
vue.config.globalProperties.handleBeforePlaceOrderHandlers = runBeforePlaceOrderHandlers
11195

112-
return response.data
113-
}
96+
vue.config.globalProperties.handlePlaceOrder = async function (data, response) {
97+
if (!response?.data) {
98+
return response?.data
99+
}
100+
101+
if (!response?.data?.placeOrder?.orderV2 && response?.data?.placeOrder?.errors) {
102+
const message = response.data.placeOrder.errors.find(() => true).message
103+
Notify(message, 'error')
104+
throw new Error(message)
105+
}
106+
107+
await updateOrder(data, response)
108+
await runAfterPlaceOrderHandlers(response, this)
109+
110+
return response.data
111+
}
112+
})

resources/js/components/Checkout/CheckoutLogin.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export default {
3535
}),
3636
3737
render() {
38-
return this.$scopedSlots.default(this)
38+
return this.$slots.default(this)
3939
},
4040
4141
mounted() {

resources/js/components/Checkout/CheckoutSuccess.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export default {
1212
},
1313
1414
render() {
15-
return this.$scopedSlots.default(this)
15+
return this.$slots.default(this)
1616
},
1717
1818
created() {
@@ -27,7 +27,7 @@ export default {
2727
}
2828
})
2929
30-
this.$root.$emit('checkout-success', this.order)
30+
window.$emit('checkout-success', this.order)
3131
3232
useEventListener(window, 'beforeunload', this.beforeUnloadCallback, { once: true })
3333
},

resources/js/components/Elements/RangeSlider.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ export default {
1616
default: () => ({ min: undefined, max: undefined }),
1717
},
1818
},
19+
emits: ['change'],
1920
2021
render() {
21-
return this.$scopedSlots.default(this)
22+
return this.$slots.default(this)
2223
},
2324
2425
data() {

resources/js/components/Elements/Slider.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useElementHover, useIntervalFn, useEventListener, useThrottleFn, useRes
33
44
export default {
55
render() {
6-
return this.$scopedSlots.default(this)
6+
return this.$slots.default(this)
77
},
88
props: {
99
reference: {
@@ -77,11 +77,11 @@ export default {
7777
},
7878
methods: {
7979
initSlider() {
80-
this.slider = this.$scopedSlots.default()[0].context.$refs[this.reference]
80+
this.slider = this.$slots.default(this)[0].ctx.refs[this.reference]
8181
if (Array.isArray(this.slider) && this.slider.length) {
8282
this.slider = this.slider[0]
8383
}
84-
this.container = this.containerReference ? this.$scopedSlots.default()[0].context.$refs[this.containerReference] : this.slider
84+
this.container = this.containerReference ? this.$slots.default(this)[0].ctx.refs[this.containerReference] : this.slider
8585
},
8686
initLoop() {
8787
if (!this.loop) {
@@ -120,7 +120,7 @@ export default {
120120
if (!this.stopOnHover) {
121121
return
122122
}
123-
this.hover = useElementHover(this.$el)
123+
this.hover = useElementHover(this.$el.nextSibling)
124124
},
125125
scroll(event) {
126126
this.position = this.vertical ? event.target.scrollTop : event.target.scrollLeft

resources/js/components/Elements/Toggler.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script>
22
export default {
33
render() {
4-
return this.$scopedSlots.default(this)
4+
return this.$slots.default(this)
55
},
66
props: {
77
open: {

resources/js/components/GlobalSlideover.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ export default {
1010
}
1111
},
1212
render() {
13-
return this.$scopedSlots.default(this)
13+
return this.$slots.default(this)
1414
},
1515
mounted() {
16-
this.$root.$on('global-slideover-open', (data) => {
16+
window.$on('global-slideover-open', (data) => {
1717
this.isCurrentSlideover = data.initiator === this
1818
})
1919
},
2020
methods: {
2121
open() {
22-
this.$root.$emit('global-slideover-open', { title: this.title, position: this.position, initiator: this })
22+
window.$emit('global-slideover-open', { title: this.title, position: this.position, initiator: this })
2323
},
2424
},
2525
}

resources/js/components/GlobalSlideoverInstance.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script>
22
export default {
33
render() {
4-
return this.$scopedSlots.default(this)
4+
return this.$slots.default(this)
55
},
66
data() {
77
return {
@@ -10,10 +10,10 @@ export default {
1010
}
1111
},
1212
mounted() {
13-
this.$root.$on('global-slideover-open', (data) => {
13+
window.$on('global-slideover-open', (data) => {
1414
this.title = data.title || ''
1515
this.position = data.position || 'left'
16-
this.$el.querySelector('#slideover-global').checked = true
16+
this.$el.nextSibling.querySelector('#slideover-global').checked = true
1717
})
1818
},
1919
}

resources/js/components/Graphql.vue

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,17 @@ export default {
4646
}),
4747
4848
render() {
49-
if (!('default' in this.$scopedSlots)) {
49+
if (!('default' in this.$slots)) {
5050
return null
5151
}
5252
53-
return this.$scopedSlots.default({ ...this, variables: this.dataVariables })
53+
return this.$slots.default({
54+
props: this.$props,
55+
variables: this.dataVariables,
56+
data: this.data,
57+
running: this.running,
58+
runQuery: this.runQuery,
59+
})
5460
},
5561
5662
created() {

0 commit comments

Comments
 (0)