Skip to content

Vue.js and Webwork3

Peter Staab edited this page Jun 21, 2019 · 2 revisions

Vue.js and Webwork3

Webwork3, the new single-page application interface for webwork, is written using the Vue.js javascript framework.

Directory Structure

webwork3       // main directory for webwork3
  dist         // location of index.html and related libraries.  This is filled automatically with webpack.
  src          // source directory of all vue files and related
    mixins     // directory for vue mixins
    App.vue    // the topmost vue component
    main.js    // the main javascript file
    store.js   // the vuex store information
    common.js  // all common constants and functions used throughout the interface. 
    router.js  // information about the vue-router. 
    components // main directory for vue components
      common_components 
      views    // components for ClassListManager, Library, ProblemSetsManager, etc. 

Generic Vue component

All of the vue components in webwork3 are Single-File components that consist of at least two parts. The standard example from the vuejs website is

<template>
  <p>{{ greeting }} World!</p>
</template>

<script>
module.exports = {
  data: function () {
    return {
      greeting: 'Hello'
    }
  }
}
</script>

<style scoped>
p {
  font-size: 2em;
  text-align: center;
}
</style>

which has

  • A template tag which is the html code to render the component
  • A script tag which is where the data and any needed javascript coding for the component is located.
  • A style tag (if needed) that produces any CSS for the page.

A webwork3 component

The following is the vue component for the list of courses, located in src/CourseList.vue

<template>
  <div>
    <b-navbar toggleable="lg" type="dark" id="top-navbar" class="fixed-top" >
      <b-navbar-brand href="#"><img id="wwlogo" src="/webwork3/images/webwork_square.svg"></b-navbar-brand>
      <b-navbar-brand>WeBWorK</b-navbar-brand>
      <b-navbar-brand>List of Courses </b-navbar-brand>
    </b-navbar>
    <b-container>
      <b-row>
        <b-col cols=3>
          <b-list-group>
            <b-list-group-item v-for="course in courses" :key="course">
              <router-link :to="'/courses/' + course + '/login'">{{course}}</router-link>
            </b-list-group-item>
          </b-list-group>
        </b-col>
      </b-row>
    </b-container>
</div>
</template>

<script>
import axios from 'axios'

export default {
  data: function () {
    return {
      courses: []
    }
  },
  created(){
    axios.get("/webwork3/api/courses")
      .then( (response) => {
        this.courses = response.data;
      })
  }
}
</script>

This is a relatively simple component that doesn't contain other user-defined components. It does take advantage of the bootstrap-vue framework and needs the axios library for making and handling http requests:

  • The elements inside the template tag are to be rendered.
    • All elements that start with <b- are bootstrap view elements which are generally wrappers for bootstrap classes, with additional vue-related functionality.
    • Vue allows rendering of arrays or lists with v-for and this generates a b-list-group-item element (for extra styling) for each course.
    • For each course there is a link using router-link. This uses vue-router to handle complicated Single-Page web applications in a way that is natural with different views having different URLs.
  • The <script> tag is for javascript, but needs particular structure for vue.
    • There is a import statement which uses the es6 or ecmascript 6 features. More about how this is handled for non-modern browsers in another page.
    • The data is stored as an object within a function. This is necessary for vue components.
    • The mounted() function (note again this syntax is es6) is run upon mounting this component. Within this, a call is made to /webwork3/api/courses, which calls the backend server running dancer (see [information about the backend)[]). After this returns, it assigns the courses array with the result of the server call.
    • Note: vuejs is responsive in that when data changes, the template responds to update the interface to the change.