Skip to content

Extend Template when using Vue.extend() #4665

@purepear

Description

@purepear

Vue.extend() works well but i think there is no way to extend the corresponding template without changing scope. Here is an example of what i'd like to achieve. <block> is like <slot> but i renamed it not to be confused with the current slot implementation

const BaseForm = Vue.extend({
  template: `
    <form>
      <block name="header">
        <h1>{{ title }}</h1>
      </block>
      <block name="content">Form inputs go here</block>
      <block name="actions">
        <button @click="saveRecord">Save</button>
        <button @click="deleteRecord">Delete</button>
      </block>
    </form>
  `,
  data () {
    return {
      title: 'Base Title',
      apiUrl: null,
      record: {}
    }
  },
  methods: {
    saveRecord () {
      // axios.post(this.apiUrl + this.record.id)...
    },
    deleteRecord () {
      // axios.delete(this.apiUrl + this.record.id)...
    }
  }
})

const PersonForm = BaseForm.extend({
  template: `
    <extend>
      <div block="header">
        {{ title }} From Person Form
        <button @click="saveRecord">Save from header</button>
      </div>
      <div block="content">
        <input type="text" v-model="record.name" />
        <input type="text" v-model="record.age" />
        <button @click="incAge">Increase age</button>
      </div>
   </extend>
  `,
  data () {
    return {
      title: 'My Title',
      apiUrl: '/api/my/',
      record: {
        id: 1,
        name: '',
        age: 0
      }
    }
  },
  methods: {
    incAge () {
      this.record.age++
    }
  }
})

So js is merged as usual but then the base template blocks are replaced with the new ones when compiling the template. So everything works within the same scope.
<block> and <extend> can be changed with different words/options in the api

Does this make sense? Or is there a better way to do it? Or is it not intact with Vue principles?

The end results should be:

{
  template: `
    <form>
      <div>
        {{ title }} From Person Form
        <button @click="saveRecord">Save from header</button>
      </div>
      <div>
        <input type="text" v-model="record.name" />
        <input type="text" v-model="record.age" />
        <button @click="incAge">Increase age</button>
      </div>
      <button @click="saveRecord">Save</button>
      <button @click="deleteRecord">Delete</button>
    </form>
  `,
  data () {
    return {
      title: 'My Title',
      apiUrl: '/api/my/',
      record: {
        id: 1,
        name: '',
        age: 0
      }
    }
  },
  methods: {
    incAge () {
      this.record.age++
    },
    saveRecord () {
      // axios.post(this.apiUrl + this.record.id)...
    },
    deleteRecord () {
      // axios.delete(this.apiUrl + this.record.id)...
    }
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions