Vue JS在作用域插槽中选择带有v-model的元素

时间:2018-12-29 07:24:36

标签: vue.js

我有一个带有前端Vue js和后端Laravel的Web应用程序。我必须显示一个用于选择时区的下拉列表,该下拉列表将从刀片文件中的Laravel后端填充。我的vue组件中有一个作用域范围内的插槽,该插槽可以绑定该下拉列表,从而提供反应性属性selectedId,可以将其绑定为选择元素v-model。这里的问题是select元素设置为从反应性属性selectedId传递的值,但是在更改选择选项时,新值不会传递回该反应性属性selectedId。因此,我认为我无法以两种方式绑定反应性属性selectedId。我怎样才能解决这个问题?

以下是我的代码

NewProject.vue

<template>
    <div>
        <div class="row">
            <div class="col-md-12">
                <fieldset>
                    <div class="form-group">
                        <label class="col-sm-2 control-label">Select Project Time Zone</label>
                        <slot name="timezone" :selectedId="selectedId"></slot>
                        {{selectedId}}
                    </div>
                </fieldset>

                <button v-on:click="getSelectedTimeZone">Click Me</button>

            </div>
        </div>
    </div>
</template>

<script>

    export default{

        data(){
            return {
                selectedId: 'Pacific/Fiji'
            }
        },

        methods: {
            getSelectedTimeZone: function (event) {
                alert(this.selectedId);
            }
        },
    }

</script>

<style scoped>

</style>

newProject.js

require('./bootstrap');

import NewProject from "../../../assets/js/components/Template/NewProject.vue";
import GlobalMixin from "../../../assets/js/mixins/GlobalMixin";

const newProject=new Vue({
    el:'#newProject',
    mixins:[
        GlobalMixin,
    ],
    components:{
        'new-project':NewProject,
    },
    methods:{

    },
    mounted(){

    },
});

new_project.blade.php

@extends('layouts.headless')


@section('content')

    <new-project>

        <template slot="timezone" slot-scope='data'>
            <select v-model="data.selectedId">
                @foreach ($timezone_list['Pacific'] as $key=>$value)
                    <option value="{{$key}}">{!! $value !!}</option>
                @endforeach
            </select>
        </template>

    </new-project>

@stop

Outputs Following

But the value is not getting updated

1 个答案:

答案 0 :(得分:0)

将时区数组作为道具传递给组件,然后使用v-for创建绑定的插槽。我还将在自定义组件上使用v-model将所选时区绑定到父数据属性,这将允许进行响应式更新。

要将PHP数组传递给Vue组件prop:

<timezones :timezones='{!! json_encode($timezone_list['Pacific']) !!}' v-model="selectedTZ">

// Laravel 5.5+ allows using the @json directive
<timezones :timezones=@json($timezone_list['Pacific']) v-model="selectedTZ">

Vue.component('timezones', {
  props: ['timezones', 'value'],
  data: () => ({
    selected: null
  }),
  template: `<div>
<select @change="$emit('input', $event.target.value)">
<option v-for="timezone in timezones" :value="timezone" :key="timezone">
<slot :timezone="timezone"></slot>
</option>
</select>
</div>`
})

new Vue({
  el: '#app',
  data: () => ({
    timezones: [],
    selectedTZ: 'Africa/Abidjan'
  }),
  mounted() {
    this.timezones = moment.tz.names()
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://momentjs.com/downloads/moment.js"></script>
<script src="https://momentjs.com/downloads/moment-timezone-with-data.js"></script>
<div id="app">
  <timezones :timezones="timezones" v-model="selectedTZ">
    <template slot-scope="slotProps">
      <span v-if="slotProps.timezone.startsWith('Africa')"></span>
      <span v-else-if="slotProps.timezone.startsWith('Asia')"></span>
      <span v-else-if="slotProps.timezone.startsWith('America')"></span>
      <span v-else-if="slotProps.timezone.startsWith('Antarctica')">⛄</span>
      <span v-else-if="slotProps.timezone.startsWith('Australia')"></span>
      <span v-else-if="slotProps.timezone === 'Pacific/Fiji'">⭐</span>
      {{ slotProps.timezone }}
    </template>
  </timezones>

  <p>You've selected: {{ selectedTZ }}</p>
</div>