<?xml version="1.0" encoding="utf-8"?>
<!-- generator="Kirby" -->
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">

  <channel>
    <title>Mot-cl&#233;: vuejs &#183; Blog &#183; Liip</title>
    <link>https://www.liip.ch/fr/blog/tags/vuejs</link>
    <generator>Kirby</generator>
    <lastBuildDate>Tue, 09 Oct 2018 00:00:00 +0200</lastBuildDate>
    <atom:link href="https://www.liip.ch" rel="self" type="application/rss+xml" />

        <description>Articles du blog Liip avec le mot-cl&#233; &#8220;vuejs&#8221;</description>
    
        <language>fr</language>
    
        <item>
      <title>From coasters to Vuex</title>
      <link>https://www.liip.ch/fr/blog/from-coasters-to-vuex</link>
      <guid>https://www.liip.ch/fr/blog/from-coasters-to-vuex</guid>
      <pubDate>Tue, 09 Oct 2018 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>You'll take a coaster and start calculating quickly. All factors need to be taken into account as you write down your calculations on the edge of the coaster. Once your coaster is full, you'll know a lot of answers to a lot of questions: How much can I offer for this piece of land? How expensive will one flat be? How many parking lots could be built and how expensive are they? And of course there's many more.</p>
<h2>In the beginning, there was theory</h2>
<p>Architecture students at the ETH learn this so-called &quot;coaster method&quot; in real estate economics classes. Planning and building a house of any size is no easy task to begin with, and neither is understanding the financial aspect of it. To understand all of those calculations, some students created spreadsheets that do the calculations for them. This is prone to error. There are many questions that can be answered and many parameters that influence those answers. The ETH IÖ app was designed to teach students about the complex correlations of different factors that influence the decision. Furthermore, if building a house on a certain lot is financially feasible or not.</p>
<figure><figure><img src="https://liip.rokka.io/www_inarticle/0c0b57/spreadsheet.jpg" alt=""></figure><figcaption>The spreadsheet provided by the client PO</figcaption></figure>
<p>The product owner at ETH, a lecturer for real estate economics, took the tome to create such speadsheets, much like the students. These spreadsheets contained all calculations and formulas that were part of the course, as well as some sample calculations. After a thorough analysis of the spreadsheet, we came up with a total of about 60 standalone values that could be adjusted by the user, as well as about 45 subsequent formulas that used those values and other formulas to yield yet another value.</p>
<p>60 values and 45 subsequent formulas, all of them calculated on a coaster. Implementing this over several components would end up in a mess. We needed to abstract this away somehow.</p>
<h2>Exploring the technologies</h2>
<p>The framework we chose to build the frontend application with, was Vue. We used Vue to build a prototype already. so we figured we could reuse some components. We already valued Vue's size and flexibility and were somewhat familiar with it, so it was a natural choice. There's two main possibilities of handling your data when working with Vue: Either manage state in the components, or in a state machine, like Vuex.</p>
<p>Since many of the values need to be either changed or displayed in different components, keeping the state on a component level would tightly couple those components. This is exactly what is happening in the spreadsheet mentioned earlier. Fields from different parts of the sheet are referenced directly, making it hard to retrace the path of the data.</p>
<figure><figure><img src="https://liip.rokka.io/www_inarticle/431b52/components-coupled.jpg" alt=""></figure><figcaption>A set of tightly coupled components. Retracing the calculation of a single field can be hard.</figcaption></figure>
<p>Keeping the state outside of the components and providing ways to update the state from any component decouples them. Not a single calculation needs to be done in an otherwise very view-related component. Any component can trigger an update, any component can read, but ultimately, the state machine decides what happens with the data.</p>
<figure><figure><img src="https://liip.rokka.io/www_inarticle/373d8b/components-decoupled.jpg" alt=""></figure><figcaption>By using Vuex, components can be decoupled. They don't need state anymore.</figcaption></figure>
<p>Vue has a solution for that: Vuex. Vuex allows to decouple the state from components, moving them over to dedicated modules. Vue components can commit mutations to the state or dispatch actions that contain logic. For a clean setup, we went with Vuex.</p>
<h2>Building the Vuex modules</h2>
<p>The core functionality of the app can be boiled down to five steps:</p>
<ol>
<li>Find the lot - Where do I want to build?</li>
<li>Define the building - How large is it? How many floors, etc.?</li>
<li>Further define any building parameters and choose a reference project - How many flats, parking lots, size of a flat?</li>
<li>Get the standards - What are the usual prices for flats and parking lots in this region?</li>
<li>Monetizing - What's the net yield of the building? How can it be influenced?</li>
</ol>
<p>Those five steps essential boil down to four different topics:</p>
<ol>
<li>The lot</li>
<li>The building with all its parameters</li>
<li>The reference project</li>
<li>The monetizing part</li>
</ol>
<p>These topics can be treated as Vuex modules directly. An example for a basic module <code>Lot</code> would look like the the following:</p>
<pre><code class="language-javascript">// modules/Lot/index.js

