One place for hosting & domains

      Blocks

      Using Redis Transaction Blocks


      Redis is an open-source, in-memory database used for caching, messaging, and other storage tasks that benefit from fast execution and low latency. The Redis database supports a high degree of control over parallel executions that allow you to fine-tune its performance.

      This guide walks you through using Redis’s transaction blocks. Transaction blocks group Redis commands and execute them as single units. Doing so guarantees uninterrupted sequential execution of each set of commands. This ensures that all of the commands in a transaction block are executed, even in highly parallel environments.

      Before You Begin

      1. Familiarize yourself with our
        Getting Started with Linode
        guide and complete the steps for setting your Linode’s hostname and timezone.

      2. This guide uses sudo wherever possible. Complete the sections of our
        Securing Your Server
        guide to create a standard user account, harden SSH access, and remove unnecessary network services.

      3. Update your system.

        • On Debian and Ubuntu, use the following command:

          sudo apt update && sudo apt upgrade
          
        • On AlmaLinux, CentOS (8 or later), or Fedora, use the following command:

          sudo dnf upgrade
          
      4. Follow the instructions in our
        How to Install and Configure Redis
        guide to installing a Redis server and command-line interface (CLI). Be sure to use the drop-down menu at the top of that page to select your Linux distribution and get the appropriate steps.

      Note

      The steps written in this guide are for non-root users. Commands that require elevated privileges are prefixed with sudo. If you’re not familiar with the sudo command, see the
      Linux Users and Groups
      guide.

      What Are Redis Transactions?

      Redis Transactions are a group of commands that are executed collectively and sequentially. The benefits of executing commands as transaction blocks are to ensure the following:

      • The sequence of commands is not interrupted, even by another Redis client
      • The commands are executed as an atomic unit and the entire transaction block is processed collectively

      Transactions are especially useful in environments with numerous clients, and where clients are making frequent transactions in parallel. Redis’s transaction blocks ensure that a given set of commands executes as a unit and in a predetermined order.

      Transaction Blocks vs. Pipelines

      Redis pipelining is another method used to optimize command execution in a highly parallel network. Pipelining in Redis allows clients to queue a series of commands and send them to the server simultaneously, rather than in multiple round trips.

      It may seem like transaction blocks and pipelining serve similar purposes. However, each has a distinct goal and acts to optimize command execution in very different ways from the other. Some of the differences are:

      • Pipelining is concerned primarily with network efficiency. It reduces the round-trip time for a series of commands by submitting them all in one request, rather than a series of requests each with its own response.

        Pipelining is useful for reducing latency and increasing the feasible number of operations per second.

      • Transactions are concerned with the integrity of a group of commands. They ensure that the entirety of a designated group of commands gets executed sequentially and without interruption. This is in contrast to pipelines that may execute requests in alternation with requests sent from other clients.

        Transaction blocks are useful when you need to guarantee a collection of commands is processed as a unit and the commands are executed sequentially.

      How to Run a Transaction Block

      To start a transaction in Redis, use the following command in the Redis CLI:

      MULTI
      

      The MULTI command begins a new transaction block. Any subsequent commands you enter are queued in sequence. To end the queuing of commands and complete the transaction block, use the following command:

      EXEC
      

      The commands displayed below include a complete example of creating a transaction block with the MULTI and EXEC commands. It starts with the MULTI command to initiate a transaction block. Then it creates a new key with a value of 10 and increments that key’s value by one. The key is then reset to 8 and again increments the value by one. Finally, the EXEC command completes the block and executes the transaction.

      MULTI
      SET the_key 10
      INCR the_key
      SET the_key 8
      INCR the_key
      GET the_key
      EXEC
      

      Notice that, for each command within the block (between MULTI and EXEC), the client responds with QUEUED. Once you send the EXEC command, the server provides an appropriate response for each command within the transaction.

      1) OK
      2) (integer) 11
      3) OK
      4) (integer) 9
      5) "9"

      How to Handle Errors in a Transaction Block

      When working with Redis transaction blocks, there are two kinds of errors that you may encounter. Based on when they occur, the errors can be categorized as follows:

      • Errors before the EXEC command:

        These include errors related to syntax or related to server restrictions, like maximum memory. Although you can continue queuing commands after receiving one of these errors, the transaction block subsequently fails when you run EXEC.

        For example, the transaction below includes a typo for the GET command:

        MULTI
        SET new_key "alpha"
        GRT new_key
        
        (error) ERR unknown command `GRT`, with args beginning with: `new_key`,

        Disregarding the error and attempting to execute the transaction results in an error.

        EXEC
        
        (error) EXECABORT Transaction discarded because of previous errors.

        For this reason, you should cancel any transaction blocks that encounter errors during queuing. See the next section —
        How to Cancel a Transaction Block
        — for instructions on how to do so.

      • Errors after the EXEC command:

        These are errors returned by the server in response to individual commands in the transaction. For example, you might receive such an error due to mismatched types:

        MULTI
        SET new_key "beta"
        LPOP new_key
        EXEC
        
        1) OK
        2) (error) WRONGTYPE Operation against a key holding the wrong kind of value

        Notice that the first command was executed successfully, which you can further verify using the GET command:

        GET new_key
        
        "beta"

      How to Cancel a Transaction Block

      A transaction can be canceled at any time before the EXEC command. To do so, use the DISCARD command.

      The example below demonstrates that the key, another_key remains unchanged from its pre-transaction value:

      SET another_key "gamma"
      MULTI
      SET another_key 2
      INCR another_key
      DISCARD
      GET another_key
      
      "gamma"

      As mentioned above, the ability to cancel an in-progress transaction becomes especially handy if you encounter an error while queuing commands for a transaction.

      Conclusion

      Redis transaction execute a collection of commands and ensure that the command execution is not interrupted by another client. This guide covered creating transaction blocks, understanding common transaction errors, and canceling in-progress transactions.

      You can learn more about Redis and how to get the most out of your Redis databases through our other guides in this series. These guides cover everything from
      connecting to a remote Redis server
      to working with the
      hash data type
      .

      More Information

      You may wish to consult the following resources for additional information
      on this topic. While these are provided in the hope that they will be
      useful, please note that we cannot vouch for the accuracy or timeliness of
      externally hosted materials.



      Source link

      Decoding WordPress: New Site Blocks in 5.9


      WordPress has always been a user-friendly platform that is flexible and easy to learn. However, those without coding skills may struggle to perform certain customization tasks.

      Fortunately, Version 5.9 introduced Full-Site Editing, which brings together both new and existing features to provide centralized control of your entire site. One of the most significant changes is the addition of new site level blocks.

      In this post, we’ll discuss everything you need to know about site blocks in WordPress. We’ll also look at some examples and show you how to use them. Let’s get started!

      An Introduction to WordPress Blocks

      Blocks have been a fundamental aspect of WordPress since late 2018. Version 5.0 of WordPress replaced the classic editor with a new WordPress block editor called Gutenberg.

      A block is a specific element that you can add to your site. For instance, there are blocks for images, headings, lists, paragraphs, and more. This system provides users with a simple and intuitive way to create a unique website.

      Each block comes with a set of customization options, such as alignment, color, and size. Additionally, blocks can be moved around on via a drag-and-drop editor, facilitating a simpler page-building process.

      Common WordPress Blocks

      Gutenberg introduced blocks for various purposes. There may be some blocks that you will never touch. However, there are others you’ll probably use every time you create a post. Let’s take a look at some of the most common options in the new block editor.

      The Heading Block

      The Heading block provides several choices for configuring and styling headings:

      WordPress Heading Block

      This block can help you organize your content more efficiently. For instance, you can select the heading level H2 for main sections, and H3-H6 for subsections. Additionally, you can add a hyperlink to the heading.

      The Paragraph Block

      Paragraphs are the most frequently-used block in the Gutenberg editor:

      WordPress Paragraph Block

      This element enables users to write text and customize the typography. Usually, headings are used to group relevant paragraphs together and split up the page’s content.

      The Image Block

      Image blocks enable you to upload photos or artwork to your site:

      WordPress Image Block

      You can then use the settings to resize and crop your images. You can also add captions and alt text.

      The Video Block

      You can also add videos to your post. There are different options for displaying videos:

      WordPress Video Block

      For instance, you can upload them to your site’s Media Library, or embed them from YouTube and other video-sharing platforms. You can also add text tracks such as subtitles, captions, chapters, and descriptions to the block.

      The List Block

      The List block enables you to insert bulleted or numbered lists into your page:

      WordPress List Block

      This block comes with styling options such as bold and italics, as well as more intricate rich-text controls. Additionally, you can add hyperlinks to list items.

      Skip the line and get tips right in your inbox

      Click below to sign up for more how-to’s and tutorials just like this one, delivered to your inbox.

      marketing tips

      New Site Blocks in WordPress 5.9

      Now that Full-Site Editing is here, individual blocks can also be used for editing your site’s theme. You can use the new editor to customize all aspects of your site:

      WordPress Full Site Editing - edit template

      This feature has replaced the Customizer. However, it only supports block-based themes, such as Twenty Twenty-Two. If you’re using a ‘standard’ theme, you’ll still have access to the Customizer (and the Gutenberg block editor), but you won’t be able to use the Full-Site Editor.

      The Full-Site Editor comes with templates for different pages, such as your archive or home page. Additionally, you can customize more areas of your site, such as your header and footer. There is also a new Global Styles feature, which enables you to define site-wide settings for your blocks.

      In addition, the Full-Site Editor has introduced a range of ‘theme blocks’. Often nicknamed ‘site blocks’, these new additions enable you to use and edit global elements such as the site logo and tagline, navigation, and post lists.

      The Benefits of Using Theme Blocks

      The new theme blocks were introduced to make the web design process in WordPress simpler and more streamlined. Previously, the WordPress theme editor had limited customization options, and users who wanted unique designs often needed to use custom code.

      Theme blocks remove the need for coding (and third-party page builder plugins) in most cases. Each block has a variety of styling and display options, offering users the flexibility to create almost any layout and design. Whether you’re a WordPress beginner or an experienced web developer, the process of creating custom sites is now faster and easier.

      Let’s take a look at some notable site blocks that have been added with WordPress 5.9. This is just a brief introduction – we’ll delve more deeply into each of these Gutenberg blocks shortly.

      Navigation

      This feature enables you to add your site’s navigation menu to a page:

      WordPress Navigation Block

      You can customize both the design and structure of your menu. For instance, you can add submenu items, change the color and alignment, and more.

      Query Loop

      A query loop is a block that displays a set of posts based on specific conditions and parameters:

      WordPress Query Loop Block

      This is a great way to showcase posts on a particular topic. You can filter content by post categories, tags, authors, and keywords. The block also comes with different styling options for the post feed.

      Template Part

      Template parts are used to organize the structure of a site. They’re essentially collections or containers of other content blocks:

      WordPress Template Part Block

      They can only be used when editing templates, so you’ll find this block in the Full-Site Editor. Each template part has a user-generated name. When adding a block, you can choose an existing template or create a new one.

      How to Use Common WordPress Site Blocks (6 New Theme Blocks)

      Now, let’s take a detailed look at a few common theme blocks. For each of the new blocks, we’ll discuss its purpose and the steps for using it.

      1. Navigation

      Navigation blocks are used for editing your site’s menus. When you add this block to your page, you are given three options: select an existing menu, add all of the site’s pages, or start with an empty menu:

      WordPress Navigation Block

      You can include additional menu items as well as indented items, which appear as subpages. Moreover, you can change the links and names of each item using the “anchor” icon in the toolbar. The toolbar also enables you to change the alignment and other layout settings.

      2. Login/out

      The login/out block provides a simple way to add a login and logout button to your website:

      WordPress Login/Out Block

      It automatically displays the correct link depending on the status of the user. You also have the option to display the login/out button as a switch.

      3. Template Part 

      This element can be thought of as a group of blocks. The template part helps you organize the structure of your page. These blocks can only be used when editing templates, and they’re an excellent way to manage global areas such as headers and footers:

      WordPress Header Block

      Template parts can be added in the site editor. Upon selecting the block, you’ll be asked if you want to add an existing template or create a new one.

      If you opt for the latter, you’ll be prompted to enter a name for the template. Then, you can go ahead and add in blocks to create the desired layout.

      4. Site Title

      As the name suggests, this block is used to display the title of your site:

      WordPress Site Title Block

      By default, the title links to the home page, but this can be turned off with a toggle switch in the settings. There’s also a range of styling options, including text and background colors, font size, line height, letter spacing, and other typography settings.

      5. Post Excerpt

      Post excerpts give readers a sneak peek into a post, and can help them decide whether or not they wish to read the entire article:

      WordPress Post Excerpt Block

      Most of the time, this block will be a child element of a query loop. It displays either the first 55 words of a post, or the set excerpt for that post. You can also add a “read more” link. This will take the user directly to the full post.

      6. Query Loop

      Query loops can be used to display a set of posts based on specific conditions and parameters. For example, you may use this block to show all posts in a particular category or by a specific author:

      WordPress Query Loop Block

      Query loops are made up of multiple blocks, including post titles, dates, excerpts, and featured images. You have the option to start blank and add nested blocks manually, or start with a premade layout and edit from there.

      You can then alter the width, alignment, arrangement, and colors. You can also change the number of posts that the query loop displays.

      Conclusion

      In the past, customizing WordPress sites may have been challenging for some users. However, with the release of new site blocks in version 5.9, the process has become a lot easier.

      Thanks to the Full-Site Editing feature, you can now make changes to your entire site from a unified interface. You can also customize individual elements such as the site title and tagline, navigation menu, and template parts like headers and footers.

      If you’re looking for a fast, reliable, and affordable place to host your WordPress site, we’ve got you covered. Check out our DreamHost WordPress Hosting plans!

      Power Your Website with DreamHost

      We make sure your website is fast, secure and always up so your visitors trust you. Plans start at $1.99/mo.

      shared hosting



      Source link

      How To Create Reusable Blocks of Code with Vue Single-File Components


      The author selected Open Sourcing Mental Illness to receive a donation as part of the Write for DOnations program.

      Introduction

      When creating a web application using Vue.js, it’s a best practice to construct your application in small, modular blocks of code. Not only does this keep the parts of your application focused, but it also makes the application easier to update as it grows in complexity. Since an app generated from the Vue CLI requires a build step, you have access to a Single-File Components (SFC) to introduce modularity into your app. SFCs have the .vue extension and contain an HTML <template>, <script>, and <style> tags and can be implemented in other components.

      SFCs give the developer a way to create their own HTML tags for each of their components and then use them in their application. In the same way that the <p> HTML tag will render a paragraph in the browser, and hold non-rendered functionality as well, the component tags will render the SFC wherever it is placed in the Vue template.

      In this tutorial, you are going to create a SFC and use props to pass data down and slots to inject content between tags. By the end of this tutorial, you will have a general understanding of what SFCs are and how to approach code re-usability.

      Prerequisites

      Step 1 — Setting Up the Project

      In this tutorial, you are going to be creating an airport card component that displays a number of airports and their codes in a series of cards. After following the Prerequisites section, you will have a new Vue project named sfc-project. In this section, you will import data into this generated application. This data will be an array of objects consisting of a few properties that you will use to display information in the browser.

      Once the project is generated, open your terminal and cd or change directory into the root src folder:

      From there, create a new directory named data with the mkdir command, then create a new file with the name us-airports.js using the touch command:

      • mkdir data
      • touch data/us-airports.js

      In your text editor of choice, open this new JavaScript file and add in the following local data:

      sfc-project/data/us-airports.js

      export default [
        {
          name: 'Cincinnati/Northern Kentucky International Airport',
          abbreviation: 'CVG',
          city: 'Hebron',
          state: 'KY'
        },
        {
          name: 'Seattle-Tacoma International Airport',
          abbreviation: 'SEA',
          city: 'Seattle',
          state: 'WA'
        },
        {
          name: 'Minneapolis-Saint Paul International Airport',
          abbreviation: 'MSP',
          city: 'Bloomington',
          state: 'MN'
        }
      ]
      

      This data is an array of objects consisting of a few airports in the United States. This will be rendered in a Single-File Component later in the tutorial.

      Save and exit the file.

      Next, you will create another set of airport data. This data will consist of European airports. Using the touch command, create a new JavaScript file named eu-airports.js:

      • touch data/eu-airports.js

      Then open the file and add the following data:

      sfc-project/data/eu-airports.js

      export default [
        {
          name: 'Paris-Charles de Gaulle Airport',
          abbreviation: 'CDG',
          city: 'Paris',
          state: 'Ile de France'
        },
        {
          name: 'Flughafen München',
          abbreviation: 'MUC',
          city: 'Munich',
          state: 'Bavaria'
        },
        {
          name: 'Fiumicino "Leonardo da Vinci" International Airport',
          abbreviation: 'FCO',
          city: 'Rome',
          state: 'Lazio'
        }
      ]
      

      This set of data is for European airports in France, Germany, and Italy, respectively.

      Save and exit the file.

      Next, in the root directory, run the following command in your terminal to start your Vue CLI application running on a local development server:

      This will open the application in your browser on localhost:8080. The port number may be different on your machine.

      Visit the address in your browser. You will find the following start up screen:

      Vue default template page

      Next, start a new terminal and open your App.vue file in your src folder. In this file, delete the img and HelloWorld tags in the <template> and the components section and import statement in the <script>. Your App.vue will resemble the following:

      sfc-project/src/App.vue

      <template>
      
      </template>
      
      <script>
      export default {
        name: 'App',
      }
      </script>
      
      <style>
      #app {
        font-family: Avenir, Helvetica, Arial, sans-serif;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        text-align: center;
        color: #2c3e50;
        margin-top: 60px;
      }
      </style>
      

      After this, import the us-airports.js file that you created earlier. In order to make this data reactive so you can use it in the <template>, you need to import the ref function from vue. You will need to return the airport reference so the data can be used in the HTML template.

      Add the following highlighted lines:

      sfc-project/src/App.vue

      <template>
        <div class="wrapper">
          <div v-for="airport in airports" :key="airport.abbreviation" class="card">
            <p>{{ airport.abbreviation }}</p>
            <p>{{ airport.name }}</p>
            <p>{{ airport.city }}, {{ airport.state }}</p>
          </div>
        </div>
      </template>
      
      <script>
      import { ref } from 'vue'
      import data from '@/data/us-airports.js'
      
      export default {
        name: 'App',
        setup() {
          const airports = ref(data)
      
          return { airports }
        }
      }
      </script>
      ...
      

      In this snippet, you imported the data and rendered it using <div> elements and the v-for directive in the template.

      At this point, the data is imported and ready to be used in the App.vue component. But first, add some styling to make the data easier for users to read. In this same file, add the following CSS in the <style> tag:

      sfc-project/src/App.vue

      ...
      <style>
      #app { ... }
      
      .wrapper {
        display: grid;
        grid-template-columns: 1fr 1fr 1fr;
        grid-column-gap: 1rem;
        max-width: 960px;
        margin: 0 auto;
      }
      
      .card {
        border: 3px solid;
        border-radius: .5rem;
        padding: 1rem;
        margin-bottom: 1rem;
      }
      
      .card p:first-child {
        font-weight: bold;
        font-size: 2.5rem;
        margin: 1rem 0;
      }
      
      .card p:last-child {
        font-style: italic;
        font-size: .8rem;
      }
      </style>
      

      In this case, you are using CSS Grid to compose these cards of airport codes into a grid of three. Notice how this grid is set up in the .wrapper class. The .card class is the card or section that contains each airport code, name, and location. If you would like to learn more about CSS, check out our How To Style HTML with CSS.

      Open your browser and navigate to localhost:8080. You will find a number of cards with airport codes and information:

      Three airport cards rendering the data for the US airports dataset

      Now that you have set up your initial app, you can refactor the data into a Single-File Component in the next step.

      Step 2 — Creating a Single-File Component

      Since Vue CLI uses Webpack to build your app into something the browser can read, your app can use SFCs or .vue files instead of plain JavaScript. These files are a way for you to create small blocks of scalable and reusable code. If you were to change one component, it would be updated everywhere.

      These .vue components usually consist of these three things: <template>, <script>, and <style> elements. SFC components can either have scoped or unscoped styles. When a component has scoped styles, that means the CSS between the <style> tags will only affect the HTML in the <template> in the same file. If a component has un-scoped styles, the CSS will affect the parent component as well as its children.

      With your project successfully set up, you are now going to break these airport cards into a component called AirportCards.vue. As it stands now, the HTML in the App.vue is not very reusable. You will break this off into its own component so you can import it anywhere else into this app while preserving the functionality and visuals.

      In your terminal, create this .vue file in the components directory:

      • touch src/components/AirportCards.vue

      Open the AiportCards.vue component in your text editor. To illustrate how you can re-use blocks of code using components, move most of the code from the App.vue file to the AirportCards.vue component:

      sfc-project/src/components/AirportCards.vue

      <template>
        <div class="wrapper">
          <div v-for="airport in airports" :key="airport.abbreviation" class="card">
            <p>{{ airport.abbreviation }}</p>
            <p>{{ airport.name }}</p>
            <p>{{ airport.city }}, {{ airport.state }}</p>
          </div>
        </div>
      </template>
      
      <script>
      import { ref } from 'vue'
      import data from '@/data/us-airports.js'
      
      export default {
        name: 'Airports',
        setup() {
          const airports = ref(data)
      
          return { airports }
        }
      }
      </script>
      
      <style scoped>
      .wrapper {
        display: grid;
        grid-template-columns: 1fr 1fr 1fr;
        grid-column-gap: 1rem;
        max-width: 960px;
        margin: 0 auto;
      }
      
      .card {
        border: 3px solid;
        border-radius: .5rem;
        padding: 1rem;
        margin-bottom: 1rem;
      }
      
      .card p:first-child {
        font-weight: bold;
        font-size: 2.5rem;
        margin: 1rem 0;
      }
      
      .card p:last-child {
        font-style: italic;
        font-size: .8rem;
      }
      </style>
      

      Save and close the file.

      Next, open your App.vue file. Now you can clean up the App.vue component and import AirportCards.vue into it:

      sfc-project/src/App.vue

      <template>
        <AirportCards />
      </template>
      
      <script>
      import AirportCards from '@/components/Airports.vue'
      
      export default {
        name: 'App',
        components: {
          AirportCards
        }
      }
      </script>
      
      <style scoped>
      #app {
        font-family: Avenir, Helvetica, Arial, sans-serif;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        text-align: center;
        color: #2c3e50;
        margin-top: 60px;
      }
      </style>
      

      Now that AirportCards is a standalone component, you have put it in the <template> HTML as you would a <p> tag.

      When you open up localhost:8080 in your browser, nothing will change. The same three airport cards will still display, because you are rendering the new SFC in the <AirportCards /> element.

      Next, add this same component in the template again to illustrate the re-usability of components:

      /src/App.vue

      <template>
        <AirportCards />
        <airport-cards />
      </template>
      ...
      

      You may notice that this new instance of AirportCards.vue is using kebab-case over PascalCase. When referencing components, Vue does not care which one you use. All capitalized words and letters will be separated by a hyphen and will be lower case. The same applies to props as well, which will be explained in the next section.

      Note: The case that you use is up to personal preference, but consistency is important. Vue.js recommends using kebab-case as it follows the HTML standard.

      Open the browser and visit localhost:8080. You will find the cards duplicated:

      The US airport cards rendered twice in the browser.

      This adds modularity to your app, but the data is still static. The row of cards is useful if you want to show the same three airports, but changing the data source would require changing the hard-coded data. In the next step, you are going to expand this component further by registering props and passing data from the parent down to the child component.

      Step 3 — Leveraging Props to Pass Down Data

      In the previous step, you created an AirportCards.vue component that rendered a number of cards from the data in the us-airports.js file. In addition to that, you also doubled the same component reference to illustrate how you can easily duplicate code by adding another instance of that component in the <template>.

      However, leaving the data static will make it difficult to change the data in the future. When working with SFCs, it can help if you think of components as functions. These functions are components that can take in arguments (props) and return something (HTML). For this case, you will pass data into the airports parameter to return dynamic HTML.

      Open the AirportCards.vue component in your text editor. You are currently importing data from the us-airports.js file. Remove this import statement, as well as the setup function in the <script> tag:

      sfc-project/src/components/AirportCards.vue

      ...
      <script>
      
      export default {
        name: 'Airports',
      }
      </script>
      ...
      

      Save the file. At this point, nothing will render in the browser.

      Next, move forward by defining a prop. This prop can be named anything; it just describes the data coming in and associates it with a name.

      To create a prop, add the props property in the component. The value of this is a series of key/value pairs. The key is the name of the prop, and the value is the description of the data. It’s best to provide as much description as you can:

      sfc-project/src/components/AirportCards.vue

      ...
      <script>
      
      export default {
        name: 'Airports',
        props: {
          airports: {
            type: Array,
            required: true
          }
        }
      }
      </script>
      ...
      

      Now, in AirportCard.vue, the property airports refers to the data that is passed in. Save and exit from the file.

      Next, open the App.vue component in your text editor. Like before, you will need to import data from the us-airports.js file and import the ref function from Vue to make it reactive for the HTML template:

      sfc-project/src/App.vue

      <template>
        <AirportCards :airports="usAirports" />
        <airport-cards />
      </template>
      
      <script>
      import { ref } from 'vue'
      import AirportCards from '@/components/Airports.vue'
      import usAirportData from '@/data/us-airports.js'
      
      export default {
        name: 'App',
        components: {
          AirportCards
        },
        setup() {
          const usAirports = ref(usAirportData)
      
          return { usAirports }
        }
      }
      </script>
      

      If you open your browser and visit localhost:8080, you will find the same US airports as before:

      US airports rendered on cards in the browser

      There is another AirportCards.vue instance in your template. Since you defined props within that component, you can pass any data with the same structure to render a number of cards from different airports. This is where the eu-airports.js file from the initial setup comes in.

      In App.vue, import the eu-airports.js file, wrap it in the ref function to make it reactive, and return it:

      /src/App.vue

      <template>
        <AirportCards :airports="usAirports" />
        <airport-cards :airports="euAirports" />
      </template>
      
      <script>
      ...
      import usAirportData from '@/data/us-airports.js'
      import euAirportData from '@/data/eu-airports.js'
      
      export default {
        ...
        setup() {
          const usAirports = ref(usAirportData)
          const euAirports = ref(euAirportData)
      
          return { usAirports, euAirports }
        }
      }
      </script>
      ...
      

      Open your browser and visit localhost:8080. You will find the European airport data rendered below the US airport data:

      US airport data rendered as cards, followed by European airport data rendered in the same way.

      You have now successfully passed in a different dataset into the same component. With props, you are essentially re-assigning data to a new name and using that new name to reference data in the child component.

      At this point, this application is starting to become more dynamic. But there is still something else that you can do to make this even more focused and re-usable. In Vue.js, you can use something called slots. In the next step, you are going to create a Card.vue component with a default slot that injects the HTML into a placeholder.

      Step 4 — Creating a General Card Component Using Slots

      Slots are a great way to create re-usable components, especially if you do not know if the HTML in that component will be similar. In the previous step, you created another AirportCards.vue instance with different data. In that example, the HTML is the same for each. It’s a <div> in a v-for loop with paragraph tags.

      Open your terminal and create a new file using the touch command. This file will be named Card.vue:

      • touch src/components/Card.vue

      In your text editor, open the new Card.vue component. You are going to take some of the CSS from AirportCards.vue and add it into this new component.

      Create a <style> tag and add in the following CSS:

      sfc-project/src/components/Card.vue

      <style>
      .card {
        border: 3px solid;
        border-radius: .5rem;
        padding: 1rem;
        margin-bottom: 1rem;
      }
      </style>
      

      Next, create the HTML template for this component. Before the <style> tag, add a <template> tag with the following:

      sfc-project/src/components/Card.vue

      <template>
        <div class="card">
      
        </div>
      </template>
      ...
      

      In between the <div class="card">, add the <slot /> component. This is a component that is provided to you by Vue. There is no need to import this component; it is globally imported by Vue.js:

      sfc-project/src/components/Card.vue

      <template>
        <div class="card">
          <slot />
        </div>
      </template>
      

      This slot is a placeholder for the HTML that is between the Card.vue component’s tags when it is referenced elsewhere.

      Save and exit the file.

      Now go back to the AirportCards.vue component. First, import the new Card.vue SFC you just created:

      sfc-project/src/components/AirportCards.vue

      ...
      <script>
      import Card from '@/components/Card.vue'
      
      export default {
        name: 'Airports',
        props: { ... },
        components: {
          Card
        }
      }
      </script>
      ...
      

      Now all that is left is to replace the <div> with <card>:

      /src/components/AirportCards.vue

      <template>
        <div class="wrapper">
          <card v-for="airport in airports" :key="airport.abbreviation">
            <p>{{ airport.abbreviation }}</p>
            <p>{{ airport.name }}</p>
            <p>{{ airport.city }}, {{ airport.state }}</p>
          </card>
        </div>
      </template>
      ...
      

      Since you have a <slot /> in your Card.vue component, the HTML between the <card> tags is injected in its place while preserving all styles that have been associated with a card.

      Save the file. When you open your browser at localhost:8080, you will find the same cards that you’ve had previously. The difference now is that your AirportCards.vue now reference the Card.vue component:

      US airport data rendered as cards, followed by European airport data rendered in the same way.

      To show the power of slots, open the App.vue component in your application and import the Card.vue component:

      sfc-project/src/App.vue

      ...
      <script>
      ...
      import Card from '@/components/Card.vue'
      
      export default {
        ...
        components: {
          AirportCards,
          Card
        },
        setup() { ... }
      }
      </script>
      ...
      

      In the <template>, add the following under the <airport-cards /> instances:

      sfc-project/src/App.vue

      <template>
        <AirportCards :airports="usAirports"/>
        <airport-cards :airports="euAirports" />
        <card>
          <p>US Airports</p>
          <p>Total: {{ usAirports.length }}</p>
        </card>
        <card>
          <p>EU Airports</p>
          <p>Total: {{ euAirports.length }}</p>
        </card>
      </template>
      ...
      

      Save the file and visit localhost:8080 in the browser. Your browser will now render additional elements displaying the number of airports in the datasets:

      US and European airports displayed, along with two cards that display that there are three airports in each dataset

      The HTML between the <card /> tags is not exactly the same, but it still renders a generic card. When leveraging slots, you can use this functionality to create small, re-usable components that have a number of different uses.

      Conclusion

      In this tutorial, you created single-file components and used props and slots to create reusable blocks of code. In the project, you created an AirportCards.vue component that renders a number of airport cards. You then broke up the AirportCards.vue component further into a Card.vue component with a default slot.

      You ended up with a number of components that are dynamic and can be used in a number of different uses, all while keeping code maintainable and in keeping with the D.R.Y. software principle.

      To learn more about Vue components, it is recommended to ready through the Vue documentation. For more tutorials on Vue, check out the How To Develop Websites with Vue.js series page.



      Source link