Code Monkey home page Code Monkey logo

freecodecamp-projects-vue's Introduction

freecodecamp-projects-vue's People

Contributors

ankurinfoniti avatar ashikpaul avatar ashikpaul42 avatar dependabot[bot] avatar gwenf avatar sameergaikwad222 avatar stevetj88 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

freecodecamp-projects-vue's Issues

Accessibility

I'm watching the live stream on YouTube but unable to leave comments during the video so I'll put this here.

<div>s should not be used as a replacement for <button>s

This requires lots of a11y work to make the <div> appear as a <button> to all kinds of users (keyboard, screenreader, etc). To make this easier you can simply remove all styles from the <button> that you are working with to start anew with your styles (as though it were a <div>).

animation

Hi gwenf, great tutorial thanks for sharing 🙂
But isn't it better to avoid the update Function - in this case?🤔

Maybe this works better

/main.js

new Vue({
 el: "#app",
 data: {
   quotes,
   currentQuote: quotes[0],
   animating: false,
 },
 methods: {
   newQuote: function () {
     const num = Math.floor(Math.random() * quotes.length);
     this.currentQuote = quotes[num];
     this.animating = true;
     setTimeout(() => {
       this.animating = false;
     }, 1000);
   },
 },
});

/index.html

  <style>
  .card-text p:nth-child(1){
    transform: translateX(10px);
  }
 .animate {
    animation: fadeInTranslateX ease 1s;
    -webkit-animation: fadeInTranslateX ease 1s;
    -moz-animation: fadeInTranslateX ease 1s;
    -o-animation: fadeInTranslateX ease 1s;
    -ms-animation: fadeInTranslateX ease 1s;
  }
 @keyframes fadeInTranslateX {
   0% {opacity:0;transform: translateX(-5px);}
   100% {opacity:1;      transform: translateX(10px);
   }
 }

 @-moz-keyframes fadeInTranslateX {
   0% {opacity:0;transform: translateX(-5px);}
   100% {opacity:1;      transform: translateX(10px);
   }
 }

 @-webkit-keyframes fadeInTranslateX {
   0% {opacity:0;transform: translateX(-5px);}
   100% {opacity:1;      transform: translateX(10px);
   }
 }

 @-o-keyframes fadeInTranslateX {
   0% {opacity:0;transform: translateX(-5px);}
   100% {opacity:1;      transform: translateX(10px);
   }
 }

 @-ms-keyframes fadeInTranslateX {
   0% {opacity:0;transform: translateX(-5px);}
   100% {opacity:1;      transform: translateX(10px);
   }
  }
</style>

/index.html

          <button @click="newQuote" class="btn btn-primary mt-2" :disabled="animating">
            New Quote
          </button>  /// just in case you want to avoid double clicking

`updated` anonymous function repeatedly calls itself

Summary

As in the title of the issue, the updated function appears to be indirectly called from the code in its body.

Taken from the Vue.js API:

Called after a data change causes the virtual DOM to be re-rendered and patched.

In the details description, Vue.js mentions "in most cases you should avoid changing state inside the hook. To react to state changes, it’s usually better to use a computed property or watcher instead."

  • It may be ideal to use the suggestion above when resolving the issue, assuming my own don't have any merit.
  • Thread #2 already addresses a solution to part of the issue, but since it didn't specifically point out the consequence(s) of the updated function in this case, I suppose I can suggest my own as well.

Reproducing the issue

Pressing the button will cause this recurrent loop to run. Since the code inside it is written to mutate the state of our Vue data object, the function will be called again--and again--and again. Mutating (changing) a variable in the data object that is used for display in the browser will cause this to occur.

This is most apparent either through logging done in the function but is also seen when viewing the HTML of the element with the animate class through the Chrome debugger.

