【问题标题】:Using v-model inside scoped slots在作用域槽内使用 v-model
【发布时间】:2019-08-08 05:16:40
【问题描述】:

我正在使用带有新 v-slot 语法的 Vue 2.6.9。我想访问与插槽内的 v-model 交互。问题是在插槽内显示数据有效,但使用 v-model 无效。这是我的代码:

Vue.component('base-test', {
  template: `
  <div>
    <slot :foo="foo" :foo2="foo2"></slot>
  </div>
  `,
  data(){
    return{
      foo: 'Bar',
      foo2: 'Bar 2'
    }
  }
});


// Mount
new Vue({
  el: '#app'
});

<div id="app">
  <base-test v-slot="sp">
    <div>foo2 is {{ sp.foo2 }}</div>
    <input type="text" v-model="sp.foo">
    <div>foo is {{ sp.foo }}</div>
  </base-test>
</div>

Codepen

我的问题是如何在插槽内与组件 data 进行交互。

【问题讨论】:

标签: vue.js


【解决方案1】:

关于this 问题,Vue 核心成员说您不应该修改传递给插槽的数据。

您应该传递一个方法来更改值。如果您同意这一点,请关注this 回答。


但是,有一种巧妙的方法可以利用 Javascript 参考值来实现这一目标

您传递一个保持其反应性的反应性对象(例如 Observer、reactiveGetter、reactiveSetter),而不是传递一个原始值(不会有反应性)。

子组件

<template>
  <div class="child">
    <slot :model="model"></slot>
  </div>
</template>

<script>
export default {
  data: () => ({
    model: {
      value: "Initial value",
    },
  }),
};
</script>

父组件

<template>
  <div id="app">
    <Child v-slot="{ model }">
      <input type="text" v-model="model.value" />
    </Child>
  </div>
</template>

<script>
import Child from "./components/Child";

export default {
  components: {
    Child,
  },
};
</script>

See it live on codesandbox.

【讨论】:

    【解决方案2】:

    好的,看来不能直接更改数据。这样做的方法是作为 slot prop 方法传递并基本上重做 v-model:

    <div id="app">
      <base-test v-slot="sp">
        <div>foo2 is {{ sp.foo2 }}</div>
        <input type="text" 
              :value="sp.foo2" @input="event => sp.onInput(event, 'foo2')">
        <div>foo is {{ sp.foo }}</div>
      </base-test>
    </div>
    
    Vue.component('base-test', {
      template: `
      <div>
        <slot :foo="foo" :foo2="foo2" :onInput="onInput"></slot>
      </div>
      `,
      data(){
        return{
          foo: 'Bar',
          foo2: 'Bar 2'
        }
      },
      methods:{
        onInput(event, prop){
          this[prop] = event.target.value;
        }
      }
    });
    
    
    // Mount
    new Vue({
      el: '#app'
    });
    

    Codepen demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-11
      • 2021-08-19
      • 2020-12-26
      • 2021-02-09
      • 2017-08-27
      • 1970-01-01
      相关资源
      最近更新 更多