I read a few stories about math lately. One of them is a story by Kevin Hartnett about Francis Su, who believes math can be a gateway to a better life. To Live Your Best Life, Do Mathematics.:
Christopher, an inmate serving a long sentence for armed robbery who had begun to teach himself math from textbooks he had ordered. After seven years in prison, during which he studied algebra, trigonometry, geometry and calculus, he wrote to Su asking for advice on how to continue his work. After Su told this story, he asked the packed ballroom at the Marriott Marquis, his voice breaking: „When you think of who does mathematics, do you think of Christopher?”
If I learn mathematics and I become a better thinker, I develop perseverance, because I know what it’s like to wrestle with a hard problem, and I develop hopefulness that I will actually solve these problems. And some people experience a kind of transcendent wonder that they’re seeing something true about the universe. That’s a source of joy and flourishing.
I was quite proud of my artwork. It looked interesting, saved so much time compared to creating the same design in Illustrator or Photoshop. However, I realised without understanding geometry, there was no chance for me to reach somewhere near to Marius Watz.
Jinju slowly leveled up her math skills, applying it to everything she did along the way.
Of course, this all reminds me of Ana Tudor, who is an unconventional (and at times self-deprecating) mathematician, who uses her considerable math skills to create art with code.
If someone says to you, don’t you miss doing creative stuff, as an engineer? Don’t you miss the creativity of the art world? You can say: I’m working on an infinite canvas capable of any size and shape, that’s already glowing every color possible into the eyes of just about everyone on the planet. And I get to decide the kind of experience, feeling, and emotion they are going to have. How is that not creative?
This is the third part in a five part series about the JavaScript framework, Vue.js. We’ll cover Vue-cli, and talk a little more about real-life development processes.
This is not intended to be a complete guide, but rather an overview of the basics to get you up and running so you can get to know Vue.js and understand what the framework has to offer.
If you haven’t yet read the last section on Vue.js components and props, I highly suggest you do so before reading this section, otherwise, some things we’ll cover will lack context.
Vue offers a really nice cli that gets you up and running with your choice of a few build tools, and really nice simple starter boilerplate. It’s a lovely tool. Before installing vue-cli, you might want to check that your versions of node, and npm or yarn are up-to-date. You’d first want to install vue-cli (the -g helps you install it globally)
$ npm install -g vue-cli
There are many builds available to you, but in our example, we’ll use webpack:
$ vue init webpack <project-name>
You can go through the commands that the output will give you, which will help you cd into the directory, install everything, set up your `package.json` file, and then finally serve up a local dev server at localhost:8080 with the command:
$ npm run dev
You’re up and running! I love that the setup is so clean. You’ll start off with an App file in your `/src/` directory with a `Hello.vue` file in the `/components/` directory. This is really nice because you can see already how you’d set up these files, and how imports and exports might work.
Let’s go over this new `.vue` file extension for a moment, because if you haven’t worked with vue, you won’t have come across it before.
In your `.vue` file, you can place everything you need for your component. We no longer have to wrap our templates in <script type="text/x-template">, now we’ll more semantically create files that follow this logic:
<template>
<div>
<!-- Write your HTML with Vue in here -->
</div>
</template>
<script>
export default {
// Write your Vue component logic here
}
</script>
<style scoped>
/* Write your styles for the component in here */
</style>
I’ve made a repo of Vue snippets for Sublime Text to quickly spin up boilerplate like this for `.vue` files (this is what the snippet vbase would output). There’s also this one for atom, (though it specifies version 1+, and Vue is at v2), and this for vscode.
A few things to note here: just like in React, you have to return exactly one enclosing tag, here I’ve used a div. I’ve also used <g> elements in SVG. It can be anything, but the entire template must be wrapped in the one tag.
You’ll see that we’ll use export default here to write our scripts such as the data function or methods we used previously, but if we were to use components as children in this `.vue` document, we would also have to import them (more on this in a minute).
You can also see that we have a special scoped value on the style tag. This allows us to very easily scope the styles for this component to only this component. We could also use just <style> and it would create styles for the whole application. I typically like to create a base stylesheet for the whole application with common styles like fonts and line-heights, which I’ll @import into the <style> tag of the App.vue file with the help of vue-style-loader. I’ll then use the <style scoped> tag for very particular styles for the template when it calls for it, but really to each their own on this one! The nice thing is that Vue-cli lets you decide how to organize it, and you don’t have to add any other dependencies or modules to scope our styles this way. *heart eyes*.
We spoke briefly about slots before, when we use slots in Vue components with the scoped style tags, they apply to the component that has the slots. This is so helpful, because you can switch out components and change the appearance out very easily. *heartier eyes*
I have to say that in terms of development workflow, working within each particular `.vue` file for my HTML, styles, and JS has been extraordinarily helpful. I love that things are separated enough to see each piece clearly, yet close enough together that I’m not context-shifting. It speeds up my development, and I’ve noticed that markup stays pretty semantic.
You also might notice that your syntax highlighter doesn’t automatically recognize `.vue` files, so I’ve installed this for Sublime Text.
Here is the most basic way of importing/exporting components into a file (vimport:c in vue-sublime snippets)
import New from './components/New.vue';
export default {
components: {
appNew: New
}
}
For more of a real-life example, let’s look at a sample of that last wine-label demo we used, with the components separated out into their own templates:
Note that I’m using the component here to style each slot differently, that’s a really nice way of working, but it’s only one way. There are endless ways you can compose your application with components, slots, and props. The code here also only shows a piece of what’s happening. I’ve made a repo for you to explore, having used Vue-cli from the start to construct this. I highly recommend using Vue-cli in tandem with reading this and building out some components and passing state with props in a simple manner, just to get accustomed to the workflow. It’s very intuitive and quick once you get past the initial setup!
Lifecycle Hooks
Before we talk about lifecycle hooks, we need to backtrack a little and talk about the virtual DOM I mentioned in the first article. I noted that Vue.js has a virtual DOM, but not really what it does.
When you work with something like jQuery, in essence you’re listening to the DOM, and changing things based on those updates. We end up spending a lot of time checking what the DOM is up to, and storing state there. In contrast, a virtual DOM is an abstract representation of a DOM, sort of like a copy, but in this case it will be our master copy. When we work with state the way we have been with Vue in these articles, we’re creating the state ourselves, and then observing when the state changes.
When a Vue instance updates, Vue will check to see if it’s different from what we had previously. If it is indeed different, it will call some of these lifecycle methods, and patch the actual DOM with changes. This is for efficiency, this way the DOM is only updating what it absolutely needs to.
The lifecycle hooks provide you a method so that you might trigger something precisely at different junctures of a component’s lifecycle. Components are mounted when we instantiate them, and in turn unmounted, for instance when we toggle them in a v-if/v-else statement.
Some of the hooks available to you are: beforeCreate, created, beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, and destroyed. The API docs do a good job of describing each if you’d like to dig in further. Here’s a small demo to show how some of them work (check the console):
Note that we use v-if here instead of v-show, as v-if will actually mount and unmount the component, while v-show will only toggle visibility (but it will remain mounted and stay in the DOM). Similarly, <keep-alive></keep-alive> will not be mounted or unmounted, but rather become activated and deactivated- as the component remains mounted, but is not in use.
Just as the methods available on the component bind this automatically, lifecycle hooks also auto-bind to the instance so that you can use the component’s state, and methods. Again, you don’t have to console.log to find out what this refers to! *heartiest eyes* For this reason though, you shouldn’t use an arrow function on a lifecycle method, as it will return the parent instead of giving you nice binding out of the box.
In the following I’m moving a ton of elements when each component is initially mounted, so I’ll use the mounted hook to trigger the corresponding animation for each component. You may have to hit the rerun button in the bottom left corner to see the starting animation.
mounted() {
let audio = new Audio('https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/rain.mp3'),
tl = new TimelineMax();
audio.play();
tl.add("drops");
//drops in
tl.staggerFromTo("#droplet-groups g path", 0.3, {
drawSVG: "0% -10%"
}, {
drawSVG: "100% 110%",
repeat: 3,
repeatDelay: 1,
ease: Sine.easeIn
}, 0.5, "drops");
…
}
There are also beautiful and sophisticated <transition> and <transition-group> components that Vue offers and we use elsewhere in this demo, and we’ll cover these, and why and when to use each in the last post of the series on Animation.
Huge tech companies evangelize for it. It has loads of tech partners and loads of publishers using it. Well-respected companies are building things for it.
There is also a ton of backlash. It’s too easy to break. It gives Google far too much control. It’s not entirely progressive enhancement friendly. Offline development is harder. The caching layer means clicking a link from Google search results shows the site without ever leaving google.com, which is concerning for any number of reasons, a small one being that it makes sharing the URL weird. That’s just a few. I’ve heard quite the laundry list of complaints.
On this episode of ShopTalk we discuss all things AMP with someone on the AMP team (and who’s own blog is entirely AMP) and an entrepreneur building a service around AMP. Do they wonder if AMP is helping or hurting the web? They do.
When learning to write JavaScript without jQuery, I found posts like this (also on SitePoint) quite helpful to reference. Now we’re going through that again, in a way, with ES6 replacing some of what we used libraries to help with.
I imagine if you’re really getting into performance work, you’ll want a firm understanding of this. There are lots of ways to block/delay parts of this process. The job of a perf nerd is to understand when and why that’s happening, evaluate if it’s necessary or not, and tweak things to get to that painting step as soon as possible.
I’m curious if this is generic enough that 100% of all rendering engines work 100% the same way, or if there are significant differences.
Ethan Marcotte, on time- and budget-constrained organizations websites:
Between the urgency of their work and the size of their resources, spending months on a full redesign isn’t something they can afford to do. Given that, a free theme for, say, WordPress can yield a considerable amount of value, especially to budget-constrained organizations. They can launch their redesign more quickly, and continue reaching the people who need their information most.
So Ethan takes a look at a bunch of free themes, so at least a responsible choice can be made there, and finds
the results were surprising: on a 3G connection, the slower themes I tested took anywhere from 45-90 seconds for any content to appear. In other words, the pages took roughly a minute before they were usable.
Pretty rough.
What I find particularly scary is that these are just empty themes. I usually attribute the slowness of sites in this category (off the shelf, slap-a-CMS on it) to be what happens on top of the theme. Stuff like uploading too many/too large of images and installing a million plugins that load their own set of resources.
I think it shows off some recent technology in a new light: saving us from ourselves. HTTP/2 makes concatenating resources less important, and that’s saving us from ourselves and those million plugins individual CSS and JavaScript files. WordPress does responsive images by default now, that’s saving us from ourselves and ensuring we aren’t loading more image than we need. AMP, as a technology, is saying y’all have lost the plot here and we need to save you from yourselves.
If I was going to sum up my experiences with Vue in a sentence, I’d probably say something like „it’s just so reasonable” or „It gives me the tools I want when I want them, and never gets in my way”. Again and again, when learning Vue, I smiled to myself. It just made sense, elegantly.
This is my own introductory take on Vue. It’s the article I wish I had when I was first learning Vue. If you’d like a more non-partisan approach, please visit Vue’s very well thought out and easy to follow Guide.
Article Series:
Rendering, Directives, and Events (You are here!)
Components, Props, and Slots (Coming soon!)
Vue-cli (Coming soon!)
Vuex (Coming soon!)
Animations (Coming soon!)
One of my favorite things about Vue is that it takes all of the successful things from other frameworks, and incorporates them without getting disorganized. Some examples that stand out for me:
A virtual DOM with reactive components that offer the View layer only, props and a Redux-like store similar to React.
Conditional rendering, and services, similar to Angular.
Inspired by Polymer in part in terms of simplicity and performance, Vue offers a similar development style as HTML, styles, and JavaScript are composed in tandem.
Some benefits I’ve enjoyed over Vue’s competitors: cleaner, more semantic API offerings, slightly better performance than React, no use of polyfills like Polymer, and an isolated, less opinionated view than Angular, which is an MVC.
I could go on, but it’s probably better if you read their comprehensive and community-driven comparison with other frameworks. It’s worth a read, but you can skip back to it later if you’d like to dive into the code.
Let’s Get Started!
We can’t kick this off without the obligatory „Hello, world!” example. Let’s do that so you can get up and running:
<div id="app">
{{ text }} Nice to meet Vue.
</div>
If you’re familiar with React, this will have some similarities. We’ve escaped into JavaScript in the middle of the content with the mustache template and used a variable, but one difference is we are working with straight up HTML instead of JSX. JSX is pretty easy to work with, but I do think it’s nice that I don’t have to spend time changing class to className, etc. You’ll also notice that this is pretty lightweight to get up and running.
Now let’s try Vue out with something I really love: loops and conditional rendering.
Conditional Rendering
Let’s say I have a set of items, like navigation, that I know I’m going to reuse. It might make sense to put it in an array to update it in a few places dynamically and consistently. In vanilla JS (with Babel) we might do something like this: create the array, then create an empty string where we add each item wrapped in an <li>, and then wrap all of that in a <ul> and add it to the DOM with innerHTML:
<div id="container"></div>
const items = [
'thingie',
'another thingie',
'lots of stuff',
'yadda yadda'
];
function listOfStuff() {
let full_list = '';
for (let i = 0; i < items.length; i++) {
full_list = full_list + `<li> ${items[i]} </li>`
}
const contain = document.querySelector('#container');
contain.innerHTML = `<ul> ${full_list} </ul>`;
}
listOfStuff();
Pretty clean and declarative. If you’re familiar with Angular, this will likely be familiar to you. I find this to be such a clean and legible way to conditionally render. If you jumped into the code and had to update it, you could do so very easily.
Another really nice offering is dynamic binding with v-model. Check this out:
You’ll probably notice two things about this demo. First, that it really took nothing at all to type directly into the book and dynamically update the text. Vue enables us to very easily set up two-way binding between the <textarea> and the <p> with v-model.
The other thing you might notice is that we’re now putting data in a function. In this example, it would work without doing so. We could have just put it in an object like our earlier examples. But this would only work for the Vue instance and be exactly the same across the application (thus, not so great for individual components). It’s OK for one Vue instance, but this will share data across all of the child components as well. It’s good practice to start putting data in a function because we’ll need to when we start using components and want them to each hold state of their own.
These aren’t the only easy input bindings available to you at all, and even v-if has an alternate, v-show, which won’t mount/unmount the component, but rather, leave it in the DOM and toggle visibility.
There are so many more directives available to you, here’s a sampling of some of the ones I use very often. A lot of these offer shortcuts as well, so I’ll show both. From here on, we’ll mostly use the shortcuts, so it’s good to at least familiarize yourself with them a little bit in this table.
Binding that data is all well and good but only gets us so far without event handling, so let’s cover that next! This is one of my favorite parts. We’ll use the binding and listeners above to listen to DOM events.
There are a few different ways to create usable methods within our application. Just like in vanilla JS, you can pick your function names, but methods are intuitively called, well, methods!
We’re creating a method called increment, and you can see that this automatically binds to this and will refer to the data in this instance and component. I love this kind of automatic binding, it’s so nice to not have to console.log to see what this is referring to. We’re using shorthand @click to bind to the click event here.
Methods aren’t the only way to create a custom function. You can also use watch. The main difference is that methods are good for small, synchronous calculations, while watch is helpful with more tasking or asynchronous or expensive operations in response to changing data. I tend to use watch most often with animations.
Let’s go a little further and see how we’d pass in the event itself and do some dynamic style bindings. If you recall in the table above, instead of writing v-bind, you can use the shortcut :, so we can bind pretty easily to style (as well as other attributes) by using :style and passing in state, or :class. There are truly a lot of uses for this kind of binding.
In the example below, we’re using hsl(), in which hue calculated as a circle of degrees of color that wraps all the way around. This is good for our use as it will never fail, so as we track our mouse in pixels across the screen, the background style will update accordingly. We’re using ES6 template literals here.
You can see that we didn’t even need to pass in the event to the @click handler, Vue will automatically pass it for you to be available as a parameter for the method. (shown as e here).
Also, native methods can also be used, such as event.clientX, and it’s simple to pair them with this instances. In the style binding on the element there’s camel casing for hyphenated CSS properties. In this example, you can see how simple and declarative Vue is to work with.
We don’t even actually need to create a method at all, we could also increase the counter directly inline in the component if the event is simple enough:
You can see that we’re updating the state directly in the @click handler without a method at all- you can also see that we can add a little bit of logic in there as well (as you wouldn’t have lower than zero items on a shopping site). Once this logic gets too complex, though, you sacrifice legibility, so it’s good to move it into a method. It’s nice to have the option for either, though.
Progressive Web Apps (sometimes referred to as PWAs, because everything in tech needs an acronym) is the encapsulating term for websites following a certain approach, that meet particular technical criteria. The „app” involvement in the name isn’t an accident – these creations share much of the functionality that you’ll find in native experiences – but really, they’re just websites.
It’s like if you build a website that is so damn good, you get to have a home screen icon on mobile devices. And good is defined by performance and progressive enhancement.
When you hear people say „I want the web to win” they typically mean „I don’t want to lose the web to proprietary app development”. PWAs seem like an early step toward making web apps not second-class citizens on mobile devices. Maybe there is a future where native app development is web development.
We be tweetin’ all the time about web design and development stuff. In fact, @Real_CSS_Tricks, the official Twitter account for this site, is largely just an outgoing airhorn for the stuff we publish here and interesting things elsewhere. The human beings that operate this site have their own accounts.
It’s pretty interesting to see which tweets take off! Here’s a list of the most popular tweets in the last year or so.
I’d say SVG is normally the best fit for this kind of thing, but this is a damn impressive experiment. I like the websites interface in how you can hover over the parts of CSS and it shows you what part of the icon it is.
I’ve been reminded a few times lately how the web is both is a great enabler, allowing people all over the world to share ideas and build businesses, and a pain in the ass.
The other day, I listened to a gentlemen explain to me his unique startup business, a marketplace connecting two groups of people. It will be a real challenge, I thought, reaching all these people on both sides and getting them to understand how his business can help. He was up for the challenge and making great headway. His biggest problem, he said, was his website. ARG! The website should not be the limiting factor here. It should not be the hard part. The website should be the easy part. The hard part is reaching all those people that can make or break this idea.
A few weekends ago I watched a team come together and, highly reluctantly, spend their entire weekend handling frustrating infrastructure work on their website. Migrations gone haywire; upgrades being harder than they should have been. These people work with web tech, but web tech isn’t their business. Their time is better spent building their business, and on the weekend, resting their brains.
I’m not that worried about these folks. They have the expertise and resources to get through. I am worried about all the people out there who don’t. I’m worried about the people who are entrenched in a website setup that is far too complex for them and actively disrupting their work and business.
With Squarespace, you’re getting a beautifully designed responsive site. You don’t have to worry about upgrades or security. You control everything – you don’t need permission or to call someone to change things on your site. You don’t need to worry about how domain names work, or hosting, or SSL. It makes the website the easy part so you can focus on whatever your hard part is. Plus I’ll worry about you less.
Use the offer code „CSS” at check-out to get 10% off your first purchase.