How to separate methods from MyLayout.vue to a mixin.js?



  • MyLayout.vue

    <template>
    ...
    
        <q-layout-drawer
          v-model="leftDrawerOpen"
          :content-class="$q.theme === 'mat' ? 'bg-grey-2' : null"
        >
          <q-list no-border link inset-delimiter>
            <q-list-header>Listas de tareas</q-list-header>
            <q-item v-for="list of lists" :key="list._id" 
              :class="{active:list._id == selected}" @click.native="selected = list._id">
              <q-item-main :label="list.title" />
              <q-item-side right icon="delete" 
              v-if="selected == list._id"
              @click.native="deleteList(selected)"/>
            </q-item>
            <q-item>
              <q-item-main>
                <q-input v-model.trim="list.title" placeholder="+ Nueva lista" @keyup.enter="sendList"/>
              </q-item-main>
              <q-item-side right icon="format_color_fill">
                <q-popover>
                  <q-color-picker v-model="list.color"/>
                </q-popover>
              </q-item-side>
            </q-item>
          </q-list>
        </q-layout-drawer>
    
        <q-page-container>
          <router-view />
        </q-page-container>
      </q-layout>
    </template>
    
    <script>
    import { openURL } from 'quasar'
    
    class List {
      constructor(title = '', color = '') {
        this.title = title;
        this.color = color;
      }
    }
    
    export default {
      name: 'MyLayout',
      data () {
        return {
          leftDrawerOpen: this.$q.platform.is.desktop,
          list: new List(),
          lists: [],
          selected: undefined,
        }
      },
      created() {
        this.getLists();
      },
        methods: {
            openURL,
            submit () {
              return
            },
            sendList() {
            if(this.list.title == '') { return }
            else {
              fetch('http://localhost:3000/api/lists', {
                method: 'POST',
                body: JSON.stringify(this.list),
                headers: {
                  'Accept': 'application/json',
                  'Content-Type': 'application/json'
                }
              })
                .then(res => res.json())
                .then(data => {
                  this.getLists();
                  this.list = new List();
                });
            }
            },
    
          getLists() {
            fetch('http://localhost:3000/api/lists')
              .then(res => res.json())
              .then(data => {
                this.lists = data;
              });
          },
    
          deleteTask(listId) {
            fetch('http://localhost:3000/api/lists/' + listId, {
              method: 'DELETE',
              headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
              }
            })
              .then(res => res.json())
              .then(data => {
                this.getLists();
              });
          },
        }
    }
    </script>
    

    I want to separate the methods in a mixin.js, I tried this:
    mixins.js

    export default {
      created: function() {
        this.getLists();
      },
      methods: {
        sendList: function() {
          if(this.list.title == '') { return }
          else {
            fetch('http://localhost:3000/api/lists', {
              method: 'POST',
              body: JSON.stringify(this.list),
              headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
              }
            })
              .then(res => res.json())
              .then(data => {
                this.getLists();
                this.list = new List();
              });
          }
        },
    
        getLists: function() {
          fetch('http://localhost:3000/api/lists')
            .then(res => res.json())
            .then(data => {
              this.lists = data;
            });
        },
    
        deleteList: function(listId) {
          fetch('http://localhost:3000/api/lists/' + listId, {
            method: 'DELETE',
            headers: {
              'Accept': 'application/json',
              'Content-Type': 'application/json'
            }
          })
            .then(res => res.json())
            .then(data => {
              this.getLists();
            });
        },
      }
    }
    

    I have this error (twice, like if the mixins runs two times don’t know why)

    Property or method “lists” is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.

    It seems that if I put the methods in an external file it can not receive the data. I have also tried adding the following data to mixins.js before the methods:

    data () {
        return {
          list: new List(),
          lists: [],
          selected: undefined,
        }
      },
    

    but I get many more mistakes still

    in MyLayout.vue

    Error in data(): “ReferenceError: List is not defined”

    Property or method “leftDrawerOpen” is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.

    Property or method “lists” is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.

    Error in render: “TypeError: Cannot read property ‘title’ of undefined”

    TypeError: Cannot read property ‘title’ of undefined

    in mixins.js

    List is not defined



  • You probably need a bit of reading about mixins in the vue js doc. In your component mixins: [MyMixin].



  • My error was not in mixins.js, neither in MyLayout.vue, but in index.vue



  • glad you fixed it on your own, the code you presented is vague to have known which was which :).


Log in to reply