Q:

Trying to pull data from Vue components in single file components

This is my first time experimenting with Vue.js so it's altogether possible I'm missing something very obvious.
Basically, I have a component that calculates the number of boxes needed for a certain quantity of a printed piece (I work in the print industry).
If needed, I have a button to create an additional component if the printed piece has multiple parts.
I'd like to have a reactive way to update the total number of boxes needed for all parts, but I just can't seem to get there.
Here's a link to my Gitlab repo with the code: https://gitlab.com/dsross/printutils
Any help would be appreciated.
I'm also using Browserify to write the build.js and build.css files referenced in index.html.
Here are my files, in case no one wants to look at the repo:
App.vue
<template>
  <div id="app">
    <div>
    </div>
    <div>
      <calculator v-for="(part, index) in parts" :key="index"></calculator>
      <br />
      <br />
      <div class="card shadow-sm">
        <div class="card-body">
          <button type="button" class="btn" @click="addPart()">Add Part</button>
          <button type="button" class="btn" @click="totalBoxes">Total Boxes</button>
          <span>Box Total (all parts): </span><span id="grandtotal"></span>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  // import Hello from './components/Hello.vue'
  import Calculator from './components/Calculator.vue'

  export default {
    name: 'app',
    components: {
      Calculator
    },
    methods: {
      addPart: function () {
        console.log("Adding part");
        this.parts.push(Calculator);
      },
      totalBoxes: function () {
        console.log("totalBoxes called");
        let totalBoxes = 0;
        let partTotals = document.querySelectorAll("#partBoxTotal");
        for (var i = 0; i < partTotals.length; i++) {
          totalBoxes += parseInt(partTotals[i].innerHTML);
        }
        this.totalBoxCount = totalBoxes;
        document.getElementById("grandtotal").innerHTML = totalBoxes;
      }
    },
    data: function () {
      return {
        parts: [Calculator],
        totalBoxCount: 0
      }
    },
  }
</script>

Calculator.vue
<template>
    <div class="card shadow-sm" id="boxCalculator">
        <div class="card-body">
            <form>
                <div class="form-group">
                    <p>Paper:
                        <select class="custom-select" v-model="paperWeight">
                            <option v-for="(mweight, paper) in mweights" :key="mweight" v-bind:value="paper">{{paper}}</option>
                        </select>
                    </p>
                    <br />
                    <br />
                    <p>Final Width:
                        <input class="form-control" type="text" v-model="finalWidth" id="finalWidth" value="">
                    </p>
                    <p>Final Height:
                        <input type="text" class="form-control" v-model="finalHeight" id="finalHeight" value="">
                    </p>
                    <p>Sheets Per Unit:
                        <input type="text" class="form-control" v-model="numberOfSheets" id="numberOfSheets" name="numberOfSheets"
                            value="">
                    </p>
                    <p>Quantity:
                        <input type="text" class="form-control" v-model="quantity" id="quantity" name='quantity'>
                    </p>
                    <p>Stitched:
                        <input type="checkbox" v-model="stitched" name="stitched" id="stitched" value="">
                    </p>
                </div>
            </form>
            <div class="card">
                <div class="card-body">
                    <div id='results'>
                        <p id="partWeightTotal">Part Total Weight: {{ totalWeight }}</p>
                        <p><span>Part Box Total: </span><span id="partBoxTotal">{{ boxQuantity }}</span></p>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    import {
        mWeights,
        stitchedMultiplier,
        maxArea
    } from "../constants.js"

    module.exports = {
        data: function () {
            return {
                paperWeight: this.selected,
                paperType: "",
                finalWidth: "",
                finalHeight: "",
                numberOfSheets: "",
                quantity: "",
                stitched: "",
                boxes: "",
                mweights: mWeights
            }
        },
        computed: {
            squareInches: function () {
                return this.finalHeight * this.finalWidth;
            },
            squareInchWeight: function () {
                let mWeight = mWeights[`${this.paperWeight}`];
                return (mWeight / 1000) / maxArea;
            },
            totalWeight: function () {
                return ((this.squareInches * this.squareInchWeight) * this.numberOfSheets) * this.quantity;
            },
            boxQuantity: function () {
                let boxes = this.totalWeight / 35;
                if (this.stitched) {
                    this.boxes = Math.ceil(boxes * stitchedMultiplier);
                    // this.$root.$emit('box-change', this.boxes);
                    return this.boxes
                } else {
                    this.boxes = Math.ceil(boxes);
                    // this.$root.$emit('box-change', this.boxes);
                    return Math.ceil(this.boxes);
                };
            },
        },
    }
