Day 31 | 常见 Livewire 问题: jQuery 在渲染时会打回原形

jQuery 在大多数的专案中都不可或缺,在没有 Livewire 之前要修改画面都要靠它来手动更改。但使用了 Livewire 後,Livewire 的渲染机制居然会导致 jQuery 失效!??

ㄧ、先简单建立一个有使用 jQuery 的功能

先简单用在画面上印出一个 Hello World,并透过 jQuery 去将它改成 你好世界

<div>
    <p id="title">Hello World!!</p>
</div>

<script>
    $('#title').text('你好世界 !!')
</script>

https://ithelp.ithome.com.tw/upload/images/20211005/20111805KAb8ChF0V8.png

这时候画面都很正常,原本的「HelloWorld」也有被正确的替换成 「你好世界」


二、给他一个 Input

这时我们就来做一些会产生页面变动的事吧!只要输入了值就会带动下方的 $input_text 显示跟着修改,到时候再来看会不会有问题!

public $input_text;
<div class="mt-5">
        <label>随意输入些什麽</label>
        <input type="text" wire:model="input_text">

        刚刚输入的:{{ $input_text }}
    </div>

https://ithelp.ithome.com.tw/upload/images/20211005/20111805yNoZNEjt8N.png


三、输入!然後爆炸!!!

咦咦咦咦咦! 随着输入的同时,上方的「你好世界」居然变回最原本的 Hello World 了 !!!

https://ithelp.ithome.com.tw/upload/images/20211005/2011180573OYkiAIyH.png


四、解决方法

坏掉的原因是因为画面有变动时,会使页面重新渲染都并致後来透过手动修改 DOM 的内容被打回原形。所以不光只有 jQuery 会有问题,就算是用原生的 document 去改动页面都会有这个问题!

知道原因後,只要知道画面哪时候改动再去执行一次改动的程序码就好啦!!

因为要重新执行一次一模一样的 code,因此可以考虑把载入页面时执行的 JavaScript 都包进一个 Function ,这样之後更新时直接呼叫一个就能跑全部。也要记得呼叫一次,这样才会执行

<script>
    function init () {
        $('#title').text('你好世界 !!')
    }

    init()
</script>

之後加入 Livewire 的事件监听,每当触发 ReloadJS 事件就会执行一次:

Livewire.on('ReloadJS', () => {
    init()
})

由於 Livewire.on 必须跟最外层引入的 @livewireScripts 放一起才有作用,这个在讲解该篇时也有提到。所以我们会用 @section('scripts') 将每个 Livewire 元件的 <scrpitt> 区块包起来,好让他被渲染至最外层。

完整的 JS 部分长这样

@section('scripts')
<script>
    function init () {
        $('#title').text('你好世界 !!')
    }

    init()

    Livewire.on('ReloadJS', () => {
        init()
    })

</script>
@endsection

之後就可以在变动时透过 $this->emit('ReloadJS') 来触发上面写的监听,这样就算画面重新渲染了也能重新执行修改 DOM 的程序码!!所以我们可以很好地利用生命周期勾(Lifecycle Hooks)去呼叫它:

这里不使用 updated 的原因很简单,因为 updated 只会在 wire:model 修改时触发。所以如果我在按钮呼叫後端改值的函式,即便值被改了也不会触发到 updated。

    public function hydrate()
    {
        $this->emit('ReloadJS');
    }

结论 & 心得

还是尽量不要手动去修改 DOM 的内容。不管是 VueJS 还是 Livewire 其实都可以透过资料去控制画面的呈现,官方文件也都会呼吁尽量避免手动修改的操作。其实在 Vue 使用 jQuery 其实也很容易发生跟现在类似的问题 XD

不过 Vue 到现在已经有很大量的元件库可以使用,不管是在表格、HTML页面产生器等等功能都有 Vue 的版本可以用。而 Livewire 等还比较少类似的元件,因此还是很难避免使用到含有 jQuery 的前端套件。万一遇到了也只能乖乖的一个一个照上方的方法做啦。


<<:  [day-19] 认识Python的资料结构!(Part .6)

>>:  Chapter5 - 当一个勤劳的园丁,来修剪我们美丽的树(II)Canvas素材 修图、压缩、效能优化

Day 5 基本 flask 函式 (2)

前言 今天会继续探讨其他的 flask 的函式。如果说昨天的函式是用来给予使用者回应,那今天提到的函...

Day 22 - Ajax

Ajax ( Asynchronous JavaScript and XML ) 网页不用重新整理,...

{CMoney战斗营} 的第十四周 # Web API

这周的主题是Web API,也就是透过HTTP通讯协定,来请求及获得回覆,也就是透过URL来传递後端...

前端工程师也能开发全端网页:挑战 30 天用 React 加上 Firebase 打造社群网站|Day22 修改会员名称

连续 30 天不中断每天上传一支教学影片,教你如何用 React 加上 Firebase 打造社群...

{DAY 13} NumPy 学习笔记(中)

前言 今天要延续昨天的NumPy语法练习 内容会分成两大部分 将会涵盖如何提取、更新、删除阵列里的...