简体   繁体   中英

How can I specify a binding context in Vue.js just like in knockout.js and WPF

We are using Vue.js , very nice framework if you ask me. From Knockout.js and WPF I know that a context can be specified for the bindings. How can this be done with Vue.js?

See the example below. Here binding-context is pseudo code for the functionality I am looking for in Vue.

Vue.component('hosting-setup', {
template:
    '<wizard>' +
        '<wizard-step binding-context="step1" :title="title">' +
            '<select :options="choices"></select>' +
        '</wizard-step>' +
        '<wizard-step binding-context="step2" :title="title">' +
            '<select :options="choices"></select>' +
        '</wizard-step>' +
    '</wizard>',

    data: function () {
        return {
            step1: {
                title: 'Choose virtualization software',
                choices: ['Virtual Box', 'VMWare'],
                choice: undefined,
            },
            step2: {
                title: 'Choose guest operating system',
                choices: ['Debian 6', 'Ubuntu 16', 'Windows Server 2012'],
                choice: undefined
            }
        };
    }
});

There is no "with" binding equivalent in Vue . There are a few approaches for what you want to do, but for your example I would use a computed to return your data as an array and then use v-for to print out each component passing the relevant data as a prop:

Vue Instance

Vue.component('wizard-step', {
  template: `<div>{{title}}</div>`,
  props: ['title']
});

new Vue({
  el: '#app',
  computed: {
    wizardSteps() {
      return [this.step1, this.Step2]
    }
  },
  data() {
    return {
      step1: {
        title: 'Choose virtualization software',
        choices: ['Virtual Box', 'VMWare'],
        choice: undefined,
      },
      Step2: {
        title: 'Choose guest operating system',
        choices: ['Debian 6', 'Ubuntu 16', 'Windows Server 2012'],
        choice: undefined
      }
    };
  }
})

Markup

  <wizard-step :title="step.title" v-for="(step, index) in wizardSteps" :key="index"></wizard-step>

Here's the JSFiddle: http://jsfiddle.net/craig_h_411/vzq25go5/

EDIT

If you want to pass the data down to the component directly, you can use v-bind to pass the object and declare the object property names you want to use in the component as props , which maybe gets closer to what you are asking for, so:

Vue.component('wizard-step', {
  template: `<div>
    {{title}}
    <select>
      <option v-for="choice in choices" >{{choice}}</option> 
    </select>
  </div>`,
  props: ['title','choices']
});

Parent markup

  <wizard-step v-bind="step1"></wizard-step>
  <wizard-step v-bind="Step2"></wizard-step>

Here's the JSFiddle for that: http://jsfiddle.net/craig_h_411/7dg41j0w/

If you have really nested child, can try to cheat using v-for with 1 item array.

<template v-for="local in [data.nest1.nest2.nest3]">
    //normal binding using local.XXXX
</template>

Tested in Vue 2.6.10:

<template>
    <wizard>
        <wizard-step v-if="props.step1 ? step = props.step1 : false" :title="step.title">
            <select :options="step.choices"></select>
        </wizard-step>
        <wizard-step v-if="props.step2 ? step = props.step2 : false" :title="step.title">
            <select :options="step.choices"></select>
        </wizard-step> 
    </wizard>
</template>

NOTE: Even better, for more concise code you could create a sub-component just for and pass title and options:

Ie

<template>
    <wizard>
        <wizard-step v-if="props.step1" :step="props.step1" />
        <wizard-step v-if="props.step2" :step="props.step2" />
    </wizard>
</template>

and your child wizard-step will be:

<template>
    <wizard-step :title="step.title">
        <select :options="step.choices"></select>
    </wizard-step>
</template>

And another improvement, if you are in control on how the data returned is structured, you could return an array of steps (instead of step1 and step2), and you could just simplify further with a for-each:

<template>
    <wizard>
        <wizard-step v-for="step in props.data" :step="step" />
    </wizard>
</template>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM