SharePoint 2013 Modern WebPart (3 of 4)

VueJS WebPart Example

This is the third of four demos giving an overview of creating modern webpart solutions for SharePoint 2013+ environments. The demo code can be found in github. The goal of this post is to give an example of using VueJS, while expanding on the previous post. This is the first time I’ve coded in VueJS, so this should be fun.

Requirements

  • NodeJS – A superset of JavaScript functions. NodeJS allows us to develop code similar to C#, which is compiled into JavaScript.

Create the Project

There is a vue-cli to help create projects, which is very useful, but for this demo I want to do the absolute minimal amount of things to compile the project.

mkdir demo-wp-vuejs
cd demo-wp-vuejs
npm i --y

I selected ‘no’ to all questions and selected ‘npm’ to install after the wizard completes.

Install Libraries

  • gd-sprest – The library used to create the webpart
  • VueJS – The VueJS library
    • css-loader is required for compiling the css to JavaScript
    • vue-loader – Used to compile the VueJS code to JavaScript
    • vue-template-compiler – Since the sample code is using a template, we will need to include this library
npm i --save gd-sprest vue
npm i --save-dev css-loader vue-loader vue-template-compiler webpack

Source Code

Create a “src” folder and add the following files

SharePoint Configuration (src/cfg.ts)

Since the previous demo included the list configuration, we will leave it out of this demo.

import { Helper, List, SPTypes, Types } from "gd-sprest";

/**
 * Configuration
 */
export const Configuration = {
    // WebPart
    WebPart: new Helper.SPConfig({
        WebPartCfg: [
            {
                FileName: "wpContacts_vuejs.webpart",
                Group: "Demo",
                XML: `<?xml version="1.0" encoding="utf-8"?>
<webParts>
    <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
        <metaData>
            <type name="Microsoft.SharePoint.WebPartPages.ScriptEditorWebPart, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
            <importErrorMessage>$Resources:core,ImportantErrorMessage;</importErrorMessage>
        </metaData>
        <data>
            <properties>
                <property name="Title" type="string">My Contacts (VueJS)</property>
                <property name="Description" type="string">Demo displaying my contacts.</property>
                <property name="ChromeType" type="chrometype">TitleOnly</property>
                <property name="Content" type="string">
                    &lt;script type="text/javascript" src="/sites/dev/siteassets/demo-vue.js"&gt;&lt;/script&gt;
                    &lt;div id="wp-contacts-vuejs"&gt;&lt;/div&gt;
                    &lt;script type="text/javascript"&gt;SP.SOD.executeOrDelayUntilScriptLoaded(function() { VueJSDemo.init(); }, 'demo-vue.js');&lt;/script&gt;
                </property>
            </properties>
        </data>
    </webPart>
</webParts>`
            }
        ]
    })
};
Main (src/index.ts)

The main source will create a global variable and use the SharePoint Script-On-Demand to notify the webpart when the library has been loaded. The initialize method will create an instance of the webpart. If we are displaying the data, then we will render the Vue application.

import { Helper } from "gd-sprest";
import Vue from "vue"
import { Configuration } from "./cfg";
import WebPart from "./wp"

/**
 * Vue JS Demo
 */
window["VueJSDemo"] = {
    // Configuration
    Configuration: Configuration,

    // Initialize the webpart
    init: function () {
        // Create an instance of the webpart
        new Helper.WebPart({
            elementId: "wp-contacts-vuejs",
            onRenderDisplay: (wp) => {
                /* Render the webpart */
                new Vue({
                    el: wp.el,
                    template: '<WebPart />',
                    components: { WebPart }
                });
            },
            onRenderEdit: (wp) => {
                // Render a message
                wp.el.innerHTML = "<h2>The page is being edited...</h2>";
            }
        });
    }
};

// Let SharePoint know the script has been loaded
SP.SOD.notifyScriptLoadedAndExecuteWaitingJobs("demo-vue.js");
WebPart (src/wp.vue)

This is my first attempt at VueJS, and I wanted to demo something other than “Hello World!”. My assumption is that most people will use the vue-cli to generate the project which includes the ability to work in the localhost environment. The code below has sample data, so when you are working in “localhost” the test data will be loaded.

<template>
  <div id="webpart">
    <div class="table">
      <template v-for="item in items">
        <div class="row">
          <div>{{ item.MCCategory }}</div>
          <div>{{ item.Title }}</div>
          <div>{{ item.MCPhoneNumber }}</div>
        </div>
      </template>
    </div>
  </div>
