編程學習網 > PHP技術 > laravel > laravel-admin 與 vue 結合使用
2021
07-15

laravel-admin 與 vue 結合使用

由于 Laravel-admin 采用的是 pjax 的方式刷新頁面,意味著很多頁面刷新的操作,并不是刷新整個 document,而是從服務器拿到部分 document,再通過類似 $(“#pjax-container”).html(newPart) 的方式更新的。


這就造成一個問題,每次 pjax 刷新,都會破壞 vue 的 dom 映射。


所以理論上有2種方法解決:


重新綁定一下 vue 的映射關系

在某些頁面禁止 pjax

1 太難搞,而且沒啥資料,放棄。2 的話比較可行。


部分禁止 pjax

打開 public/vendor/laravel-admin/laravel-admin/laravel-admin.js 添加代碼:


// 不使用 pjax 刷新的頁面

$(document).on('pjax:beforeReplace', function (e, options) {

 // console.log(arguments)

 var freshPaths = [

   /\/admin.*\/products/,

 ]

 for (let path of freshPaths) {

   if (path.test) {

     if (path.test(e.state.url)) {

       location.reload()

       return false

     }

   }

   else if (options.url.search(path) !== -1) {

     location.reload()

     return false

   }

 }

})


使用自定義 view

很多時候我們并不需要大動干戈地建立一個全部的 view,只需要在內置 view 中稍作修改。 這時候,我們需要先自定義一個 Content 類:



use Encore\Admin\Layout\Content;

class MyContent extends Content {

   public function render() {

       $items = [

           'header'      => $this->header,

           'description' => $this->description,

           'breadcrumb'  => $this->breadcrumb,

           'content'     => $this->build(),

       ];

       return view('admin.content', $items)->render();

   }

}



然后引用它:



  public function index(MyContent $content) {

       return $content

           ->header('product')

           ->description($this->brand)

           ->body($this->grid());

   }
  


這樣一來,每次進入到 index 頁面,都會渲染 admin.content 這個 view 。


view 的內容直接 copy 自 vendor/encore/laravel-admin/resources/views/content.blade.php


在 view 里插入 vue 組件

添加2部分代碼即可。 第一部分是初始化 vue app:


   

 <script data-exec-on-popstate>

   // boot up the demo

   $(function () {

     // vapp

     window.vapp = new Vue({

       el: '#app',

       data () {

         return {

           status: {

             showGalleryEditor: false,

           },

           store: {

             images: [],

             el: '',

           },

         }

       },

       components: {},

       methods: {

         startGalleryEditing (event) {

           this.status.showGalleryEditor = true

           this.store.pk = $(event.target).parent().find('ul').data('pk')

           this.store.images = $(event.target).parent().find('img').toArray().map((e) => e.getAttribute('src'))

           window.p = $(event.target).parent().find('ul')

         },

       },

     })

   })

   </script>


第2部分是插入組件:



       <gallery-editor :status="status" :images="store.images" :pk="store.pk"></gallery-editor>



vue 組件單獨一個 js 文件

位置如下:public/vendor/components/gallery-editor.js 定義如下:



Vue.component('gallery-editor', {

 props: {

   status: {

     showGalleryEditor: false,

   },

   images: [],

   pk: 0,

   moveTo: [],

 },

 data () {

   return {}

 },

 watch: {

   images (newVal, oldVal) {

     this.moveTo = []

     for (let src of newVal) {

       this.moveTo.push({

         src: src,

         productId: this.pk,

         deleted: 0,

       })

     }

   },

 },

 methods: {

   close () {

     this.status.showGalleryEditor = false

   },

   save () {

     let args = {_token: LA.token}

     args.id = this.pk

     args.images = []

     args.move_to = []

     // console.log(JSON.stringify(this.moveTo))

     for (let imgObj of this.moveTo) {

       if (imgObj.deleted) {

         continue

       }

       if (imgObj.productId === this.pk) {

         args.images.push(imgObj.src)

       } else {

         args.move_to.push({src: imgObj.src, product_id: imgObj.productId})

       }

     }

     // console.log(JSON.stringify(args))

     $.post('/admin/products/move-images', args).done(() => {

       toastr.success('success')

       this.status.showGalleryEditor = false

     }).fail((response) => {

       toastr.error(response.responseText)

     })

   },

 },

 template: `

           <div class="modal" tabindex="-1" role="dialog" :class="{show: status.showGalleryEditor, fade: !status.showGalleryEditor}">

             <div class="modal-dialog" role="document">

               <div class="modal-content">

                 <div class="modal-header">

                   <button type="button" class="close" data-dismiss="modal" aria-label="Close" @click="close"><span aria-hidden="true">&times;</span></button>

                   <h4 class="modal-title">Editing images</h4>

                 </div>

                 <div class="modal-body">

                 <ul style="list-style-type: none;">

                     <li v-for="(imageObj, key) in moveTo" :key="key" style="margin-bottom: 8px">

                         <img :src="imageObj.src" alt="" style="width:40px;height:40px">

                         <label>Move to product: <input type="text" v-model="imageObj.productId"></label>

                         <label>Delete:<input type="checkbox" v-model="imageObj.deleted"></label>

                   </li>

                   </ul>

                 </div>

                 <div class="modal-footer">

                   <button type="button" class="btn btn-default" data-dismiss="modal" @click="close">Close</button>

                   <button type="button" class="btn btn-primary" @click="save">Save changes</button>

                 </div>

               </div>

             </div>

           </div>`,

})



這是一個彈出式編輯框,具體作用就不解釋了,只是個示例。


然后還需要在 Admin/bootstrap.php 中引用這個 js 文件:



Admin::js('/vendor/components/gallery-editor.js');
以上就是“laravel-admin 與 vue 結合使用”的詳細內容,想要獲取更多laravel教程歡迎關注編程學習網



掃碼二維碼 獲取免費視頻學習資料

Python編程學習

查 看2022高級編程視頻教程免費獲取