为什么 Alpine x-data 对其自身的属性变化没有反应?

问题描述 投票:0回答:1

有一个输入组件。代码如下。

@props([
'disabled' => false,
'hidden' => false,
'type' => 'text',
'state' => null,
'borderClass' => ''
])

@php
switch ($state){
    case 'alert':
        $borderClass = 'border-2 border-red-600';
        break;
    case 'success':
        $borderClass = 'border-2 border-green-600';
        break;
}

@endphp

<input x-data="{
    borderClass: @js($borderClass),
    removeBorderClass() {

        // for testing
        document.querySelectorAll('[x-data]').forEach(el => {
            console.log(el);
        });
        console.log(document.getElementById('title'));
        // end for testing

        if (@js($borderClass)){
            let classes = this.borderClass.split(' ');
            $refs.input.classList.remove(...classes);
        }
    }
}"
    x-ref="input"
    x-on:focus="removeBorderClass()"

    value = "{{ $slot ?? '' }}"
    type = "{{ $type }}"
    {{ $disabled ? 'disabled' : '' }}
    {{ $hidden ? 'hidden' : '' }}
    {{ $attributes->merge(['class' => 'focus:ring-indigo-600 focus:border-indigo-600 focus:border shadow-sm sm:text-sm rounded-md border-gray-300 ' . $borderClass]) }}
 >

更改 $state 属性和 $borderClass 属性后,我在屏幕上看到边框颜色的更改,即

border-2 border-red-600
被添加到 DOM,但在调用
x-on:focus=removeBorderClass()

时,我没有得到任何 alpine 的更改

我决定测试结果并在方法中实现

console.log
,使用两种不同的方式来获取相同的DOM元素。 1. 通过“x-data”选择器和“id”

    // for testing
    document.querySelectorAll('[x-data]').forEach(el => {
        console.log(el);
    });
    console.log(document.getElementById('title'));
    // end for testing

这是浏览器开发工具的结果。对于

1.

document.querySelectorAll('[x-data]').forEach(el => {
                console.log(el);
            });

结果(仅是我们输入元素的一部分):

<input x-data="{
    borderClass: '',
    removeBorderClass() {

        // for testing
        document.querySelectorAll('[x-data]').forEach(el => {
            console.log(el);
        });
        console.log(document.getElementById('title'));
        // end for testing

        if (''){
            let classes = this.borderClass.split(' ');
            $refs.input.classList.remove(...classes);
        }
    }
}" x-ref="input" x-on:focus="removeBorderClass()" value="" type="text" class="focus:ring-indigo-600 focus:border-indigo-600 focus:border shadow-sm sm:text-sm rounded-md border-gray-300  w-full" style="margin-right: -2.75rem;" name="depth" wire:model.lazy="depth" placeholder="0" title="depth">
console.log(document.getElementById('title'));

结果:

<input x-data="{
    borderClass: 'border-2 border-red-600',
    removeBorderClass() {

        // for testing
        document.querySelectorAll('[x-data]').forEach(el => {
            console.log(el);
        });
        console.log(document.getElementById('title'));
        // end for testing

        if ('border-2 border-red-600'){
            let classes = this.borderClass.split(' ');
            $refs.input.classList.remove(...classes);
        }
    }
}" x-ref="input" x-on:focus="removeBorderClass()" value="" type="text" class="focus:ring-indigo-600 focus:border-indigo-600 focus:border shadow-sm sm:text-sm rounded-md border-gray-300 border-2 border-red-600 w-full" wire:model.lazy="title" name="title" id="title">

为什么它们不同。为什么调用同一个元素会得到不同的结果?如何与 alpine 进行更改?

laravel-blade laravel-livewire alpine.js
1个回答
0
投票

我做了测试,你的代码非常适合我。

我能给你的主要建议是,如果你使用新的 Tailwind 类,请重新构建资源,否则这些类可能无法应用。
使用Vite:

npm 运行构建

npm 运行开发


另一方面,通过 javascript 删除类可能是不必要的,默认情况下使用前缀 focus:

定义对应项就足够了
@props([
'disabled' => false,
'hidden' => false,
'type' => 'text',
'state' => null,
'borderClass' => ''
])

@php
    switch ($state){
        case 'alert':
            $borderClass = 'border-2 border-red-600 text-orange-400';
            break;
        case 'success':
            $borderClass = 'border-2 border-green-600 text-fuchsia-600';
            break;
    }

@endphp

<input x-data
       x-ref="input"
       value = "{{ $slot ?? '' }}"
       type = "{{ $type }}"
    {{ $disabled ? 'disabled' : '' }}
    {{ $hidden ? 'hidden' : '' }}
    {{ $attributes->merge(['class' => 'focus:text-slate-950 focus:ring-indigo-600 focus:border-indigo-600 ' .
                                      'focus:border shadow-sm sm:text-sm rounded-md border-gray-300 ' .
                                      $borderClass]) }}
>

在此示例中,我在默认列表中添加了类 focus:text-slate-950 ,并为 alert 状态设置 text-orange-400 ,为 success 设置 text-fuchsia-600 state:浏览器将使用 Tailwind 类应用适当的样式。

© www.soinside.com 2019 - 2024. All rights reserved.