</template>

<script>
import { ContextInfo, List } from "gd-sprest";
export default {
  name: "WebPart",
  data: function() {
    return {
      items: []
    };
  },
  created: function() {
    // See if the environment exists
    if (ContextInfo.existsFl) {
      let wp = this;

      // Get the list
      new List("My Contacts")
        // Get the items
        .Items()
        // Execute the results
        .execute(function(items) {
          // Update the items
          wp.items = items.results;
        });
    } else {
      // Use test data
      wp.items = [
        {
          MCCategory: "Business",
          MCPhoneNumber: "111-111-1111",
          Title: "John A. Doe"
        },
        {
          MCCategory: "Business",
          MCPhoneNumber: "222-222-2222",
          Title: "John B. Doe"
        },
        {
          MCCategory: "Family",
          MCPhoneNumber: "333-333-3333",
          Title: "John C. Doe"
        },
        {
          MCCategory: "Family",
          MCPhoneNumber: "444-444-4444",
          Title: "John D. Doe"
        },
        {
          MCCategory: "Personal",
          MCPhoneNumber: "555-555-5555",
          Title: "John E. Doe"
        },
        {
          MCCategory: "Personal",
          MCPhoneNumber: "666-666-6666",
          Title: "John F. Doe"
        }
      ];
    }
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.row {
  display: flex;
  justify-content: center;
}

.row > div {
  padding: 5px 10px;
}

.row > div:first-child {
  color: #42b983;
}
</style>

Compiler Configuration Files

Before we are able to compile the files, we need to update the configuration files.

Package (package.json)

Update the “scripts” and the “build” option. This will allow us to type in “npm run build” to compile the code.

  "scripts": {
    "build": "webpack"
  }
WebPack (webpack.config.js)

The webpack configuration file is similar to others I’ve created in the past, but this one required me to set the “alias”.

var path = require('path');
var webpack = require("webpack");

module.exports = {
    // Target the output of the typescript compiler
    context: path.join(__dirname, "src"),

    // File to target
    entry: './index.js',

    // Output
    output: {
        filename: 'demo-vue.js',
        path: path.resolve(__dirname, 'dist')
    },

    // Resolve the file extensions
    resolve: {
        alias: {
            vue: "vue/dist/vue.js"
        },
        extensions: [".js", ".vue"]
    },

    // Module to define what libraries with the compiler
    module: {
        // Loaders
        loaders: [
            {
                // Target the vue files
                test: /\.vue$/,
                // Exclude the npm libraries
                exclude: /node_modules/,
                // Define the compiler to use
                use: [
                    {
                        // Compile the vue code to JavaScript
                        loader: "vue-loader"
                    }
                ]
            }
        ]
    }
};
Compile the Code

Run ‘npm run build’ or ‘webpack’ to compile the code and create the ‘demo-vue.js’ file located in the dist folder.

Demo

Step 1 – Create Demo Page

1) Upload the file to SharePoint
2) Create a webpart page of your choice
3) Access the page

Step 2 – Install the WebPart

1) Press F-12 to access the developer tools
2) Click on the “Console” tab
3) Reference the script – We will use simple javascript to insert a script link into the page. Afterwards, our library will be available.

var s = document.createElement("script");
s.src = "/sites/dev/siteassets/demo-vue.js";
document.head.appendChild(s);

4) Install the webpart

VueJSDemo.Configuration.WebPart.install()

This part may take a little time to initialize, depending on the size of the web.

Step 3 – Test

1) Edit the page
2) Click on a webpart zone to add a new webpart
3) From the webpart gallery, select the “Demo” group “My Contacts (VueJS)” webpart

4) After the page reloads, you will see the edit message

5) Save the page, and you will see the contact list

Step 4 – Clean Up

1) Press F-12 to access the developer tools
2) Click on the “Console” tab
3) Uninstall the list and webpart

VueJSDemo.Configuration.WebPart.uninstall()

This part may take a little time to initialize, depending on the size of the web.

Output Size

One thing to note, is the output file size (uncompressed) is about 639KB. This is much smaller than the react/fabric-ui demo we just created, but it’s important to note that the react demo also included the Office Fabric UI library on top of the react library.

Conclusion

I hope this post was useful for using the VueJS framework. In the next post we will explore AngularJS framework.

1 thought on “SharePoint 2013 Modern WebPart (3 of 4)”

Comments are closed.