[英](Vue3) Problems syncing DOM element heights change using v-model and v-on
我正在創建一個網站,其中使用v-model
將范圍 slider 的值綁定到名為rangeValue
的屬性。 該代碼類似於以下內容:
<template>
...
<input
type="range"
min="10"
max="50"
class="slider"
v-model="rangeValue"
@change="updateHeight()"
/>
<div class="otherDiv" :style="{ height: `${wrapperHeight}px`></>
<div
class="firstDiv"
ref="first"
:style="{ width: `${rangeValue}rem` }">
<!-- There are elements inside whose height is also bound by rangeValue, and some that are toggled on/off via other checkbox inputs, thereby changing the height of firstDiv -->
</div>
</template>
<script>
export default {
data() {
return {
wrapperHeight: 0,
rangeValue: "10",
},
mounted(){
this.wrapperHeight = this.$refs.first.offsetHeight;
},
methods: {
updateHeight() {
this.wrapperHeight = this.$refs.first.offsetHeight;
}
}
}
</script>
<style>
...
</style>
我想讓 otherDiv 的高度與otherDiv
的高度相匹配,其高度根據范圍firstDiv
的變化而變化。 我的問題是firstDiv
的高度與范圍 slider 的變化同時更新,而otherDiv
的高度總是滯后一個“滴答”,更新到firstDiv
的值在它被范圍 slider 改變之前,而不是之后。 我嘗試了各種使用nextTick
的實現都無濟於事。
簡而言之,我需要:
firstDiv
的大小,獲取它在 DOM 中的高度,調整otherDiv
的大小我希望這是有道理的。 歡迎任何指點,謝謝!
這是你想要達到的目標嗎?
const { createApp, toRefs, reactive, computed } = Vue createApp({ setup: () => toRefs( reactive({ h8: 135 }) ) }).mount("#app")
#app.grid { display: grid; grid-gap: 0.75rem; grid-template-columns: repeat(2, 1fr); padding: 0.5rem; } #app.grid > * { overflow-y: auto; padding: 0.5rem; border-radius: 5px; box-shadow: inset 0 1px 8px 0 rgb(0 0 0/10%), inset 0 3px 4px 0 rgb(0 0 0 / 7%), inset 0 3px 3px -2px rgb(0 0 0 / 6%); background-color: #f8f8f8; } #app [type="range"] { max-width: 400px; width: 100%; margin: 0 auto; display: block; }
<script src="https://unpkg.com/vue@3.2.45/dist/vue.global.prod.js"></script> <div id="app"> <input type="range" min="60" max="400" v-model="h8" /> <div class="grid":style="{ height: `${h8}px` }"> <div class="firstDiv">first div</div> <div class="secondDiv"> second div <p v-for="n in 10":key="n">Lorem ipsum dolor sit amet.</p> </div> </div> </div>
您不僅限於擁有共同的父母(這似乎更適合您的情況)。
您可以同步完全不相關的組件,即使在單獨的應用程序中也是如此(參見下面的示例)。 您所需要的只是一個單一的事實來源。 我使用了反應式 object 但更常見和有用的實現是使用實際商店(pinia,vuex):
const { createApp, toRefs, reactive, computed } = Vue const store = reactive({ h8: 85 }); ['input-app', 'app-1', 'app-2'].forEach(app => createApp({ setup: () => toRefs(store) }).mount(`#${app}`))
#app-1, #app-2 { padding: 0.5rem; }.grid { display: grid; grid-template-areas: "input input" "app-1 app-2"; grid-template-rows: auto 1fr; grid-template-columns: 1fr 1fr; min-height: 100vh; } body { margin: 0 } #input-app { grid-area: input; } #app-1 { grid-area: app-1; } #app-2 { grid-area: app-2; align-self: end; }.firstDiv, .secondDiv { overflow-y: auto; padding: 0.5rem; border-radius: 5px; box-shadow: inset 0 1px 8px 0 rgb(0 0 0/10%), inset 0 3px 4px 0 rgb(0 0 0 / 7%), inset 0 3px 3px -2px rgb(0 0 0 / 6%); background-color: #f8f8f8; } [type="range"] { max-width: 400px; width: 100%; margin: 0 auto 1rem; display: block; }
<script src="https://unpkg.com/vue@3.2.45/dist/vue.global.prod.js"></script> <div class="grid"> <div id="input-app"> <input type="range" min="60" max="500" v-model="h8" /> </div> <div id="app-1"> <div class="firstDiv":style="{ height: `${h8}px` }"> first div </div> </div> <div id="app-2"> <div class="secondDiv":style="{ height: `${h8}px` }"> second div <p v-for="n in 10":key="n">Lorem ipsum dolor sit amet.</p> </div> </div> </div>
我真的不明白你的目標和高度/寬度關系。
但這里有一個類似的工作操場。
const { createApp, ref, onMounted } = Vue; const App = { setup() { const mydiv = ref(null); const wrapperHeight = ref(0); const rangeValue = ref(50); onMounted(() => { console.log(`onMounted(): ${mydiv.value.offsetHeight}`); wrapperHeight.value = mydiv.value.offsetHeight; }); const updateHeight = (event) => { console.log(`updateHeight(): ${event.target.value}`); wrapperHeight.value = event.target.value; } return {mydiv, wrapperHeight, rangeValue, updateHeight } } } const app = createApp(App) app.mount('#app')
<div id="app"> <input type="range" min="10" max="100" class="slider" v-model="rangeValue" @change="updateHeight" /><br/> rangeValue: {{rangeValue}} <br/> wrapperHeight: {{wrapperHeight}} <br/><br/> <div:style="{ 'background-color': 'yellow', 'min-height': `${wrapperHeight}px` }"> <div ref="mydiv" style="{ 'float': 'bottom' }">My Div</div> </div> </div> <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.