console
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>vue3 txta-demo</title>
<meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" name="viewport">
<meta name="renderer" content="webkit">
<style>
* {
margin: 0;
padding: 0;
list-style: none;
}
body {
font-size: 14px;
font-family: sans-serif,"HelveticaNeue",Helvetica,"PingFangSC","MicrosoftYaHei","HiraginoSansGB",Arial;
color: #27282b;
background: #fff;
}
a {
text-decoration: none;
color: #27282b;
}
*,
*::before,
*::after {
outline: none;
box-sizing: border-box;
}
html,
body {
min-height: 100vh;
}
.mnp {
display: flex;
width: 60vw;
height: 70vh;
border-radius: 2px;
overflow: hidden;
border: 1px solid #ddd;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
}
.tet {
display: block;
padding: 15px;
line-height: 1.6;
font-family: Consolas,sans-serif,"HelveticaNeue",Helvetica;
resize: none;
overflow: auto;
border: 0;
color: #555;
font-size: 15px;
outline: none;
}
.tet:focus {
background: #fcfcff;
}
.tet1 {
min-width: 50px;
}
.tet2 {
flex: 1;
}
.ctr-bar {
width: 10px;
height: 100%;
user-select: none;
background: transparent;
margin-right: -5px;
cursor: e-resize;
position: absolute;
top: 0;
z-index: 1;
transition: background-color .3s;
}
.ctr-bar::before {
content: '';
width: 1px;
height: 100%;
background: #ddd;
transition: .2s;
position: absolute;
top: 0;
left: 45%;
}
.ctr-bar:hover {
background: #e9ebee;
}
.ctr-bar:hover::before {
background: transparent;
}
</style>
</head>
<body>
<div class="wrapper" id="app">
<div class="mnp">
<div class="ctr-bar" :style="`left: ${dp.ctrBarLeft}px`"></div>
<textarea class="tet tet1" :style="`width: ${dp.lWidth}`" v-model="ttContent"></textarea>
<textarea class="tet tet2" v-model="ttContent"></textarea>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vio-utils/utils.min.js"></script>
<script>
const vm = Vue.createApp({
setup(props, ctx) {
const { ref, reactive, computed, onMounted, watch } = Vue
let ttContent = ref('')
let scrollTop = ref(0)
let isLeftScroll = ref(true)
const dp = reactive({
ctrBarLeft: 200,
lWidth: '50%',
mnpRectL: 0,
mnpRectR: 0,
canMove: false,
})
function setElScrollTop(selector) {
document.querySelector(selector).scrollTop = scrollTop.value
}
function regBarEvt() {
document.querySelector('.mnp').addEventListener('mousemove', e => {
if (dp.canMove) {
dp.ctrBarLeft = Math.min(Math.max(100, e.clientX - dp.mnpRectL - 5), dp.mnpRectR - 100 - dp.mnpRectL - 5)
dp.lWidth = 1
}
})
document.querySelector('.ctr-bar').addEventListener('mousedown', e => {
dp.canMove = true
})
document.addEventListener('mouseup', e => {
dp.canMove = false
})
document.querySelector('.tet1').addEventListener('scroll', vio.throttle(e => {
isLeftScroll = true
scrollTop.value = e.target.scrollTop
}, 0))
document.querySelector('.tet2').addEventListener('scroll', vio.throttle(e => {
isLeftScroll = false
scrollTop.value = e.target.scrollTop
}, 0))
}
onMounted(() => {
const mnp = document.querySelector('.mnp').getBoundingClientRect()
dp.ctrBarLeft = mnp.width / 2 - 5
dp.mnpRectL = mnp.left
dp.mnpRectR = mnp.right
regBarEvt()
})
watch(dp, (nVal) => {
dp.lWidth = `${nVal.ctrBarLeft + 5}px`
})
watch(scrollTop, (nVal) => {
isLeftScroll ? setElScrollTop('.tet2') : setElScrollTop('.tet1')
})
return {
vio,
dp,
ttContent,
scrollTop,
}
},
}).mount('#app')
</script>
</body>
</html>