<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jay Bertrand</title>
    <description>The latest articles on DEV Community by Jay Bertrand (@moncomptegithub).</description>
    <link>https://dev.to/moncomptegithub</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F480005%2F5163e3cd-46e3-45b7-b0b7-42b73cac85f1.png</url>
      <title>DEV Community: Jay Bertrand</title>
      <link>https://dev.to/moncomptegithub</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/moncomptegithub"/>
    <language>en</language>
    <item>
      <title>Vue3 + Vanilla Bootstrap5 </title>
      <dc:creator>Jay Bertrand</dc:creator>
      <pubDate>Tue, 13 Oct 2020 18:00:40 +0000</pubDate>
      <link>https://dev.to/moncomptegithub/vue3-vanilla-bootstrap5-10l3</link>
      <guid>https://dev.to/moncomptegithub/vue3-vanilla-bootstrap5-10l3</guid>
      <description>&lt;p&gt;To the non-French readers (🇬🇧, 🇺🇸, 🇳🇿, ...) , this post explains how to integrate Vanilla Bootstrap5 into a Vue3 application. I published &lt;a href="https://github.com/mon-compte-github/vue3-with-vanilla-bootstrap5" rel="noopener noreferrer"&gt;a sample project&lt;/a&gt; with a detailed README on GitHub. Feel free to ask me questions. Enjoy :)&lt;/p&gt;




&lt;p&gt;C'est mon premier post sur &lt;a href="https://dev.to/moncomptegithub/"&gt;dev.to&lt;/a&gt; \0/&lt;/p&gt;

&lt;h1&gt;
  
  
  Bootstrap
&lt;/h1&gt;

&lt;p&gt;Ca fait maintenant plusieurs années que je travaille avec Bootstrap. Pour moi qui ne suis ni graphiste, ni &lt;em&gt;web designer&lt;/em&gt;, ni illustrateur, ça me permet d'arriver rapidement à un rendu professionnel pour mes sites pros ou perso. Le « langage » est facile à appréhender, et on trouve des &lt;del&gt;centaines&lt;/del&gt; milliers d'exemples de codes et de customisations sur le web.&lt;/p&gt;

&lt;h1&gt;
  
  
  Single Page Applications
&lt;/h1&gt;

&lt;p&gt;J'aurais peut-être dû commencer par ça : je suis développeur. J'ai œuvré dans des domaines et des technos très différents (programmation système en C/C++, développement de frameworks en Java, applications bureautiques, ...) mais en ce moment, je développe essentiellement des SPAs en Angular &lt;del&gt;2&lt;/del&gt; &lt;del&gt;5&lt;/del&gt; &lt;del&gt;8&lt;/del&gt; 10. Quel rapport avec ce post ? Aucun.&lt;/p&gt;

&lt;p&gt;Je n'ai jamais fait de React, je trouve ça un peu fouillis mais vu l'engouement pour ce framework sur les Internets, il ne manque sûrement pas d'intérêt. Je me suis d'ailleurs dit qu'il fallait que j'essaye prochainement &lt;a href="https://joshwcomeau.com/react/animated-sparkles-in-react/" rel="noopener noreferrer"&gt;ce tuto&lt;/a&gt;. Mais toujours pas de lien avec le sujet.&lt;/p&gt;

&lt;p&gt;En revanche, je suis désormais officiellement accro à Vue3 😍 La version précédente avait pour avantage d'être légère et facilement intégrable, mais dès que le code grossissait un peu ... 🤮. Cette nouvelle mouture est tout simplement &lt;em&gt;OMG&lt;/em&gt; !!  Je l'utilise donc de plus en plus pour mes projets et du coup, j'ai voulu y intégrer Bootstrap. Voilà, on y est !&lt;/p&gt;

&lt;h1&gt;
  
  
  SPA + Bootstrap
&lt;/h1&gt;