export default {
  // Namespaced, so any mutations and actions can be accessed via `Lot/...`
  namespaced: true,

  // The actual state: All fields that the lot needs to know about
  state: {
    lotSize: 0.0,
    coefficientOfUtilization: 1.0,
    increasedUtilization: false,
    parkingReductionZone: 'U',
    // ...
  }
}</code></pre>
<p>The fields within the state are some sort of interface: Those are the fields that can be altered via mutations or actions. They can be considered a &quot;starting point&quot; of all subsequent calculations.</p>
<p>Those subsequent calculations were implemented as getters within the same module, as long as they are still related to the <code>Lot</code>:</p>
<pre><code class="language-javascript">// modules/Lot/index.js

export default {
  namespaced: true,

  state: {
    lotSize: 0.0,
    coefficientOfUtilization: 1.0
  },

  // Getters - the subsequent calculations
  getters: {
    /**
     * Unit: m²
     * DE: Theoretisch realisierbare aGF
     * @param state
     * @return {number}
     */
    theoreticalRealizableCountableFloorArea: state =&gt; {
      return state.lotSize * state.coefficientOfUtilization
    },

    // ...
  }
}</code></pre>
<p>And we're good to go. Mutations and actions are implemented in their respective store module too. This makes the part of the data actually changing more obvious.</p>
<h2>Benefits and drawbacks</h2>
<p>With this setup, we've achieved several things. First of all, we separated the data from the view, following the &quot;separation of concerns&quot; design principle. We also managed to group related fields and formulas together in a domain-driven way, thus making their location more predictable. All of the subsequent formulas are now also unit-testable. Testing their implementation within Vue components is harder as they are tightly coupled to the view. Thanks to the mutation history provided by the Vue dev tools, every change to the data is traceable. The overall state of the application also becomes exportable, allowing for an easier implementation of a &quot;save &amp; load&quot; feature. Also, reactivity is kept as a core feature of the app - Vuex is fast enough to make any subsequent update of data virtually instant.</p>
<p>However, as with every architecture, there's also drawbacks. Mainly, by introducing Vuex, the application is getting more complex in general. Hooking the data to the components requires a lot of boilerplating - otherwise it's not clear which component is using which field. As all the store modules need similar methods (f.e. loading data or resetting the entire module) there's also a lot of boilerplating going on. Store modules are tightly coupled with each other by using fields and getters of basically all modules.</p>
<p>In conclusion, the benefits of this architecture outweigh the drawbacks. Having a state machine in this kind of application makes sense.</p>
<h2>Takeaway thoughts</h2>
<p>The journey from the coasters, to the spreadsheets, to a whiteboard, to an actual usable application was thrilling. The chosen architecture allowed us to keep a consistent set up, even with growing complexity of the calculations in the back. The app became more testable. The Vue components don't even care anymore about where the data is from, or what happens with changed fields. Separating the view and the model was a necessary decision to avoid a mess and tightly coupled components - the app stayed maintainable, which is important. After all, the students are using it all the time.</p>]]></description>
                  <enclosure url="http://liip.rokka.io/www_card_2/09cc96/coasters.jpg" length="5389277" type="image/jpeg" />
          </item>
        <item>
      <title>Deploy your Nuxt.js app to platform.sh</title>
      <link>https://www.liip.ch/fr/blog/deploy-your-nuxt-js-app-to-platform-sh</link>
      <guid>https://www.liip.ch/fr/blog/deploy-your-nuxt-js-app-to-platform-sh</guid>
      <pubDate>Mon, 06 Aug 2018 00:00:00 +0200</pubDate>
      <description><![CDATA[<p><a href="https://nuxtjs.org/">Nuxt.js</a> is Vue's version of Next.js for React. It's a &quot;framework for creating Universal Vue.js Applications.&quot; Getting  started with Nuxt.js is rather straight forward, the guides help a lot. <a href="https://platform.sh/">platform.sh</a> is a cloud hosting provider we use a lot at Liip. Configuring platform.sh to serve any kind of app is also pretty straight forward, as there's a lot of guides for all kinds of apps. </p>
<p>I started building a microsite. Nothing too fancy. As I was familiar with Vue, I wanted to give Nuxt.js a try and created this app as a single page application. So I created a skeleton of the app, included a header, a bit of navigation and an image or two and was ready to deploy the first version of it somewhere, so stakeholders could actually have a look at it. I've already used platform.sh for various other apps before, so I figured it would be fit for a Vue SPA.</p>
<p>Since this was my first Nuxt.js app, I tried to figure out how to deploy it to platform.sh, but didn't find any resources. I decided to share the steps and config needed in order to deploy it.</p>
<h2>Vue rendered</h2>
<p><a href="https://nuxtjs.org/guide/commands#production-deployment">Nuxt's documentation</a> is pretty straight forward when it comes to deployment. There's essentially three commands that need to be run in order to get a fresh copy of a Nuxt app running:</p>
<pre><code class="language-bash">npm install
npm run build
npm start</code></pre>
<p>And these commands are exactly what is needed in order to deploy the app. Most important: <em>There's no need for any special Nuxt config.</em> The out-of-the-box config should be enough.</p>
<p>To configure an app for platform.sh, there's three files needed:</p>
<ul>
<li><code>./.platform/routes.yaml</code> - Available routes for the app</li>
<li><code>./.platform/services.yaml</code> - Attached services, such as databases, search platforms, etc.</li>
<li><code>./.platform.app.yaml</code> - The main configuration file</li>
</ul>
<p>First of all, the app must be configured. I'll call the app <code>node</code>, use a <code>node:8.11</code> as its type and give it 128M disk space:</p>
<pre><code class="language-yaml"># .platform.app.yaml

name: node
type: nodejs:8.11
disk: 128</code></pre>
<p>Now the build process needs to be added. This is done by adding a build hook:</p>
<pre><code class="language-yaml"># .platform.app.yaml

name: node
type: nodejs:8.11
disk: 128

# Build hook
hooks:
  build: |
    npm install
    npm run build</code></pre>
<p>Afterwards, platform.sh needs to know how to start the app and what kind of locations it needs to serve. The finished <code>.platform.app.yaml</code> now looks like the following:</p>
<pre><code class="language-yaml"># .platform.app.yaml

name: node
type: nodejs:8.11
disk: 128

# Build hook
hooks:
  build: |
    npm install
    npm run build

# Web config
web:
  commands:
    start: npm start
  locations:
    '/':
      passthru: true</code></pre>
<p>In the file <code>.platform/routes.yaml</code>, we also need to add a default route that passes everything it receives straight to the Nuxt process: </p>
<pre><code class="language-yaml"># .platform/routes.yaml

"https://{default}/":
    type: upstream
    upstream: "node:http"</code></pre>
<p>The file <code>.platform/services.yaml</code> can be left empty.</p>
<p>That's it. Now we can go on to deploy the Nuxt app to platform.sh:</p>
<pre><code class="language-bash">git remote add platform [...]
git push -u platform</code></pre>
<h2>Static pages</h2>
<p>Static pages function a bit differently. They are generated by Nuxt during the build process and are served as static files by platform.sh. A starting point for such a configuration can be found in the <a href="https://docs.platform.sh/configuration/app/web.html#how-can-i-serve-a-static-only-site">platform.sh documentation</a>.</p>
<p>A little bit of adjustment is needed, though.</p>
<p>The same starting config for name, type and disk size can be used:</p>
<pre><code class="language-yaml"># .platform.app.yaml

name: node
type: nodejs:8.11
disk: 128</code></pre>
<p>Now, instead of running <code>npm run build</code> in the build hook, we let Nuxt generate static files via <code>npm run generate</code>:</p>
<pre><code class="language-yaml"># .platform.app.yaml

name: node
type: nodejs:8.11
disk: 128

hooks:
  build: |
    npm install
    npm run generate</code></pre>
<p>... and let platform.sh serve everything in the <code>dist/</code> folder as a static page:</p>
<pre><code class="language-yaml"># .platform.app.yaml

name: node
type: nodejs:8.11
disk: 128

hooks:
  build: |
    npm install
    npm run generate

web:
  commands:
    start: sleep infinity
  locations:
    '/':
      root: dist
      index:
         - index.html
      rules:
          \.(css|js|gif|jpe?g|png|ttf|eot|woff2?|otf|html|ico|svg?)$:
              allow: true
          ^/robots\.txt$:
              allow: true</code></pre>
<p>Note the start command: by letting the whole app sleep for an infinite amount of time, we're not actually executing anything. Only the static files are served.</p>
<p>The files <code>.platform/routes.yaml</code> can stay the same:</p>
<pre><code class="language-yaml"># .platform/routes.yaml

"https://{default}/":
    type: upstream
    upstream: "node:http"</code></pre>
<p>Also, the file <code>.platform/services.yaml</code> stays empty. The actual deployment then happens the same way:</p>
<pre><code class="language-bash">git remote add platform [...]
git push -u platform</code></pre>
<h2>Takeaway thoughts</h2>
<p>Platform.sh and Nuxt.js really play well together. Combining the two was less complex than I originally thought and the sheer speed of both make development, for me, loads of fun. Almost as much fun as sharing knowledge and learning new things.</p>]]></description>
                  <enclosure url="http://liip.rokka.io/www_card_2/251b6d/business-cargo-cargo-container-163726.jpg" length="2708320" type="image/jpeg" />
          </item>
        <item>
      <title>Hacking with Particle server and spark firmware</title>
      <link>https://www.liip.ch/fr/blog/hacking-particle-server-spark-firmware</link>
      <guid>https://www.liip.ch/fr/blog/hacking-particle-server-spark-firmware</guid>
      <pubDate>Fri, 02 Sep 2016 00:00:00 +0200</pubDate>
      <description><![CDATA[<h2>The particle server</h2>
<p>In my previous <a href="https://blog.liip.ch/archive/2016/08/03/music-dance-web-technologies.html">blog post</a>, I wrote about the concept of <a href="https://github.com/JordanAssayah/MVM">my project</a> using particle. Now I will explain what I had to do to increase the data rate transfer of my modules (remember, my goal is to get data  with the closest data transfer of 1 [ms] ).</p>
<p>First, I installed the local Api server ( <a href="https://github.com/spark/spark-server">github.com/spark/spark-server</a>). </p>
<p>Then I had to register all of my photon's public key on my server and the server public key on my photons.</p>
<p>Using this command :</p>
<pre><code>particle keys server local_server_key.pub.pem IP_ADDRESS</code></pre>
<p>Then, I launched the server to see if my photons were responding with something like this :</p>
<pre><code>Connection from: 192.168.1.159, connId: 1
on ready { coreID: '48ff6a065067555008342387',
 ip: '192.168.1.159',
 product_id: 65535,
 firmware_version: 65535,
 cache_key: undefined }
Core online!</code></pre>
<p>So from here all was working fine but what I also needed to use there is JS library to get data from OAuth. The thing is that you have to do a lot of configurations if you want to make it works but in this project it was not the goal. I had to test as quickly as possible. So I did what you usually do not have to do with a library installed via npm.</p>
<p>In the file “node_modules/particle-api-js/lib/Default.js” I replaced :</p>
<pre><code>'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

exports.default = {
    baseUrl: 'https://api.particle.io',
    clientSecret: 'particle-api',
    clientId: 'particle-api',
    tokenDuration: 7776000 
};

module.exports = exports['default'];
//# sourceMappingURL=Defaults.js.map</code></pre>
<p>By :</p>
<pre><code>'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

exports.default = {
    baseUrl: 'https://localhost:8080',
    clientSecret: 'particle',
    clientId: 'particle',
    tokenDuration: 7776000 
};

module.exports = exports['default'];
//# sourceMappingURL=Defaults.js.map</code></pre>
<p>And then you have a server where you can create OAuth users accounts and use them from a local app.</p>
<h2>The spark firmware</h2>
<p>The second part is about the firmware of the photon. In the spark protocol library, I had to remove some <a href="https://github.com/spark/firmware/blob/v0.5.2/communication/src/spark_protocol.cpp#L483">lines of code</a> that was fixing a data limit rate per second.</p>
<p>So removed those lines :</p>
<pre><code>if (now - recent_event_ticks[evt_tick_idx] &lt; 1000) {
   // exceeded allowable burst of 4 events per second
   return false;
}</code></pre>
<p>And finally the longest part of the whole thing was to build a complete and clean firmware and upload it to the photon without breaking it (with a bad firmware uploaded to the device, electronic components burn).</p>
<p>So you have to install <a href="http://dfu-util.sourceforge.net/">dfu utils</a>, put your photon in dfu mode and follow the next steps : </p>
<ul>
<li>Within the “firmware/main” folder, type </li>
</ul>
<pre><code>make clean all PLATFORM=photon program-dfu</code></pre>
<p>It will generate the new firmware and will upload it to the photon.</p>
<ul>
<li>Restart you local server</li>
<li>Test the code you want to use and see a very big difference ( about 20 / 30 [ms] to send, receive and process data. Before it was 70 / 80 [ms] )</li>
</ul>
<p>So from here you can get what you want. You just have an idea in your head and you can transform your “local” projects by a “wireless” projects ;)</p>
<p>In conclusion it's a bit complicated to configure the environment to use the API in a local network but it let's you use and remove all unnecessary code processing  to have the best performances.</p>
<p>The web api that <a href="https://www.particle.io/">particle.io</a> offers is really great ! It's really simple to use. Another alternative would be to use TCP / UDP protocols and launch a server that is listening to a defined port (about 50 / 60 [ms] to send, receive and process data but with some lag).</p>
<p>Another goal to this post was to record a little demo video. Unfortunately, my app is not finished but I'll release on my <a href="https://www.youtube.com/channel/UCLQGLUROLHiRdpLe-wRwIsQ">youtube channel</a> the video when my app will work ! So stay tuned ;)</p>]]></description>
                  <enclosure url="http://liip.rokka.io/www_card_2/4be82c44ac13eb673812adc58f66189614905498/12711026-1154414194578531-30521974511740211-o.jpg" length="206242" type="image/jpeg" />
          </item>
        <item>
      <title>When music and dance meet web technologies</title>
      <link>https://www.liip.ch/fr/blog/music-dance-web-technologies</link>
      <guid>https://www.liip.ch/fr/blog/music-dance-web-technologies</guid>
      <pubDate>Wed, 03 Aug 2016 00:00:00 +0200</pubDate>
      <description><![CDATA[<h2>Who am I ?</h2>
<p>I'm Jordan Assayah, I am 18 years old and am currently working at Liip as a trainee from February 1st to August 31st. My main job is to work in a team and develop new functionalities for the zebra project. I'm also a dancer (especially a tap dancer) and love music. Every year since ~ 4 / 5 years , I go to the tapdance world championships to represent Switzerland.</p>
<h2>Personal project</h2>
<p>After 4 months of really nice integration in the team, I've asked to David J. if it was possible to restart a project that I was developing at home. The main goal of the project is to produce music over WIFI with little and cheap modules (because I'm a student) that you can put on your shoes and control the whole thing from a web application where you can choose sounds for sensors, the velocity, the volume, etc.</p>
<p>I was searching for good and cheap modules for a long time and I finally found something : <a href="http://www.particle.io">ParticleIO</a>. They sell WIFI and GSM modules arduino compatible. The perfect microcontroller for the project. So I've bought two of <a href="https://www.particle.io/products/hardware/photon-wifi-dev-kit">those</a> and try to use them. The cool thing about it is that there are multiple tools like a Particle CLI, a dashboard to sniff data, an online IDE (little bit weird, I know), a Particle JS library, an IOS and Android SDK, a firmware documentation and the best for the end, a <a href="https://github.com/spark/spark-server">local REST API server</a>.</p>
<p>So far, I've only hacked a little bit the local server to let WIFI modules send data much faster (about 80 |  70 [ms]). This let me make a lot of queries in a second and allows the app to be a “Real Time App”. I did, but not yet completed, the interface that let user choose sounds, activate /deactivate sensors, etc.</p>
<h2>Technologies</h2>
<p>As a personal project, I wanted to learn new framework and new ways to program so I've searched for a framework/library that let me compose my application with multiple components (e.g.: the audio player  as a component). After some days I've found a JS library. <a href="http://vuejs.org">VueJS</a>. VueJS is like React but don't use a virtual-DOM. It is focused on the view layer only. VueJS uses the actual DOM as the template and keeps references to actual nodes for data bindings. This limits VueJS to environments where DOM is present. </p>
<p>This is a simple example of a vue component with 3 parts : the script, the template and the style.<figure><img src="https://liip.rokka.io/www_inarticle/90768a104adce1e82957485ab648b8593c0f979d/vue-component.jpg" alt="vue-component"></figure></p>
<h2>The next step</h2>
<p>As I've started my project only 2 months ago, I don't think I can finish it until the end of my internship knowing that I work on it only every Monday. I will maybe do a little demo to see what I've done so far.</p>
<p>I would like to get to the point where I can use the application with, at least, the possibility of playing sounds with it. The final goal is to have a complete and simple interface with the possibility to records “songs” and manage sounds from a timeline.</p>
<p>At the end of my internship, I'll release a new blog post talking about the final stage of my project and especially the REST API server. Finally, if you want to contribute to the project, you can go and see the code on github : <a href="https://github.com/JordanAssayah/MVM">github.com/JordanAssayah/MVM</a>.</p>
<figure><a href="https://www.liip.ch/content/4-blog/20160803-music-dance-web-technologies/12711026_1154414194578531_30521974511740211_o.jpg"><img src="https://liip.rokka.io/www_inarticle/3ca7543ef1deb4c1101073928f50e53234d3a10c/12711026-1154414194578531-30521974511740211-o-1024x682.jpg" alt="Jordan dancing"></a></figure>
<p>Me dancing at the opening of the ThinkSpace in Lausanne</p>]]></description>
                  <enclosure url="http://liip.rokka.io/www_card_2/4be82c44ac13eb673812adc58f66189614905498/12711026-1154414194578531-30521974511740211-o.jpg" length="206242" type="image/jpeg" />
          </item>
    
  </channel>
</rss>
