One place for hosting & domains

      December 2021

      How To Install and Use the Visual Studio Code (VS Code) Command Line Interface


      Introduction

      Visual Studio Code is a free, open-source, and cross-platform text editor developed primarily by Microsoft. It uses web technologies such as JavaScript and CSS, which has helped facilitate a large ecosystem of community-created plugins to extend its functionality into many different programming languages and features.

      In this tutorial, you’ll install the Visual Studio Code command line interface and learn how to use it to open files and directories, compare changes between files, and install extensions.

      Prerequisites

      To complete this tutorial, you’ll need to have Visual Studio Code installed. Please refer to the official Setting up Visual Studio Code documentation to find out how to install Code for your platform.

      Installing the Visual Studio Code Command Line Interface

      You may need to install the Visual Studio Code command line interface before using it. To do so, first launch the normal Visual Studio Code graphical interface. If this is your first time opening the app, the default screen will have a icon bar along the left, and a default welcome tab:

      A screenshot of the default

      Visual Studio Code provides a built-in command to install its command line interface. Bring up Code’s Command Palette by typing Command+Shift+P on Mac, or Control+Shift+P on Windows and Linux:

      A screenshot of the Visual Studio Code interface with the Command Palette activated, waiting for input to be entered after its '>' prompt

      This will open a prompt near the top of your Code window. Type shell command into the prompt. It should autocomplete to the correct command which will read Shell Command: Install 'code' command in PATH:

      A screenshot of the Visual Studio Code interface, with the Command Palette activated and the "Install 'code' command in PATH" command highlighted

      Press ENTER to run the highlighted command. You may be prompted to enter your administrator credentials to finish the installation process.

      You now have the code command line command installed.

      Verify that the install was successful by running code with the --version flag:

      Output

      1.62.1 f4af3cbf5a99787542e2a30fe1fd37cd644cc31f x64

      If your output includes a version string, you’ve successfully installed the Visual Studio Code command line interface. The next few sections will show you a few ways to use it.

      Opening Files with the code Command

      Running the code command with one or more filenames will open those files in the Visual Studio Code GUI:

      This will open the file1 file in Code.

      This will open all markdown (.md) files in the current directory in Code.

      By default, the files will be opened in an existing Code window if one is available. Use the --new-window flag to force Visual Studio Code to open a new window for the specified files.

      Opening a Directory with the code Command

      Use the code command followed by one or more directory names to open the directories in a new Visual Studio Code window:

      • code directory1 directory2

      Code will open a new window for the directories. Use the --reuse-window flag to tell Code to reuse the existing frontmost window instead.

      Opening a .code-workspace Workspace File with the code Command

      Opening a workspace file with the code command works similar to opening directories:

      • code example.code-workspace

      This will open the example workspace in a new window, unless you reuse an existing window by adding the --reuse-window flag.

      Installing an Extension Using the code Command

      You can install Visual Studio Code extensions using the code command line tool as well. To do so, you’ll first need to know the extension’s unique identifier. To find this information, first navigate to the extension’s page on the Visual Studio Marketplace.

      For instance, here is the page for the Jupyter Notebook extension:

      https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter

      Notice the itemName parameter in the address. This parameter’s value, ms-toolsai.jupyter, is this extension’s unique identifier.

      You can also find this information on the Marketplace page itself, towards the bottom of the right-hand column in the More info section:

      A screenshot of the Jupyter extension's page on the Visual Studio Marketplace, highlighting the 'Unique Identifier ms-toosai.jupyter' unique id information in the page's right-hand column

      Once you have this unique id, you can use it with code --install-extension to install the extension:

      • code --install-extension ms-toolsai.jupyter

      Output

      Installing extension 'ms-toolsai.jupyter'... Extension 'ms-toolsai.jupyter' v2021.11.1001489384 was successfully installed.

      Use the same id with the --uninstall-extension flag to uninstall the extension.

      Showing the Differences Between Two Files Using the code Command

      To show a standard split-screen diff that will highlight the additions, deletions, and changes between two files, use the --diff flag:

      A screenshot of the Visual Studio Code diff interface, with two files side by side, and the second line highlighted, showing a few words have changed between the two versions

      Similar to opening files, this will reuse the frontmost window by default, if one exists. To force a new window to open, use the --new-window flag.

      Piping stdin Into Visual Studio Code Using the code Command

      An important feature of most command line shells is the ability to pipe (or send) the output of one command to the input of the next. In the following command line, notice the | pipe character connecting the ls ~ command to code -:

      This will execute the ls command on the ~ directory, which is a shortcut for the current user’s home directory. The output from ls will be a list of files and directories in your home directory. This will be sent to the code command, where the single - indicates that it should read the piped in text instead of a file.

      code will output some information about the temporary file that it has created to hold the input:

      Output

      Reading from stdin via: /var/folders/dw/ncv0fr3x0xg7tg0c_cvfynvh0000gn/T/code-stdin-jfa

      Then this file will open up in the Code GUI interface:

      A screenshot of Visual Studio Code with a text file open, displaying the text piped in from the ls command. The text is standard directories such as Desktop and Documents, along with file1 and file2 used in the previous section

      This command will continue to wait indefinitely for more input. Press CTRL+C to have code stop listening and return you to your shell.

      Add the --new-window flag to force Code to open a new window for the input.

      Conclusion

      In this tutorial you installed Visual Studio Code’s code command line tool, and used it to open files and directories, compare files, and install extensions.

      To learn more about the code command, you can run its --help function:

      You can also refer to the official Visual Studio Code command line documentation or take a look at our VS Code tag page for more Visual Studio Code tutorials, tech talks, and Q&A.



      Source link

      How To Make Your Vue.js Application DRY with Slots, Mixins, and Composition API


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

      Introduction

      DRY is a programming strategy that stands for “Don’t Repeat Yourself”. It encourages code re-usability through modular architecture, where code is re-used rather than repeated. This often results in code that is dynamic and scalable. In short, this principle guides programmers to avoid repeating code and hardcoding any values in your application.

      Vue.js includes several strategies to modularize and re-use repeated snippets of code. In this tutorial, you will try out these strategies by making a sample Vue.js application DRY. The tutorial will introduce ways to keep your template and script DRY within your component. You will use layout components that establish an HTML structure that you can place content into via slots. Then, you will use mixins, which are JavaScript files that contain data, methods, and computed properties that mix together with existing component options. Finally, you are going to use the new Composition API that was introduced in Vue 3. The Composition API is a different way to structure your components, and promotes the unification of component properties.

      Prerequisites

      Step 1 — Setting Up the Example Application

      To illustrate how you can create scalable and DRY Vue.js code, you’ll first set up an example application. This example application will be a main/detail application that shows a list of airport cards. When clicked, these cards will navigate you to another view with additional details on that airport.

      First, you’ll need to create a new Vue.js application. Do this by running the following command in your terminal:

      • vue create favorite-airports

      When prompted, select Manually select features. The following options to select are: Choose Vue version, Babel, and Router. Once selected, hit the RETURN key and continue filling out the prompts as follows:

      Output

      Vue CLI v4.5.15 ? Please pick a preset: Manually select features ? Check the features needed for your project: Choose Vue version, Babel, Router ? Choose a version of Vue.js that you want to start the project with 3.x ? Use history mode for router? (Requires proper server setup for index fallback in production) Yes ? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files

      Once the favorite-airports project is created, open your terminal window and cd (change directory) into the favroite-airports root folder. Once you’ve changed the directory, create a new directory to hold all of your local data for this project:

      Inside this folder, create a new Javascript file named src/data/airports.js and open it in your text editor of choice. To provide your app with sample data, add the following contents to the file:

      favorite-airports/src/data/airports.js

      export default [
        {
          name: 'Cincinnati/Northern Kentucky International Airport',
          abbreviation: 'CVG',
          city: 'Hebron',
          state: 'KY',
          destinations: {
            passenger: [ 'Toronto', 'Seattle/Tacoma', 'Austin', 'Charleston', 'Denver', 'Fort Lauderdale', 'Jacksonville', 'Las Vegas', 'Los Angeles', 'Baltimore', 'Chicago', 'Detroit', 'Dallas', 'Tampa' ],
            cargo: [ 'Anchorage', 'Baltimore', ' Chicago' , 'Indianapolis', 'Phoenix', 'San Francisco', 'Seattle', 'Louisville', 'Memphis' ]
          }
        },
        {
          name: 'Seattle-Tacoma International Airport',
          abbreviation: 'SEA',
          city: 'Seattle',
          state: 'WA',
          destinations: {
            passenger: [ 'Dublin', 'Mexico City', 'Vancouver', 'Albuquerque', 'Atlanta', 'Frankfurt', 'Amsterdam', 'Salt Lake City', 'Tokyo', 'Honolulu' ],
            cargo: [ 'Spokane', 'Chicago', 'Dallas', ' Shanghai', 'Cincinnati', 'Luxenbourg', 'Anchorage', 'Juneau', 'Calgary', 'Ontario' ]
          }
        },
        {
          name: 'Minneapolis-Saint Paul International Airport',
          abbreviation: 'MSP',
          city: 'Bloomington',
          state: 'MN',
          destinations: {
            passenger: [ 'Dublin', 'Paris', 'Punta Cana', 'Winnipeg', 'Tokyo', 'Denver', 'Tulsa', 'Washington DC', 'Orlando', 'Mexico City' ],
            cargo: [ 'Cincinnati', 'Omaha', 'Winnipeg', 'Chicago', 'St. Louis', 'Portland', 'Philadelphia', 'Milwaukee', 'Ontario' ]
          }
        }
      ]
      

      This is an array of objects consisting of a few airports in the United States. In the main view of this application, you are going to iterate through this data to generate cards consisting of the name, abbreviation, city, and state properties.

      Save data/airports.js and return to the terminal.

      When you’ve completed that step, create a single-file component (SFC) with the name AirportCard.vue. This file will live in the components directory of your project and will contain all the styles and logic for the airport cards. Open AirportCard.vue in your text editor and add the following:

      favorite-airports/src/components/AirportCard.vue

      <template>
        <div class="airport">
          <p>{{ airport.abbreviation }}</p>
          <p>{{ airport.name }}</p>
          <p>{{ airport.city }}, {{ airport.state }}</p>
        </div>
      </template>
      
      <script>
      export default {
        props: {
          airport: {
            type: Object,
            required: true
          }
        }
      }
      </script>
      
      <style scoped>
      .airport {
        border: 3px solid;
        border-radius: .5rem;
        padding: 1rem;
        margin-bottom: 1rem;
      }
      
      .airport p:first-child {
        font-weight: bold;
        font-size: 2.5rem;
        margin: 1rem 0;
      }
      
      .airport p:last-child {
        font-style: italic;
        font-size: .8rem;
      }
      </style>
      

      You may notice that there is some CSS included in this code snippet. In the AirportCard.vue component, the wrapper <div> contains the class of airport. This CSS adds some styling to the generated HTML by adding borders to give each airport the appearance of a “card”. The :first-child and :last-child are pseudo selectors that apply different styling to the first and last <p> tags in the HTML inside the <div> element with the class of airport. In addition to that, you may also notice that this component contains a prop, which in Vue.js is a way to pass data down from a parent component to a child component.

      Save and exit from the file.

      Before wrapping up this setup, replace the existing views/Home.vue component code with the following:

      favorite-airports/src/views/Home.vue

      <template>
        <div class="wrapper">
          <div v-for="airport in airports" :key="airport.abbreviation">
            <airport-card :airport="airport" />
          </div>
        </div>
      </template>
      
      <script>
      import allAirports from '@/data/airports.js'
      import AirportCard from '@/components/AirportCard.vue'
      
      export default {
        components: {
          AirportCard
        },
        data() {
          return {
            airports: allAirports
          }
        }
      }
      </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;
      }
      
      .wrapper {
        display: grid;
        grid-template-columns: 1fr 1fr 1fr;
        grid-column-gap: 1rem;
        max-width: 960px;
        margin: 0 auto;
      }
      
      p,
      h3 {
        grid-column: span 3;
      }
      </style>
      

      This code contains a v-for loop that iterates through the airports.js data and renders a series of AirportCards.vue components with airport data passed in via the prop :airport. Save this code and return to the command line.

      With the project set up, run the local development server using the npm run serve command in your terminal:

      This will start a server on your localhost, usually at port 8080. Open your web browser of choice and visit localhost:8080 to see the following:

      A list of cards rendered in Vue using the v-for directive.

      Now that your example application is set up, in the next step you are going to create two different Vue.js components that you can later use as page layouts.

      Step 2 — Using slot to Create Layout Components

      Layout components are components that use slot elements to compose HTML templates that can be re-used with different content. These are great for when you have multiple templates that you want to re-use, such as a two-column or three-column layout.

      To create a layout component, you’ll first create a directory for them to live in. You could put them in the components folder, but since these components have a very specific job, your project will be more legible to other programmers if you differentiate them. Create a directory called layouts in the src directory:

      Next, create a file in your layouts directory named DefaultLayout.vue. The DefaultLayout.vue component will be a wrapper that contains the view’s content and centers it in the browser window. Open DefaultLayout.vue in your text editor and add the following:

      favorite-airports/src/layouts/DefaultLayout.vue

      <template>
        <div class="default-layout">
          <slot />
        </div>
      </template>
      
      <style scoped>
        .default-layout {
          max-width: 960px;
          margin: 0 auto;
        }
      </style>
      

      This component is a div with a class of default-layout. You can leverage this class to add some styles. The CSS styles you see in the component above restrict its width to a max of 960px, with side margins being automatic. This will center the div horizontally in the browser window. The slot element is a default slot. Anything that is placed between two <layout-default> tags will be injected to where this <slot /> is. You can try this out by refactoring the Home.vue that you modified in the previous step.

      Save your DefaultLayout.vue file. In your text editor, open src/views/Home.vue and import the DefaultLayout.vue component.

      favorite-airports/src/views/Home.vue

      ...
      <script>
      import allAirports from '@/data/airports.js'
      import AirportCard from '@/components/AirportCard.vue'
      import DefaultLayout from '@/layouts/DefaultLayout.vue'
      
      export default {
        components: {
          AirportCard,
          DefaultLayout
        },
        data() {
          return {
            airports: allAirports
          }
        }
      }
      </script>
      ...
      

      With the DefaultLayout.vue component imported, you can now replace the containing <div /> with <default-layout />.

      favorite-airports/src/views/Home.vue

      <template>
        <default-layout class="wrapper">
          <div v-for="airport in airports" :key="airport.abbreviation">
            <airport-card :airport="airport" />
          </div>
        </default-layout>
      </template>
      ...
      

      You can now remove the max-width and margin properties in the .wrapper class that contain and center the div. Save this file, and open localhost:8080 in your browser window. Visually, nothing will change, but you now have a new layout component to contain any content in a centered div.

      Before you move on to the next step, you will create one more layout component. This is going to be a two-column layout. One column will be for supplemental information, and the other will be for the main content of the view. Create a new file at src/layouts/TwoColumnLayout.vue. Once created, open TwoColumnLayout.vue component in your text editor and add the following:

      favorite-airports/src/layouts/TwoColumnLayout.vue

      <template>
        <div class="two-column-layout">
          <aside>
            <slot name="sideBar" />
          </aside>
          <main>
            <slot name="content" />
          </main>
        </div>
      </template>
      
      <style>
        .two-column-layout {
          display: grid;
          grid-template-columns: 1fr 1fr 1fr;
          grid-column-gap: 1rem;
        }
      
        .two-column-layout aside,
        .two-column-layout main {
          border: 1px solid;
          border-radius: 5px;
        }
      
        .two-column-layout aside {
          grid-column: span 1;
        }
      
        .two-column-layout main {
          grid-column: span 2;
        }
      </style>
      

      In this component, you have two named slots, one for the sidebar and the other for the main content. On the containing <div>, you are using CSS to create a grid of three columns, with one spanning one column and the other spanning two.

      To use this layout, create a new view for the airport detail view at src/views/AirportDetail.vue, then add the following code to the new file:

      favorite-airports/src/views/AirportDetail.vue

      <template>
        <two-column-layout>
          <template v-slot:sideBar>
            <p>Sidebar</p>
          </template>
          <template v-slot:content>
            <p>Main Content</p>
          </template>
        </two-column-layout>
      </template>
      
      <script>
      import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
      
      export default {
        components: {
          TwoColumnLayout
        },
      }
      </script>
      

      This new view imports TwoColumnLayout.vue then uses v-slot to fill the named slots with the right content.

      Save this file. To make this view viewable, add a route in the Vue router file:

      favorite-airports/src/router/index.js

      import { createRouter, createWebHistory } from 'vue-router'
      import Home from '../views/Home.vue'
      import AirportDetail from '../views/AirportDetail'
      
      const routes = [
        {
          path: '/',
          name: 'Home',
          component: Home
        },
        {
          path: '/airport/:code',
          name: 'AirportDetail',
          component: AirportDetail
        },
        {
          path: '/about',
          name: 'About',
          // route level code-splitting
          // this generates a separate chunk (about.[hash].js) for this route
          // which is lazy-loaded when the route is visited.
          component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
        }
      ]
      ...
      

      Here you are registering a route that, when visited, will load the AirportDetail.vue component. The :code in the path is an argument that you can leverage later to grab a specific airport’s data.

      Save your file, then open your browser to localhost:8080/airport/cvg. You will find the following:

      The airport detail view, with a sidebar box and a main content box.

      In this step, you created layout components by leveraging slots. These layout components can help keep your app DRY by eliminating duplicate code when creating a structure of the webpage. In the next step, you are going try out mixins to share methods and properties between components.

      Step 3 — Using Mixins to Share Methods and Properties

      Mixins are a way to redistribute reusable component options to any number of components. When a mixin is imported, the mixin’s component options are “mixed in” to the current component. To illustrate this, this step will first run through an example of mixin syntax, and will then add mixins into your example app.

      Say you have two files with unique properties. The first has a data method and a computed property, like the following:

      sample-component

      <script>
        export default {
          data() {
            return {
              firstName: 'Dave',
              lastName: 'Berning'
            }
          },
          computed: {
            fullName() {
              return `${this.firstName} ${this.lastName}`
            }
          }
        }
      </script>
      

      The second is a file containing some component options that you want to re-use:

      someMixin

      export default {
        data() {
          return {
            counter: 0
          }
        },
        methods: {
          increment() {
            this.counter++
          }
        }
      }
      

      You can mix these two files together by importing the mixin (someMixin) into the component (sample-component). In this hypothetical component, you import it with the import keyword and assign it using the mixin property:

      sample-component

      <script>
      import someMixin from '@/mixins/someMixin'
      
      export default {
        data() {
          return {
            firstName: 'Dave',
            lastName: 'Berning'
          }
        },
        mixins: [ 'someMixin' ],
        computed: {
          fullName() {
            return `${this.firstName} ${this.lastName}`
          }
        }
      }
      </script>
      

      When imported, the hypothetical component has access to all methods, data, computed properties, and any other component options that it might contain.

      Next, you will create a mixin that contains a method and a data property. This function will combine the airport name and abbreviation and store it into a data property.

      In your terminal, create a new directory using the mkdir command:

      Make a file named src/mixins/airport.js and export an object containing the follow properties:

      src/mixins/airport.js

      export default {
        data() {
          return {
            airportWithCode: ''
          }
        },
        methods: {
          getAirportWithCode(airport) {
            this.airportWithCode = `${airport.name} - ${airport.abbreviation}`
          }
        }
      }
      

      This object will now have a data method and a method sets the data to an airport’s name and abbreviation. Save this file.

      With this created, import it into the Home.vue view. You are going to leverage this method and data property to display the string that is returned when the user clicks a card:

      src/views/Home.vue

      <template>
        <default-layout class="wrapper">
          <div v-for="airport in airports" :key="airport.abbreviation" @click="getAirportWithCode(airport)">
            <airport-card :airport="airport" />
          </div>
          <p>test: {{ airportWithCode }}</p>
        </default-layout>
      </template>
      
      <script>
      import allAirports from '@/data/airports.js'
      import AirportCard from '@/components/AirportCard.vue'
      import DefaultLayout from '@/layouts/DefaultLayout.vue'
      import airportMixin from '@/mixins/airport.js'
      
        export default {
          components: {
            AirportCard,
            DefaultLayout
          },
          mixins: [ airportMixin ],
          data() {
            return {
              airports: allAirports
            }
          }
        }
      </script>
      ...
      

      Since you have access to the methods and data within that mixin, you can reference them like any other component option. You’ve done this in this code snippet to store an airportWithCode value when the user clicks a card, then render the string value in a paragraph element. Save the file.

      Next, re-use this same mixin in AirportDetail.vue. Open AirportDetail.vue in your text editor, then write a JavaScript filter to return the airport object if the abbreviation matches the :code argument that was defined in the router earlier:

      src/views/AirportDetail.vue

      ...
      <script>
      import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
      import allAirports from '@/data/airports.js'
      
      export default {
        components: {
          TwoColumnLayout
        },
        data() {
          return {
            airport: ''
          }
        },
        methods: {
        getAirportByCode() {
          return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
          }
        },
        mounted() {
          this.airport = this.getAirportByCode()
        }
      }
      </script>
      

      In this snippet, you are creating a new method named getAirportByCode that filters through the airport data and returns the airport object whose abbreviation matches the abbreviation in the route URL. On mounting, you are assigning the airport data property to that object that is returned.

      Save the file. Next, import the mixin you used earlier. You’ll leverage the same data and method properties you did before:

      src/views/AirportDetail.vue

      <template>
        <two-column-layout>
          <template v-slot:sideBar>
            <p>Sidebar</p>
          </template>
          <template v-slot:content>
            <p>Main Content</p>
            <p>{{ airportWithCode }}</p>
          </template>
        </two-column-layout>
      </template>
      
      <script>
      import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
      import allAirports from '@/data/airports.js'
      import airportMixin from '@/mixins/airport.js'
      
      export default {
        components: {
          TwoColumnLayout
        },
        mixins: [ airportMixin ],
        data() { ... },
        methods: { ... },
        mounted() {
          this.airport = this.getAirportByCode()
          this.getAirportWithCode(this.airport)
        }
      }
      </script>
      

      Since you have determined the specific airport with getAirportByCode() and set it to this.airport, you can now use the getAirportWithCode method to set the value of airportWithCode from the mixin. You can then display the value by adding that variable to the template.

      Save this file, and open localhost:8080/airport/cvg in the browser window. You will find the string value of airportWithCode rendered in the main content section, as shown in the following image:

      Detail view of the CVG airport, with the string

      In this step, you used mixins to share methods and computed properties between components. Mixins can be a great way to organize components and leverage reusable code throughout your application. Next, you are going to learn about the new Composition API, why it was created, and how it can improve the composition of your next Vue application.

      Step 4 — Using the Composition API

      The mixins and layout components that you have tried out so far in this tutorial are usable in all major versions of Vue, including Vue 2 and earlier. These constitute the Options API. But in Vue 3 there is another API you can use to make your application DRY: the Composition API.

      The Composition API is a new way to set up components. Instead of having separate sections for data, computed, methods, and props, you have a single setup hook that everything lives in. Within this setup property, everything the component needs to operate before it is created will go in here. Additionally, everything needed to define options in the Options API needs to be imported. But this is not so for the Composition API.

      In this step, you are going to refactor one of your components from using the Options API to the new Composition API.

      In your text editor, open the AirportDetail.vue component. Right now, you have a mixin imported into this component. That mixin provides some functions and data properties. But in the Composition API, everything that your component needs to render will live inside the setup method; there’s no need to import this method.

      Remove your mixin import, and add the setup method under mounted:

      favorite-airports/src/views/AirportDetail.vue

      ...
      <script>
      import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
      import allAirports from '@/data/airports.js'
      
      export default {
        components: { ... },
        methods: {
          getAirportByCode() {
            return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
          }
        },
        mounted() { ... },
        setup() {
      
        }
      }
      </script>
      

      With your setup method created, start refactoring this by adding the new onMounted lifecycle hook. The onMounted function accepts one argument, typically an anonymous function:

      favorite-airports/src/views/AirportDetail.vue

      ...
      <script>
      import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
      import allAirports from '@/data/airports.js'
      import { onMounted } from 'vue'
      
      export default {
        components: { ... },
        methods: {
          getAirportByCode() {
            return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
          }
        },
        mounted() { ... },
        setup() {
          onMounted(() => {
      
          })
        }
      }
      </script>
      

      When this component is mounted, you’ll store the current airport object into a reactive data property. To make a variable or constant reactive, you need to wrap the value in a ref function, which you will import from vue. The name of the constant will be the name of your reference in your setup and template sections of the component. Also, remove the getAirportByCode from methods and define it like a regular JavaScript function inside of setup:

      favorite-airports/src/views/AirportDetail.vue

      ...
      <script>
      import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
      import allAirports from '@/data/airports.js'
      import { onMounted, ref } from 'vue'
      
      export default {
        components: { ... },
        mounted() { ... },
        setup() {
          function getAirportByCode() {
            return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
          }
      
          onMounted(() => {
            const airport = ref(getAirportByCode())
          })
        }
      }
      </script>
      

      After you do that, you can go ahead and delete the old mounted and methods properties from the component file.

      Since you aren’t using a mixin now, you will define getAirportWithCode inside of your setup function and assign it to a variable airportWithCode so you can use it in your view:

      favorite-airports/src/views/AirportDetail.vue

      ...
      <script>
      import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
      import allAirports from '@/data/airports.js'
      import { onMounted, ref } from 'vue'
      
      export default {
        components: {
          TwoColumnLayout
        },
        setup() {
          const airportWithCode = ref('')
      
          function getAirportByCode() {
            return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
          }
      
          function getAirportWithCode(airport) {
            return `${airport.name} - ${airport.abbreviation}`
          }
      
            onMounted(() => {
              const airport = ref(getAirportByCode())
            })
          }
        }
      </script>
      

      One very important thing about reactive data properties with the Composition API is that ref returns an object. To access the values, you need to access its .value property:

      favorite-airports/src/views/AirportDetail.vue

      ...
      <script>
      import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
      import allAirports from '@/data/airports.js'
      import { onMounted, ref } from 'vue'
      
      export default {
        components: {
          TwoColumnLayout
        },
        setup() {
          const airportWithCode = ref('')
      
          function getAirportByCode() {
            return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
          }
      
          function getAirportWithCode(airport) {
            return `${airport.name} - ${airport.abbreviation}`
          }
      
          onMounted(() => {
            const airport = ref(getAirportByCode())
            airportWithCode.value = getAirportWithCode(airport.value)
          })
        }
      }
      </script>
      

      There are now two things that you need to do before this can be completely converted to using the Composition API. The first thing you need to change is this.$route in the getAirportByCode function. In the Composition API, you cannot access the route or router with this.$route and this.$router, respectively.

      To access the route, import the useRoute from the vue-router package. It’s better to save this into a const that you can reference throughout the application:

      favorite-airports/src/views/AirportDetail.vue

      ...
      <script>
      import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
      import allAirports from '@/data/airports.js'
      import { onMounted, ref } from 'vue'
      import { useRoute } from 'vue-router'
      
      export default {
        components: {
          TwoColumnLayout
        },
        setup() {
          const route = useRoute()
          const airportWithCode = ref('')
      
          function getAirportByCode() {
            return allAirports.filter(airport => airport.abbreviation === route.params.code.toUpperCase())[0]
          }
      
          function getAirportWithCode(airport) {
            return `${airport.name} - ${airport.abbreviation}`
          }
      
          onMounted(() => {
            const airport = ref(getAirportByCode())
            airportWithCode.value = getAirportWithCode(airport.value)
          })
        }
      }
      </script>
      

      When that is done, return the object in your setup function. The properties returned in this object can be used in the template:

      favorite-airports/src/views/AirportDetail.vue

      ...
        setup() {
          const route = useRoute()
          const airportWithCode = ref('')
      
          function getAirportByCode() {
            return allAirports.filter(airport => airport.abbreviation === route.params.code.toUpperCase())[0]
          }
      
          function getAirportWithCode(airport) {
            return `${airport.name} - ${airport.abbreviation}`
          }
      
          onMounted(() => {
            const airport = ref(getAirportByCode())
            airportWithCode.value = getAirportWithCode(airport.value)
          })
      
          return { airportWithCode }
        }
      }
      </script>
      

      Save your code and reload localhost:8080/airport/cvg in your browser. After refactoring the code, there will be no change in what is rendered. However, you are now taking advantage of the Composition API.

      Conclusion

      In this tutorial, you tried out a few strategies to make your application DRY. Specifically, you re-used layout components in multiple views, then modularized properties and methods with mixins. Finally, you re-factored your app to use the new Composition API that was introduced in Vue 3. This API is a new way to set up components before they get created, making functional in more situations.

      If you’d like to learn more about Mixins or the Composition API, it’s highly encouraged to review the official Vue documentation. For more tutorials on Vue, check out the How To Develop Websites with Vue.js series page.



      Source link