&lt;p&gt;Bootstrap étant un peu connu, tous les frameworks &lt;em&gt;hype&lt;/em&gt; de création de SPA ont leur &lt;em&gt;binding&lt;/em&gt; natif.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://ng-bootstrap.github.io/#/home" rel="noopener noreferrer"&gt;Ng-Bootstrap&lt;/a&gt; pour Angular&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://react-bootstrap.github.io" rel="noopener noreferrer"&gt;React-Bootstrap&lt;/a&gt; pour React &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://bootstrap-vue.org" rel="noopener noreferrer"&gt;Bootstrap-Vue&lt;/a&gt; pour Vue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ils ont tous plein d'arguments pour vanter leur mérite : intégrés, configurables, accessibles, modulaires, ... mais parfois, on ne peut pas, ou simplement on ne &lt;em&gt;veut&lt;/em&gt; pas utiliser une surcouche. &lt;/p&gt;

&lt;p&gt;Maintenant que le cadre est posé, on peut passer aux choses sérieuses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intégration
&lt;/h2&gt;

&lt;p&gt;Pour commencer, on part d'un projet Vue3, nouveau ou existant. Ici j'ai créé un projet &lt;em&gt;from scratch&lt;/em&gt; en Javascript, mais je vous conseille &lt;strong&gt;fortement&lt;/strong&gt; d'utiliser TypeScript pour vos développements.&lt;/p&gt;

&lt;p&gt;Pour pouvoir customiser Bootstrap bien comme il faut, on utilise ses sources au format &lt;a href="https://sass-lang.com" rel="noopener noreferrer"&gt;SASS&lt;/a&gt;. Vue gère très bien ce format à condition d'installer le préprocesseur qui va bien, c'est justement le rôle des paquets &lt;code&gt;sass&lt;/code&gt; et &lt;code&gt;sass-loader&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Enfin, on installe Bootstrap 5 et ses dépendances (il semble que &lt;code&gt;Popper.js&lt;/code&gt; soit obligatoire, pour le moment en tous cas).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# création d'un projet vue3 from scratch&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @vue/cli
&lt;span class="nv"&gt;$ &lt;/span&gt;vue create vue3-with-vanilla-bootstrap5

&lt;span class="c"&gt;# pour pouvoir utiliser du SCSS&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;npm i sass-loader sass

&lt;span class="c"&gt;# intégration de bootstrap&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;npm i bootstrap@next popper.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pour reconfigurer Bootstrap, on crée un fichier &lt;code&gt;src/assets/custom.scss&lt;/code&gt;. Son contenu initial est copié de &lt;code&gt;node_modules/bootstrap/scss/bootstrap.scss&lt;/code&gt;, le fichier qui &lt;em&gt;bootstrap&lt;/em&gt; Bootstrap.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="c1"&gt;// helpers (ne génèrent pas de contenu)&lt;/span&gt;
&lt;span class="c1"&gt;// doivent être définis en premier&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s2"&gt;"../../node_modules/bootstrap/scss/functions"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s2"&gt;"../../node_modules/bootstrap/scss/variables"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s2"&gt;"../../node_modules/bootstrap/scss/mixins"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s2"&gt;"../../node_modules/bootstrap/scss/utilities"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// notre customisation commence ici&lt;/span&gt;

&lt;span class="c1"&gt;// nouvelle couleur de fond&lt;/span&gt;
&lt;span class="nv"&gt;$body-bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#ECECEC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#F24438&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$secondary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#7C4E40&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// couleurs du thème revisitées&lt;/span&gt;
&lt;span class="nv"&gt;$theme-colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;"primary"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"secondary"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="nv"&gt;$secondary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;ne&lt;/span&gt; &lt;span class="n"&gt;pas&lt;/span&gt; &lt;span class="n"&gt;oublier&lt;/span&gt; &lt;span class="n"&gt;les&lt;/span&gt; &lt;span class="n"&gt;couleurs&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;
    &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;sinon&lt;/span&gt; &lt;span class="n"&gt;elles&lt;/span&gt; &lt;span class="n"&gt;ne&lt;/span&gt; &lt;span class="n"&gt;seront&lt;/span&gt; &lt;span class="n"&gt;plus&lt;/span&gt; &lt;span class="n"&gt;disponibles&lt;/span&gt;
    &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;peut&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="err"&gt;ê&lt;/span&gt;&lt;span class="n"&gt;me&lt;/span&gt; &lt;span class="n"&gt;en&lt;/span&gt; &lt;span class="n"&gt;ajouter&lt;/span&gt; &lt;span class="n"&gt;des&lt;/span&gt; &lt;span class="n"&gt;nouvelles&lt;/span&gt;
    &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tertiary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;accent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="s2"&gt;"tertiary"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="mh"&gt;#515151&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="nv"&gt;$success&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;       &lt;span class="nv"&gt;$info&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"warning"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="nv"&gt;$warning&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"danger"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="nv"&gt;$danger&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"light"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;      &lt;span class="nv"&gt;$light&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"dark"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;       &lt;span class="nv"&gt;$dark&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s2"&gt;"../../node_modules/bootstrap/scss/root"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ... autres fichiers scss qui génèrent les règles css&lt;/span&gt;
