<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] >[success] # 正式分裝章節 ~~~ 1.上個章節講了一下思路,這個章節會封裝一個splitpane的布局組件 ~~~ >[danger] ##### 基礎面板 ~~~ 1.根據上章節封裝一個基礎面板 ~~~ ~~~ <template> <div class="split-pane-wrapper"> <div class="pane pane-left" :style="{width:leftOffsetPercent}"> <button @click="handleClick">點擊減少左側寬度</button> </div> <div class="pane-trigger-con" :style="{left:triggerLeft, width: `${triggerWidht}px`}"></div> <div class="pane pane-right" :style="{left:leftOffsetPercent}"></div> </div> </template> <script> export default { name: "split-pane", props:{ triggerWidht:{ type:Number, default:8, }, }, data(){ return{ // 在這定義一個值。這樣用戶可以直接指定占比的值 // 在頁面css 布局使用的值 使用計算屬性拼接即可 leftOffset:0.3, } }, methods:{ handleClick(){ this.leftOffset -= 0.02 } }, computed:{ // 動態屬性去拼接生成css 實際需要的代%形式的數據 leftOffsetPercent(){ return `${this.leftOffset * 100}%` }, triggerLeft(){ return `calc(${this.leftOffset * 100}% - ${this.triggerWidht/2}px)` }, }, } </script> <style lang="less"> .split-pane-wrapper{ width: 100%; height: 100%; position: relative; .pane{ position: absolute; height: 100%; top:0; &-left{ /*width: 30%;*/ background: brown; } &-right{ right: 0; bottom: 0; /*left: 30%;*/ background: chartreuse; } &-trigger-con{ z-index: 100; height: 100%; background: red; position: absolute; top: 0; } } } </style> ~~~ >[info] ## 增加事件 ~~~ 1.接下來需要做通過給紅色條添加事件,可以通過數據去操作布局 2.了解幾個方法'event.pageX' -- 鼠標x軸的坐標距離(準確或是) 3.'this.$refs.outer.getBoundingClientRect()' -- 獲取綁定dom元素的一些 距離瀏覽器的基本信息: DOMRect {x: 8, y: 8, width: 400, height: 200, top: 8, …} bottom:208 height:200 left:8 right:408 top:8 width:400 x:8 y:8 3.常見想得到某個元素具體的位置,一般采用鼠標距離減去dom元素距 離瀏覽器距離 4.'event'事件中隱藏的兩個快捷方法'event.srcElement' -- 獲取當前dom 5.'event'事件中隱藏的兩個快捷方法'event.srcElement.getBoundingClientRect()' -- 獲取當前dom位置信息 6.去除css 拖住樣式'user-select: none;' ~~~ >[danger] ##### 綁定鼠標點擊紅條時候觸發事件 ~~~ 1.想在鼠標點擊的時候觸發一個事件,可以得到紅色條距離dom的位置 ,后期根據這個位置去觸發讓左側和右側距離重新計算。 2.點擊事件應該綁定在哪里,如果將點擊事件綁定在紅條區域,會出現 當鼠標移出紅條的位置的時候,整個動態布局停止 'event.target.addEventListener('mousemove',this.handleMousemove)' 3.因此不能寫成上面的寫法,而是應該綁定在整個document上 'document.addEventListener('mousemove',this.handleMousemove)' 4.在點擊事件上,增加的鼠標移動后重新計算的事件分開寫方便維護 5.增加移入事件后,要對應的加入移除事件的后續操作,因此在data 中聲明一個變量'canMove'用來記錄當前點擊還是未點擊來觸 發'handleMousemove' 事件 6.由于'mousemove' 是綁定在全局的,因此'mouseup' 也要綁定全局 7.按照第六條的思路需要在頁面上綁定兩個事件,但實際可以整合在 '@mousedown="handleMousedown" ' 中,這里面已經綁定了一個鼠標 移入事件,因此直接在綁定一個鼠標抬起事件 'handleMousup' 8.當我們計算'leftOffset'也就是左面區域的百分比的時候,鼠標到左側邊框 距離除以整體距離,就會出現一個效果,一瞬間區域發生變化并且鼠標 在整個紅色區域,為了避免這個問題定位計算的時候直接從紅條中心 位置計算,對應代碼地方的g公式如下: 'const offset = event.pageX - this.initOffset + this.triggerWidth / 2 - outerRect.left;' ~~~ ~~~ <template> <div class="split-pane-wrapper" ref="outer"> <div class="pane pane-left" :style="{width:leftOffsetPercent}"> <button @click="handleClick">點擊減少左側寬度</button> </div> <div class="pane-trigger-con" @mousedown="handleMousedown" :style="{left:triggerLeft, width: `${triggerWidth}px`}"></div> <div class="pane pane-right" :style="{left:leftOffsetPercent}"></div> </div> </template> <script> export default { name: "split-pane", props:{ triggerWidth:{ type:Number, default:8, }, }, data(){ return{ // 在這定義一個值。這樣用戶可以直接指定占比的值 // 在頁面css 布局使用的值 使用計算屬性拼接即可 leftOffset:0.3, // 增一個判斷 鼠標移入移除 canMove :false, // 去除誤差值 initOffset: 0 } }, methods:{ handleClick(){ this.leftOffset -= 0.02 }, handleMousemove(event){ // pageX 是鼠標距離瀏覽器x軸的距離 // 想獲取 紅條在布局頁面的準確位置需要用鼠標距離 - 容器對瀏覽器的距離 // 因此給 這個外部的div 綁上ref 屬性用來獲取,獲取可以使用getBoundingClientRect() //console.log(event.pageX -this.$refs.outer.getBoundingClientRect().left) if(!this.canMove) return const outerRect = this.$refs.outer.getBoundingClientRect(); // 整個leftOffset 的像素距離其實是其實就是pageX鼠標距離減去最外層整理距離瀏覽器的距離 //根據上面可以得到一個公式就是 event.pageX-outerRect.left // 但要注意實際上中間區域是蓋住了部分左右區域,也就是說只要我們進行了改變 // 就會自動到整個中間區域的中間位置,因此需要在點擊的時候需要得到整中間區域最右面的位置 // 根據上面得到一個公式減去 this.initOffset也就是扣除無用區域獲得中間區域最右面 // 為了去除因為中間區域覆蓋的影響加上中間區域一半的寬度 const offset = event.pageX - this.initOffset + this.triggerWidth / 2 - outerRect.left; this.leftOffset = (offset/outerRect.width) }, handleMousup(){ // 抬起后 重新對canMove 賦值,讓紅條不能移動 this.canMove = false }, handleMousedown(event){ //event.target.addEventListener('mousemove',this.handleMousemove) document.addEventListener('mousemove',this.handleMousemove) document.addEventListener('mouseup',this.handleMousup) this.initOffset = event.pageX - event.srcElement.getBoundingClientRect().left this.canMove = true; }, }, computed:{ // 動態屬性去拼接生成css 實際需要的代%形式的數據 leftOffsetPercent(){ return `${this.leftOffset * 100}%` }, triggerLeft(){ return `calc(${this.leftOffset * 100}% - ${this.triggerWidth/2}px)` }, }, } </script> <style lang="less"> .split-pane-wrapper{ width: 100%; height: 100%; position: relative; .pane{ position: absolute; height: 100%; top:0; &-left{ /*width: 30%;*/ background: brown; } &-right{ right: 0; bottom: 0; /*left: 30%;*/ background: chartreuse; } &-trigger-con{ z-index: 100; height: 100%; background: red; position: absolute; top: 0; } } } </style> ~~~ >[danger] ##### 最后的封裝 ~~~ 1.上面已經可以實現整體使用,但是需要注意拖拽是有限度的,因此也需要設置拖拽的最大值最小值 2.上面的代碼是我們指定'leftOffset'也是百分比占比,如果讓組件去控制,就要有一個問題, 當我么拖拽的時候會重新改變這個值因此就是涉及到,父傳子和子傳父同時出發,想同時 出發兩種方法在使用組件的時候使用v-model 和 使用語法糖sync ~~~ * 在使用組件的時候 ~~~ <template> <div class="split-pane-con"> <split-pane :value.sync="offset"> <div slot="left">left</div> <div slot="right">right</div> </split-pane> </div> </template> <script> import SplitPane from '_c/split-pane' export default { components: { SplitPane }, data () { return { offset: 0.8 } }, methods: { // handleInput (value) { // this.offset = value // } } } </script> <style lang="less"> .split-pane-con{ width: 400px; height: 200px; background: papayawhip; } </style> ~~~ * 組件封裝代碼 ~~~ <template> <div class="split-pane-wrapper" ref="outer"> <div class="pane pane-left" :style="{ width: leftOffsetPercent, paddingRight: `${this.triggerWidth / 2}px` }"> <slot name="left"></slot> </div> <div class="pane-trigger-con" @mousedown="handleMousedown" :style="{ left: triggerLeft, width: `${triggerWidth}px` }"></div> <div class="pane pane-right" :style="{ left: leftOffsetPercent, paddingLeft: `${this.triggerWidth / 2}px` }"> <slot name="right"></slot> </div> </div> </template> <script> export default { name: 'SplitPane', props: { value: { type: Number, default: 0.5 }, triggerWidth: { type: Number, default: 8 }, min: { type: Number, default: 0.1 }, max: { type: Number, default: 0.9 } }, data () { return { // leftOffset: 0.3, canMove: false, initOffset: 0 } }, computed: { leftOffsetPercent () { return `${this.value * 100}%` }, triggerLeft () { return `calc(${this.value * 100}% - ${this.triggerWidth / 2}px)` } }, methods: { handleClick () { this.leftOffset -= 0.02 }, handleMousedown (event) { document.addEventListener('mousemove', this.handleMousemove) document.addEventListener('mouseup', this.handleMouseup) this.initOffset = event.pageX - event.srcElement.getBoundingClientRect().left this.canMove = true }, handleMousemove (event) { if (!this.canMove) return const outerRect = this.$refs.outer.getBoundingClientRect() let offsetPercent = (event.pageX - this.initOffset + this.triggerWidth / 2 - outerRect.left) / outerRect.width if (offsetPercent < this.min) offsetPercent = this.min if (offsetPercent > this.max) offsetPercent = this.max // this.$emit('input', offsetPercent) this.$emit('update:value', offsetPercent) }, handleMouseup () { this.canMove = false } } } </script> <style lang="less"> .split-pane-wrapper{ height: 100%; width: 100%; position: relative; .pane{ position: absolute; top: 0; height: 100%; &-left{ // width: 30%; background: palevioletred; } &-right{ right: 0; bottom: 0; background: paleturquoise; } &-trigger-con{ height: 100%; background: red; position: absolute; top: 0; z-index: 10; user-select: none; cursor: col-resize; } } } </style> ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看