<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Vue vs React (initial impressions) in Alfresco Archive</title>
    <link>https://connect.hyland.com/t5/alfresco-archive/vue-vs-react-initial-impressions/m-p/160391#M114363</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;PRE __default_attr="info" __jive_macro_name="alert" alert="info" class="jive_text_macro jive_macro_alert"&gt;&lt;SPAN style="color: #0f7198; background-color: #ffffff;"&gt;This is a personal blog post that is primarily intended for tracking my own learning rather than provided to the Alfresco Community for educational purposes. However if you find it useful, informative or have any comments on it then please comment below.&lt;/SPAN&gt;&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;At the end of &lt;A _jive_internal="true" href="https://community.alfresco.com/people/ddraper/blog/2017/01/05/alfresco-auth-router-and-react" rel="nofollow noopener noreferrer"&gt;my last blog post&lt;/A&gt;&amp;nbsp;I'd failed to make use of my &lt;A href="https://www.npmjs.com/package/alfresco-auth-router" rel="nofollow noopener noreferrer"&gt;alfresco-auth-router NPM package&lt;/A&gt;&amp;nbsp;with the React "&lt;A href="https://github.com/facebookincubator/create-react-app" rel="nofollow noopener noreferrer"&gt;create-react-app&lt;/A&gt;" CLI. Instead I'd configured an &lt;A href="https://www.npmjs.com/package/http-proxy-middleware" rel="nofollow noopener noreferrer"&gt;http-middleware-proxy&lt;/A&gt;&amp;nbsp;to route API requests (including those required for authentication) via a local Alfresco Repository.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The main difference was the approach to creating the application. I could just as easily as built my React project with a custom &lt;A href="http://expressjs.com/" rel="nofollow noopener noreferrer"&gt;Express&lt;/A&gt; server that made use of the alfresco-auth-router but I wanted to experiment with the app building tooling provided for each UI framework. You can find the state of the React project at the time of writing in &lt;A href="https://github.com/draperd/React-Client-1" rel="nofollow noopener noreferrer"&gt;this GitHub repository&lt;/A&gt;&amp;nbsp;by checking out &lt;A href="https://github.com/draperd/React-Client-1/releases/tag/Blog1" rel="nofollow noopener noreferrer"&gt;this tag&lt;/A&gt;.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The "create-react-app" CLI is very much geared up to building Single Page Applications (SPAs) to it was necessary to use &lt;A href="https://github.com/reacttraining/react-router" rel="nofollow noopener noreferrer"&gt;react-router&lt;/A&gt;&amp;nbsp;to ensure that only authenticated users can access the Alfresco data. Again, this approach could have been implemented in Vue if necessary, in fact at some point I may go back and experiment with &lt;A href="https://router.vuejs.org/en/" rel="nofollow noopener noreferrer"&gt;vue-router&lt;/A&gt; to see how it compares.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;With authentication handled in both Vue and React applications it was now a case of building out my simple application for browsing "Company Home" in the Alfresco Repository. My intention was to implement the same component structure in both frameworks.... essentially a List component that contains Breadrcumb, Toolbar and View sub-components.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;As an aside I think that this is one of my main regrets about the way in which I implemented lists in &lt;A href="https://github.com/Alfresco/Aikau" rel="nofollow noopener noreferrer"&gt;Aikau&lt;/A&gt;. I had not foreseen the data down / events up model that is now becoming so popular and opted for a pub/sub model (although this does offer some advantages).&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;A better model is that the list manages the state and all state changing components (including pagination and breadcrumbs) are included within the list such that events can bubble up out to the list. I think that this fits with the model described in &lt;A href="https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0#.gxoox497u" rel="nofollow noopener noreferrer"&gt;this post&lt;/A&gt;.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Both Vue and React have issues in this area in that... whilst Vue offers the ability to &lt;A href="https://vuejs.org/v2/api/#vm-emit" rel="nofollow noopener noreferrer"&gt;emit&lt;/A&gt; custom events these only go from child to immediate parent (and do not bubble) whereas React doesn't offer custom events at all. Instead the pattern for React is to pass callbacks as properties to child components (as described &lt;A href="http://stackoverflow.com/questions/21951734/react-js-custom-events-for-communicating-with-parent-nodes" rel="nofollow noopener noreferrer"&gt;here&lt;/A&gt;). This presents an issue with deeper nesting of components - one suggested solution for React is described &lt;A href="https://github.com/ryanflorence/react-training/blob/gh-pages/lessons/04-less-simple-communication.md" rel="nofollow noopener noreferrer"&gt;here&lt;/A&gt; (although I think this creates stronger coupling which should be avoided).&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The other major difference is in how iteration is handled. Vue takes a very similar approach introduced in the original Angular library to provide an custom HTML attribute "&lt;A href="https://vuejs.org/v2/guide/list.html" rel="nofollow noopener noreferrer"&gt;v-for&lt;/A&gt;" to iterate over elements whereas React makes use of JSX to use a have a &lt;A href="https://facebook.github.io/react/docs/lists-and-keys.html" rel="nofollow noopener noreferrer"&gt;JavaScript loop&lt;/A&gt; to provide the iteration.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Vue.js:&lt;/P&gt;&lt;PRE class="line-numbers language-markup"&gt;&lt;CODE&gt;&lt;SPAN class="token tag"&gt;&lt;SPAN class="token tag"&gt;&lt;SPAN class="punctuation token"&gt;&amp;lt;&lt;/SPAN&gt;ul&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &lt;SPAN class="token tag"&gt;&lt;SPAN class="token tag"&gt;&lt;SPAN class="punctuation token"&gt;&amp;lt;&lt;/SPAN&gt;li&lt;/SPAN&gt; &lt;SPAN class="attr-name token"&gt;class&lt;/SPAN&gt;&lt;SPAN class="attr-value token"&gt;&lt;SPAN class="punctuation token"&gt;=&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;"&lt;/SPAN&gt;components-lists-ListView__item&lt;SPAN class="punctuation token"&gt;"&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="attr-name token"&gt;v-for&lt;/SPAN&gt;&lt;SPAN class="attr-value token"&gt;&lt;SPAN class="punctuation token"&gt;=&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;"&lt;/SPAN&gt;item in list.entries&lt;SPAN class="punctuation token"&gt;"&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="attr-name token"&gt;@click&lt;/SPAN&gt;&lt;SPAN class="attr-value token"&gt;&lt;SPAN class="punctuation token"&gt;=&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;"&lt;/SPAN&gt;navigate(item, $event)&lt;SPAN class="punctuation token"&gt;"&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;{{item.entry.name}}&lt;SPAN class="token tag"&gt;&lt;SPAN class="token tag"&gt;&lt;SPAN class="punctuation token"&gt;&amp;lt;/&lt;/SPAN&gt;li&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN class="token tag"&gt;&lt;SPAN class="token tag"&gt;&lt;SPAN class="punctuation token"&gt;&amp;lt;/&lt;/SPAN&gt;ul&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN class="line-numbers-rows"&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;React:&lt;/P&gt;&lt;PRE class="language-javascript line-numbers"&gt;&lt;CODE&gt;&lt;SPAN class="token function"&gt;render&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &lt;SPAN class="keyword token"&gt;return&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="operator token"&gt;&amp;lt;&lt;/SPAN&gt;ul&lt;SPAN class="operator token"&gt;&amp;gt;&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;&lt;SPAN class="keyword token"&gt;this&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;props&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;list&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;entries&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;&lt;SPAN class="token function"&gt;map&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;entry&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt; &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt;&lt;SPAN class="operator token"&gt;&amp;gt;&lt;/SPAN&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class="operator token"&gt;&amp;lt;&lt;/SPAN&gt;li onClick&lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt; &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt;&lt;SPAN class="operator token"&gt;&amp;gt;&lt;/SPAN&gt; &lt;SPAN class="keyword token"&gt;this&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;props&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;&lt;SPAN class="token function"&gt;navigationHandler&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;entry&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt; key&lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;entry&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;entry&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;id&lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;&lt;SPAN class="operator token"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;entry&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;entry&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;name&lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;&lt;SPAN class="operator token"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class="operator token"&gt;/&lt;/SPAN&gt;li&lt;SPAN class="operator token"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;&lt;SPAN class="operator token"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class="operator token"&gt;/&lt;/SPAN&gt;ul&lt;SPAN class="operator token"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;&lt;SPAN class="line-numbers-rows"&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I have to admit that I preferred the Vue.js approach for for this particular use-case, however I can see where the power of having full control over the JavaScript in a JSX implementation may be beneficial in other cases.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Those code snippets also show the differences in event handling of clicking on an item in the list. Again, the Vue.js approach "feels" cleaner and is easier to read in my opinion. The other major problem with the React solution is the necessity to create a "this" binding to these callback functions in the constructor for the component, i.e:&lt;/P&gt;&lt;PRE class="language-javascript line-numbers"&gt;&lt;CODE&gt;&lt;SPAN class="keyword token"&gt;this&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;pageBack &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt; &lt;SPAN class="keyword token"&gt;this&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;pageBack&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;&lt;SPAN class="token function"&gt;bind&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="keyword token"&gt;this&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN class="keyword token"&gt;this&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;pageForward &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt; &lt;SPAN class="keyword token"&gt;this&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;pageForward&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;&lt;SPAN class="token function"&gt;bind&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="keyword token"&gt;this&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN class="keyword token"&gt;this&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;navigate &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt; &lt;SPAN class="keyword token"&gt;this&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;navigate&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;&lt;SPAN class="token function"&gt;bind&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="keyword token"&gt;this&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN class="keyword token"&gt;this&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;setRelativePath &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt; &lt;SPAN class="keyword token"&gt;this&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;setRelativePath&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;&lt;SPAN class="token function"&gt;bind&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="keyword token"&gt;this&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;&lt;SPAN class="line-numbers-rows"&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Other than these differences the end implementations&amp;nbsp;were incredibly similar, although perhaps that is to be expected for such a simple use case. One thing that did immediately jump out was the necessity to do some post processing of node data in order to construct the breadcrumb trail and I plan to elaborate on that in my next post.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;It might also be interesting to note that I created another &lt;A href="https://www.npmjs.com/package/alfresco-js-utils" rel="nofollow noopener noreferrer"&gt;NPM package&lt;/A&gt; to contain JavaScript code that can be shared between both implementations (and indeed implementations using other frameworks). I intend to keep adding to this as necessary with this research.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Tue, 10 Jan 2017 08:48:30 GMT</pubDate>
    <dc:creator>ddraper</dc:creator>
    <dc:date>2017-01-10T08:48:30Z</dc:date>
    <item>
      <title>Vue vs React (initial impressions)</title>
      <link>https://connect.hyland.com/t5/alfresco-archive/vue-vs-react-initial-impressions/m-p/160391#M114363</link>
      <description>This is a personal blog post that is primarily intended for tracking my own learning rather than provided to the Alfresco Community for educational purposes. However if you find it useful, informative or have any comments on it then please comment below.At the end of my last blog post&amp;nbsp;I'd failed to</description>
      <pubDate>Tue, 10 Jan 2017 08:48:30 GMT</pubDate>
      <guid>https://connect.hyland.com/t5/alfresco-archive/vue-vs-react-initial-impressions/m-p/160391#M114363</guid>
      <dc:creator>ddraper</dc:creator>
      <dc:date>2017-01-10T08:48:30Z</dc:date>
    </item>
  </channel>
</rss>