</script>

index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>boxcalculator2</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="">
  <meta name="author" content="">
  <link rel="icon" href="../favicon.png">
  <title>Box Calculator</title>
  <!-- Bootstrap core CSS -->
  <link href="dist/css/bootstrap.min.css" rel="stylesheet">
  <!-- Custom styles for this template -->
  <link href="dist/sticky-footer.css" rel="stylesheet">
  <link rel="stylesheet" href="dist/build.css">
</head>

<body>
  <div class="container">
    <div class='row'>
      <div class='col'>
        <div id="app"></div>
      </div>
    </div>
  </div>
  <script src="dist/build.js"></script>
</body>

</html>

A:

If I understand correctly, you'd like the App's total box count to be updated automatically whenever the individual Calculators determine their box counts. One way to do this is to emit an event from Calculator when its box count changes, which could be monitored with a watcher.
There are a couple issues we'll address below:

It doesn't make sense (and is inefficient) to store Calculator -- a single-file-component definition -- in this.parts[]. Instead, it could store meaningful data points, such as Calculator's output.
Instead of DOM manipulation (i.e., querying the DOM for an element to get/set its value), opt for modeling the data in Vue, and using interpolation in the template. This lets Vue automatically display the updated value in the target element. It also obviates the element ID assignments (assuming they were used exclusively for DOM manipulation), simplifying the template for improved readability.

Storing Calculator output
In App, we must use this.parts[] to track the result of each part's calculation (which we'll capture below). We'll define each array element (i.e., a "part") to be:
{
  boxes: 0 // box count for this part
}

This definition allows a computed property (which we'll define later), based on .boxes, to be reactive.
So, in addPart() and the data option:
// App.vue
export default {
  // ...
  methods: {
    addPart() {
      this.parts.push({ boxes: 0 });
    }
  },
  data() {
    return {
      parts: [{ boxes: 0 }]
    }
  }
}

Notifying App of Calculator output
Typically, parents pass data to children via props, and children communicate data to parents with events. Alternatives include using a state management library, such as Vuex, but for the sake of simplicity, we'll use events here.
In Calculator, we want to notify the parent (App) of changes to the boxes value, so we'll add a watcher that emits an event (e.g., called boxes-changed) whenever boxes changes:
// Calculator.vue
export default {
  //...
  watch: {
    boxes(value) {
      this.$emit('boxes-changed', value);
    }
  }
}

In App, we'll listen to the boxes-changed event, and copy the event detail's value to the current part's boxes variable, where part is the current array element of parts[] being iterated.
// App.vue
<calculator v-for="(part, index) in parts" @boxes-changed="part.boxes = $event" :key="index"></calculator>

Breakdown of @boxes-changed="part.boxes = $event":

@boxes-changed="..."    - listen to boxes-changed event emitted from <calculator>
part.boxes = $event     - set part.boxes to value of event detail

Making totalBoxCount reactive
With the changes above, we have the tools needed to make App's totalBoxCount reactive:

Change totalBoxCount into a computed property that sums up the .boxes fields of this.parts[]. This property will be computed automatically whenever array elements of this.parts[] changes. 
 // App.vue
 export default {
   computed: {
     totalBoxCount() {
       // Note: Alternatively, use a simple for-loop to sum .boxes
       return this.parts
               .filter(p => p.boxes && !Number.isNaN(p.boxes) // get only parts that have a positive `.boxes` value
               .map(p => p.boxes)          // map object array into an integer array of `.boxes` values
               .reduce((p,c) => p + c, 0); // sum all array elements
     },
   },
   data() {
     return {
       parts: [],
       // totalBoxCount: 0   // CHANGED INTO COMPTUED PROP ABOVE
     }
   }
 }

In App's template, use string interpolation to display totalBoxCount:
<!-- 
<span>Box Total (all parts): </span><span id="grandtotal"></span>
--> <!-- DON'T DO THIS -->
<span>Box Total (all parts): {{totalBoxCount}}</span>

We might as well remove the Total Boxes button (previously used to manually trigger a calculation) from the template:
<!--
<button type="button" class="btn" @click="totalBoxes">Total Boxes</button>
--> <!-- DELETE -->

and its associated click-handler:
// App.vue
export default {
  methods: {
    // totalBoxes: function() { /* .. */ } // DELETE THIS
  }
}

demo

