使用Vue.js将输入字段的值绑定到第二个输入字段

时间:2017-02-18 23:26:33

标签: symfony vue.js

我有Symfony表格,其定义如下(为了简洁,减去不相关的字段):

<?php

namespace AppBundle\Form;

use AppBundle\Entity\Category;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class CategoryType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('label', TextType::class, [
                'label' => 'label.display_name',
                'attr' => [
                    'placeholder' => 'placeholder.category_name',
                    'class' => 'label',
                    '@input' => 'vUpdateSlug'
                ]
            ])
            ->add('slug', TextType::class, [
                'label' => 'label.slug',
                'attr' => [
                    'class' => 'slug',
                    '@input' => 'vUpdateSlug',
                    ':value' => 'slug'
                ]
            ]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Category::class,
            'category_id' => null
        ]);
    }
}

我将Vue.js指令附加到input个字段。我们的想法是,当有人在label字段中输入内容时,slug字段会自动使用label input值进行更新,并进行一些小的更改(用连字符替换空格)。我仍然希望用户能够根据需要更改slug,但不能更新标签。

v-on:input/@input指令行为有效,但是,我只是从Vue.js开始,我的实现感觉有点笨重(重复) - 见下文:

new Vue({
    delimiters: ['[[', ']]'],
    el: '#category-form',
    data: {
        slug: this.slug = $('[name="category[slug]"]').val()
    },
    ready: function () {
        this.slug = $('[name="category[slug]"]').val();
    },
    methods: {
        vUpdateSlug: function (event) {
            var str = event.target.value.replace(/[^a-zA-Z0-9 -]/g, '').replace(/\s+/g, '-').toLowerCase();
            return this.slug = str;
        }
    }
});

我的问题有更好的解决方案吗?

1 个答案:

答案 0 :(得分:1)

经过更多的研究和修补,我想出了以下结果:

<强> CategoryType

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('label', TextType::class, [
            'label' => 'label.display_name',
            'attr' => [
                'placeholder' => 'placeholder.category_name',
                'class' => 'label',
                'v-model' => 'label'
            ]
        ])
        ->add('slug', TextType::class, [
            'label' => 'label.slug',
            'attr' => [
                'class' => 'slug',
                '@input' => 'setSlug',
                ':value' => 'slug'
            ]
        ]);
}

Vue脚本

new Vue({
    delimiters: ['[[', ']]'],
    el: '#form-wrapper',
    data: {
        label: $('[name="category[label]"]').val(),
        slug: $('[name="category[slug]"]').val()
    },
    watch: {
        label: function(newLabel) {
            this.slug = this.compileSlug(newLabel)
        }
    },
    methods: {
        compileSlug: function(input) {
            return input.replace(/[^a-zA-Z0-9 -]/g, '')
                .replace(/\s+/g, '-')
                .toLowerCase();
        },
        setSlug: function (input) {
            this.slug = this.compileSlug(input.target.value)
        }
    }
});

JSFiddle functioning example