Menar du...


  • Kategorier för din sökning

  • Inget resultat

    Vue - Introduction

    1. Quick-start

    1. Copy one of the example_list components under: /js/vue/components.
    2. Change the name of the component in the following places:
      1. The component folder name
      2. componentName in component.js
      3. data-vue-component in x_template.html
      4. Inside the twig example comment in x_template.html
    3. Add the new component name to the vue_component_paths list in standard.html
    4. Include the component where you want it according to the twig example component in x_template.html
    5. Hear me, and rejoice!

    2. When to use Vue

    It's quite simple, if you can achieve your goal using Twig and regular HTML, do that. If you need something to be "reactive" to changes without reloading the entire page, use Vue.

    Example use cases:
    • Toggles
    • AJAX-submits
    Important note: Do not use Vue for anything that needs to be indexed by search engines. There are ways to make this work, but we'll cross the bridge when we get there.

    3. Directories and files


    /standard.html

    Every new component must be included in the vue_component_paths list here.
    To enable developer tools and debugging, super admins have access to the development version.


    /js/vue/vue_wrapper.js

    Since Vue isn't the only sheriff in town (looking at you jQuery) we might run into unforeseen consequences if we wrap the entire page in a single large Vue instance. What we do instead is to compartmentalize each component within its own Vue instance. That's what vue_wrapper.js does.

    It also listens for a few global JS-events (DOMContentLoaded, vendreDOMContentReplaced & vendreDOMContentAppended) that tells us that the page might have been altered and initializes any new instances.

    You shouldn't have to touch this one.


    /js/vue/components

    Each component has its own directory, usually containing 2 files:

    Exempelbild

     

    component.js

    Besides the usual Vue magic, this file is responsible for registering the component with Vue so it can be accessed.

    (function () {
      const componentName = "example-list";
    
      window.Vue.component(componentName, {
        template: document.querySelector(
          '[data-vue-component="' + componentName + '"]',
        ),
        data: function () {
          return {
            exampleText: 'The Debugger'
          };
        }
      });
    })();

    component.js (with jQuery)

    As mentioned above we still use jQuery in a lot of our projects and sometimes it might be needed within your vue component. You can include jQuery by adding it as seen in this example.

    (function ($) {
    ...
    })(jQuery);

    x_template.html

    In the example components, this file includes a script tag containing the x-template. No twig should be used inside this tag, all data from twig should be passed to the component by setting the props where the component is used.

    The script tag is enclosed by the verbatim twig tag, which means that twig does not render any twig code inside it. This means that double braces {{ code }} inside are interpreted as Vue code.

    There should only be exactly 1 html element directly inside the script tag, hence the use of an unadorned div in the example code.

    {% verbatim %}
    <script type="text/x-template" data-vue-component="example-list">
      <div>
        {{ exampleText }}
      </div>
    </script>
    {% endverbatim %}

    x_template.html (with child components)

     You may include other components as child components. In this example, another component named example-list-row is looped out inside our example-list component. Each item's name is passed as a prop into the child components (the child components are responsible for displaying those names).

    The :key binding is recommended when using reactive lists that may be updated, sorted and filtered as it helps vue to keep track of the list items for those purposes.

    {% verbatim %}
    <script type="text/x-template" data-vue-component="example-list">
      <div>
        <example-list-row v-for="item in list" :key="item.id" :name="item.name"></example-list-row>
      </div>
    </script>
    {% endverbatim %}

    4. How to include components and pass twig data

     

    How to include a basic component

     The simplest type of component, without any in-data, may be included like this in whichever html file you want the component to render.

    <div data-vue-wrapper>
      <example-list></example-list>
    </div>

    How to include a component with props

    Often you want to pass data from the twig context to the vue component. This is done by setting props like the example here.

    <div data-vue-wrapper>
      <example-list
        :example-prop1="{{ my_twig_variable1|json_encode }}"
        :example-prop2="{{ my_twig_variable2|json_encode }}"
      ></example-list>
    </div>

    How to use langstr inside a component

    Sometimes you want the use the system's language variables (langstr) in the component. The recommended solution is to pass them as an array to a prop, like in this example. Thus you may use them in the vue code in a similar way.

    <div data-vue-wrapper>
      <example-list
        :langstr="{{ {
          'SOME_LANGUAGE_VARIABLE': langstr('SOME_LANGUAGE_VARIABLE'),
          'C_SOME_CUSTOM_LANGUAGE_VARIABLE': langstr('C_SOME_CUSTOM_LANGUAGE_VARIABLE')
        }|json_encode }}"
      ></example-list>
    </div>

    Add langstr as a prop in component.js.

    (function () {
      const componentName = "example-list";
    
      window.Vue.component(componentName, {
        template: document.querySelector(
          '[data-vue-component="' + componentName + '"]',
        ),
        props: {
          langstr: {
            required: false,
            type: Object,
          }
        }
      });
    })();

    Example of using langstr in vue code.

    {% verbatim %}
    <script type="text/x-template" data-vue-component="example-list">
      <div>
        This: {{ langstr['SOME_LANGUAGE_VARIABLE'] }}<br>
        That: {{ langstr['C_SOME_CUSTOM_LANGUAGE_VARIABLE'] }}
      </div>
    </script>
    {% endverbatim %}

    How to use svg inside a component

    Sometimes you want the use svg files only accessible through twig. The recommended solution is to pass them as an array to a prop, just like langstr above. Thus you may use them in the vue code in a similar way.

    <div data-vue-wrapper>
      <example-list
          :svg="{{ {
            'angleLeft': include('scss/icons/angle-left.svg'),
            'angleRight': include('scss/icons/angle-right.svg')
          }|json_encode }}"
      ></example-list>
    </div>

    Add svg as a prop in component.js.

    (function () {
      const componentName = "example-list";
    
      window.Vue.component(componentName, {
        template: document.querySelector(
          '[data-vue-component="' + componentName + '"]',
        ),
        props: {
          svg: {
            required: false,
            type: Object,
          }
        }
      });
    })();

    When including the svgs in a vue component, we want them to render as html. A suggested solution is to use v-html on a container element, like in the example here.

    {% verbatim %}
    <script type="text/x-template" data-vue-component="example-list">
      <div>
        <span v-html="svg['angleRight']"></span>_<span v-html="svg['angleLeft']"></span>
      </div>
    </script>
    {% endverbatim %}

    5. Tips and gotchas

    • Every component must have a single root element, that's why some components contain a single wrapping div.
    • Try to use vanilla js as far as you can. Use fetch instead of $.ajax for instance.

    5.1 Further reading

    https://vuejs.org/
    https://vuejs.org/v2/guide/
    https://laracasts.com/series/learn-vue-2-step-by-step
    https://vuejs-tips.github.io/cheatsheet/