<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用 Vue3 指令封裝一個后臺管理系統(tǒng)圖片預覽功能

          共 8128字,需瀏覽 17分鐘

           ·

          2024-04-11 10:07

          作者:前端Ah

          https://juejin.cn/post/7324653675456364596

          最近公司搭建了一個新的 vue3 項目,因為項目中有很多模塊用到了圖片預覽功能,項目的 ui 框架用的是element-plus,框架自帶 el-image 組件里面帶了圖片預覽功能,但是當時我不想用這個組件,所以就借鑒了它里面預覽圖片組件的代碼。

          復習vue3指令的寫法

          官方指令文檔:https://cn.vuejs.org/guide/reusability/custom-directives.html#custom-directives

          簡單的例子

                
                <div v-color="red"> 我是紅色的文字</div>
                
                app.directive('color', (el, binding) => {
            // 這會在 `mounted` 和 `updated` 時都調(diào)用
            el.style.color = binding.value
          })

          這時候 div 里面的文字都變成紅色, v-color="yellow" 就變成了黃色

          相關參數(shù)介紹

          • el:指令綁定到的元素。這可以用于直接操作 DOM。
          • binding:一個對象,包含以下屬性。
          • value:傳遞給指令的值。例如在 v-my-directive="1 + 1" 中,值是 2
          • oldValue:之前的值,僅在 beforeUpdateupdated 中可用。無論值是否更改,它都可用。
          • arg:傳遞給指令的參數(shù) (如果有的話)。例如在 v-my-directive:foo 中,參數(shù)是 "foo"
          • modifiers:一個包含修飾符的對象 (如果有的話)。例如在 v-my-directive.foo.bar 中,修飾符對象是 { foo: true, bar: true }
          • instance:使用該指令的組件實例。
          • dir:指令的定義對象。
          • vnode:代表綁定元素的底層 VNode。
          • prevNode:代表之前的渲染中指令所綁定元素的 VNode。僅在 beforeUpdateupdated 鉤子中可用。

          新建 previewImageDirective.ts 文件

          導入相關函數(shù)及類型,編寫基本的指令代碼

                
                import { DirectiveBinding, h, render } from 'vue';
          import { ElImageViewer } from 'element-plus';

          export default function (app{
           app.directive('previewImage', {
            mounted(el: HTMLElement, binding: DirectiveBinding) {
             // 邏輯操作
            },
           });
          }
          • DirectiveBinding el的類型
          • h  將組件代碼轉(zhuǎn)成 vnode
          • render 將 vnode 渲染成 html

          下面開始編寫相關指令代碼

          首先我們需要創(chuàng)建一個 div 用來包裹我們的預覽組件,我們來控制這個 div 的顯示隱藏來實現(xiàn)預覽組件的彈出和隱藏。

          為什么這幾個變量為啥要定義成全局的,如果寫在指令內(nèi)部 v-previewImage="" 多次 就出現(xiàn)多個變量,和多個組件,造成了資源浪費,然后ElImageViewer組件一個頁面要寫多次還會出現(xiàn)一個錯誤

          f1added8c0397aca33ec382bdf226e33.webp 我給 element 提了issues,現(xiàn)在已經(jīng)修復,但還是推薦我這種寫法

                
                const previewBox = document.createElement('div'); // 創(chuàng)建節(jié)點
          previewBox.classList.add('preview-box'); // 給 div 增加類名
          let vnode; // 存放 vnode 的變量

          編寫指令內(nèi)部代碼

          • 第一步給圖片綁定點擊事件并給圖片添加樣式,當鼠標滑過添加小手的樣式
                
                export default function (app{
           app.directive('previewImage', {
            mounted(el: HTMLElement, binding: DirectiveBinding) {
             el.addEventListener('click', () => {
                                      el.style.cursor = 'pointer';
                                  })
            },
           });
          }
          • 第二步 使用 h 函數(shù) 渲染組件 將組件代碼轉(zhuǎn)成 vnode
                
                export default function (app{
           app.directive('previewImage', {
            mounted(el: HTMLElement, binding: DirectiveBinding) {
             el.addEventListener('click', () => {
                                      el.style.cursor = 'pointer';
                                  })
                                  vnode = h(ElImageViewer, {
              urlList: [binding.value], // 圖片地址
              hideOnClickModaltrue// 允許點擊遮罩層關閉
             });
            },
           });
          }
          • 第三步 使用 render 函數(shù)將 vnode 渲染到我們創(chuàng)建的div 里面,并且將我們創(chuàng)建的 div 插入到 body 里面
                
                export default function (app{
           app.directive('previewImage', {
            mounted(el: HTMLElement, binding: DirectiveBinding) {
             el.addEventListener('click', () => {
                                      el.style.cursor = 'pointer';
                                  })
                                  vnode = h(ElImageViewer, {
              urlList: [binding.value], // 圖片地址
              hideOnClickModaltrue// 允許點擊遮罩層關閉
             });
                                  render(vnode, previewBox); // 將 vnode 渲染成 html
                                  document.body.appendChild(previewBox); // 將 html 插入到 body 標簽里面
            },
           });
          }

          到現(xiàn)在為止我們點擊圖片組件已經(jīng)可以正常的顯示了

          8df8f53b48fe10cf170d14b9c4e21cd6.webp
          • 第四步當點擊遮罩層關閉的時候?qū)⑽覀儎?chuàng)建的 div 移除掉就 ok 了
                
                export default function (app{
           app.directive('previewImage', {
            mounted(el: HTMLElement, binding: DirectiveBinding) {
             el.addEventListener('click', () => {
                                      el.style.cursor = 'pointer';
                                  })
                                  vnode = h(ElImageViewer, {
              urlList: [binding.value], // 圖片地址
              hideOnClickModaltrue// 允許點擊遮罩層關閉
                                          onClose() => {
                                                   el.removeEventListener('click', () => {}); // 移除
                                                   document.body.removeChild(previewBox);
               },
             });
                                  render(vnode, previewBox); // 將 vnode 渲染成 html
                                  document.body.appendChild(previewBox); // 將 html 插入到 body 標簽里面
            },
           });
          }

          將文件導入到 main.ts中

          將文件導入 main.ts中然后調(diào)用我們導入的方法傳入 app 就可以在頁面中使用了

                
                import imageDirective from 'xxxx/previewImageDirective';
          const app = createApp(App);
          imageDirective(app)

          ok 上面就是完整代碼,這樣一個圖片預覽指令就完成了

          推薦閱讀  點擊標題可跳轉(zhuǎn)

          1、【Vue3】如何封裝一個超級好用的 Hook !

          2、Vue3實現(xiàn)加入購物車拋物線效果組件

          3、看尤雨溪說:為什么Vue3 中應該使用 Ref 而不是 Reactive?

          瀏覽 36
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  操人视频免费 | 性爱无码视频 | 免费观看黄色电影久久 | 粉嫩小丝袜在线观看 | 色色噜噜激情综合久久 |