&lt;span class="c1"&gt;// seulement ceux qui nous intéressent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dans &lt;code&gt;main.js&lt;/code&gt;, on importe notre fichier custom, ainsi que le javascript requis pour les widgets complexes (modal, dropdown, ...) :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// bootstrap javascript&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bootstrap&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// bootstrap style&lt;/span&gt;
&lt;span class="c1"&gt;//import 'bootstrap/scss/bootstrap.scss'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/assets/custom.scss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et voilà ! Il ne reste qu'à relooker notre application avec les classes bien connues. Attention, &lt;a href="https://designmodo.com/bootstrap-5/" rel="noopener noreferrer"&gt;la version 5 a fait un grand ménage&lt;/a&gt; !&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-primary mr-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Primary&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm7f5vlmzjwma47poqyyi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm7f5vlmzjwma47poqyyi.png" alt="Bouton Primaire Restylé"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Et jQuery ?
&lt;/h2&gt;

&lt;p&gt;Bootstrap5 n'embarque plus jQuery, même si à priori on peut encore l'utiliser avec. L'équipe de dév a &lt;a href="https://blog.getbootstrap.com/2020/06/16/bootstrap-5-alpha/#jquery-and-javascript" rel="noopener noreferrer"&gt;tout réécrit en pur javascript&lt;/a&gt; permettant ainsi de diminuer de manière drastique la taille du bundle final et, je suppose, d'améliorer les performances. &lt;/p&gt;

&lt;p&gt;Les widgets évolués (modal, dropdown, ...) sont implémentés par des classes que l'on doit importer. Et pour faire le lien entre les instances et le DOM, on peut bien évidemment utiliser Vue :)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- notez bien l'attribut ref qui nous servira à récupérer la référence au bouton --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"popoverRef"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"pop-pop-pop"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-dark"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"showPopover()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Javascript&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Popover&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bootstrap&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// le lien avec le bouton sera fait automagiquement :)&lt;/span&gt;
&lt;span class="c1"&gt;// ne pas oublier d'exporter cette valeur en sortie de setup()&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;popoverRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;popover&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Popover&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;popoverRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello world!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;placement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;top&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;popover&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Il est tout à fait possible et même relativement facile d'intégrer Bootstrap &lt;em&gt;sans surcouche&lt;/em&gt; dans une application Vue, de le customiser et de l'optimiser comme on le ferait pour un site html standard. On évite ainsi d'alourdir le projet avec une librairie supplémentaire, d'avoir à apprendre une nouvelle syntaxe, de noyer notre html dans des balises spécifiques, ...&lt;/p&gt;

&lt;p&gt;J'ai publié sur GitHub &lt;a href="https://github.com/mon-compte-github/vue3-with-vanilla-bootstrap5" rel="noopener noreferrer"&gt;le projet complet&lt;/a&gt; reprenant le code utilisé dans ce article.&lt;/p&gt;

&lt;p&gt;A bientôt :)&lt;/p&gt;

</description>
      <category>vue3</category>
      <category>bootstrap5</category>
      <category>vanilla</category>
      <category>french</category>
    </item>
  </channel>
</rss>