Problematic effects

  • Ultimately, this prevents the animation(s) defined in the style section from ever completing, as they depend on the animating boolean. The state of the variable is changed when the function runs, so any running animation will halt when it sees the animate class removed.
  • It is also worth mentioning that the setTimeout() function will eventually overwhelm the browser. Considering that the updated function makes at least two changes to the data object, it will have to handle twice as many new callers every time this type of issue arises (2, 6, 14, 30, 62, ... calls).

Removing or relocating the code responsible for changing the state of the animating boolean will prevent the problem from occurring, if the updated anonymous function is absolutely needed.

Resolving the issue

For now, it's probably best to break out the code in the updated function to the one that updates the quote itself:

Before

// Assuming this lies in the `methods` object
updateCurrentQuote: function() {
    this.displayedQuote = getRandomQuote(); // const getRandomQuote = () => quotes[Math.floor(Math.random() * quotes.length)];
    console.log('Updated current quote.');
}

// Assuming this lies in the `Vue` instance
updated: function() {
    this.isAnimating = true;
    setTimeout(() => this.isAnimating = false, 1000);
    console.log('updated function ran.');
}

After

updateCurrentQuote: function() {
    this.displayedQuote = getRandomQuote(); // const getRandomQuote = () => quotes[Math.floor(Math.random() * quotes.length)];

    // Added
    this.isAnimating = true;
    setTimeout(() => this.isAnimating = false, 1000);

    console.log('Updated current quote');
}

// At this point, the `updated` anonymous function is removed and code is put into the method above.

Of course, this isn't a perfectly drawn-out solution, but it is a proposal nonetheless. For clarity, I labeled my working solution to the issue below:

Sample

index.html

<!DOCTYPE html>
<!-- ^ Legacy browser compatibility -->
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Random Quote Machine</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <div id="app">
        <div class="container">
            <div class="row">
                <div class="col-sm-6 offset-sm-3">
                    <div class="card mt-5">
                        <div class="card-body">
                            <div class="card-text">
                                <p class="quote-body" :class="{animate: isAnimating}">{{ displayedQuote }}</p>
                                <p class="quote-author">- An individual on the internet</p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="row">
                <div class="col-sm-6 offset-sm-3 d-flex justify-content-left">
                    <!-- Prevent button from being pressed while animation plays -->
                    <button id="quote-button" class="btn btn-primary mt-2" @click="updateCurrentQuote()" :disabled="isAnimating">New Quote</button>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="main.js"></script>
</body>
</html>

style.css

html, body {
    font-family: ubuntu;
}

.animate {
    opacity: 0;
    animation: fadeInTranslateRight ease 1s;
    opacity: 1;
}
 
@keyframes fadeInTranslateRight 
{
   0% {opacity:0; transform: translateX(-5px);}
   100% {opacity:1; transform: translateX(0px); }
}

main.js

const quotes = [
    "Arrogance and confidence are best pals. I say that because I know that, and you probably don't.",
    "Egotism is virtually analogous to the grass on our front lawn. One day, we 'know' everything; the next, we know we don't.",
    "Some of the liberties we have are meant to be shared among others. When another speaks, listen.",
    "There is no cowardice in running from a battle you cannot win.",
    "Life is a genetic paralogue of stories. However grotesque, you are its main character; not the narrator, nor the author.",
    "Coplanarity, cooperation, then coexistence—that is how we are where we are. Be inclined to discover the tales of another, if you ever expect the same to be known about yourself."
];

const getRandomQuote = () => quotes[Math.floor(Math.random() * quotes.length)];

const vue = new Vue({
    el: '#app',

    data:
    {
        quotes,
        displayedQuote: `"${getRandomQuote()}"`,
        isAnimating: false
    },

    methods:
    {
        updateCurrentQuote: function () {
            this.displayedQuote = `"${getRandomQuote()}"`;
            this.isAnimating = true;
            console.log('Updated current quote.');
            setTimeout(() => this.isAnimating = false, 1000);
        }
    },
});

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.