Ладно ... Ответов нет вообще, - так что я сам погрузился в это. Это лучшее, что я мог придумать. Я надеюсь, что это помогает другим, нуждающимся в том же.
Я разрывался между использованием extends
( источник ) или mixins
( источник ).
После небольшого исследования я в конечном итоге использовал миксины ( это видео ударило по голове о том, чего я пытался достичь и как его решить). Если вы хотите сделать миксин глобальным для всех компонентов, посмотрите это видео около 4:11 и далее. Я не делаю это в нижеследующем объяснении.
Обратите внимание, что я использую webpack наряду с laravel-mix с нижеприведенным решением. Используется в WordPress-установке.
Раскрытие
Это смесь из миллиарда разных ответов и статей. Потребовалось бы целую вечность, чтобы приписать все это правильным владельцам и источникам, так что я даже не буду пытаться. Сожалею.
Mixins-файл (./mixins/scrollAndResize.js
).
export const scrollAndResizeMixin = {
created() {
console.log( 'scrollAndResizes loaded' );
this.calcScroll();
this.calcPageAndViewport();
},
data: function() {
return {
scrollFromTop: 0,
viewportHeight: 0,
viewportWidth: 0,
pageHeight: 0
}
},
methods: {
calcScroll: function (){
let doc = document.documentElement;
this.scrollFromTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
// DEBUG (uncomment and scroll, to check if it works)
// console.log( (window.pageYOffset || doc.scrollTop) );
// console.log( (doc.clientTop || 0) );
},
calcPageAndViewport: function(){
// Viewport info
this.viewportHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
this.viewportWidth = Math.min(document.documentElement.clientWidth, window.innerWidth || 0);
// Page length
var body = document.body;
var html = document.documentElement;
this.pageHeight = Math.max(
body.scrollHeight,
body.offsetHeight,
html.clientHeight,
html.scrollHeight,
html.offsetHeight
);
},
}
};
Основной js-файл (./app.js
).
// Vue
import Vue from 'vue';
// Mixins
import { scrollAndResizeMixin } from './mixins/scrollAndResize';
// The Application
const app = new Vue({
mixins: [
scrollAndResizeMixin
],
computed: {
mobile: function() {
return this.viewportWidth < 992; // This uses the mixin
}
},
created() {
window.addEventListener( 'scroll', this.calcScroll );
window.addEventListener( 'resize', this.calcPageAndViewport );
},
destroyed() {
window.removeEventListener( 'scroll', this.calcScroll );
window.removeEventListener( 'resize', this.calcPageAndViewport );
}
});
И / или использовать его только в таком компоненте, как ...
<template>
<div>
<p v-if="viewportWidth > 992">
Desktop
</p>
<p v-else>
Mobile
</p>
</div>
</template>
<script>
import { scrollAndResizeMixin } from '../mixins/scrollAndResize';
export default {
mounted() {
},
mixins: [
scrollAndResizeMixin
],
created() {
window.addEventListener('scroll', this.calcScroll);
window.addEventListener('resize', this.calcPageAndViewport);
},
destroyed() {
window.removeEventListener('scroll', this.calcScroll);
window.removeEventListener('resize', this.calcPageAndViewport);
}
}
</script>