Skip to content

Understanding Side Effects in VueJS

This article was written over 18 months ago and may contain information that is out of date. Some content may be relevant but please refer to the relevant official documentation or available resources for the latest information.

Introduction

In this article, we will talk about side effects in VueJS, and how to prevent some of them. Side effects are not outrightly bad since they might have some usecase like in a setTimeout() function. But we need to try to ensure that we know about these side effects.

What are side effects?

A side effect is when a function changes or modifies data that does not exist in its local scope. A simple example is a function that receives a parameter which is an Array, and inside that function, it changes the data in that array.

Example:

const numberList = [ 1, 2, 3, 4, 5, 6 ];

function addItem( item ) {
  return item.push( ( item.length - 1 ) + 1 );
}

addItem( numberList )
console.log( numberList )

From this example above, we find out that numberList is been mutated when additem is called.

Side Effects in Vue

Example 1: Side Effects in Computed Properties

Lets try to create a side effect example in a computed property.

<template>
<div>
	Unsorted Data: {{ languages }}
</div>
<div>
	Sorted Data: {{ sortLanguages }}
</div>
</template>

<script>
export default {
  name: ‘languages-list’,
  data() {
    return {
       languages: [
           {
              name: "React",
           },
           {
              name: "Vue",
           },
           {
              name: "Angular",
           },
           {
              name: "Svelte",
           }
        ]
     },
  },
  computed: {
    sortLanguages() {
      return this.languages.sort( ( a, b ) => { 
        if ( a.name < b.name )  { return -1; }
        if ( a.name > b.name )  { return 1; }
        return 0;
      } )
    }
  }
}
</script>

From the example above, we would see that the Unsorted Data and Sorted Data are the same. this.languages data model gets mutated when sortedLanguages is referenced. This is a side effect that can result in unexpected behaviours in your application if not properly handled.

Example 2: Side effects wWen Accessing Getters

Lets try to create a side effect example when accessing and assigning a getters data model.

// store/index.js

state: {
	languages: [
        {
            name: "React",
        },
        {
            name: "Vue",
        },
        {
            name: "Angular",
        },
        {
            name: "Svelte",
        }
   ]
},
getters: {
	getLanguages: function ( state ) {
		return state.languages;
	}
},
actions: {
	sortLanguages: function ( context ) {
		const languages = JSON.parse( JSON.stringify( context.getters.getLanguages ) );
    return languages.sort( ( a, b ) => { 
        if ( a.name < b.name )  { return -1; }
        if ( a.name > b.name )  { return 1; }
        return 0;
      } )
  }
}

From this example, we would see that the store gets updated when we call (dispatch) the action sortLanguages. This is a side effect that can result in unexpected behaviours in your application, because the languages state is been mutated.

How Do We Resolve These Side Effects?

  • Shallow clone
  computed: {
    sortLanguages() {
      const languagesClone = this.languages.slice();
      return languagesClone.sort( ( a, b ) => { 
        if ( a.name < b.name )  { return -1; }
        if ( a.name > b.name )  { return 1; }
        return 0;
      } )
    }
  }

When we shallow clone a language's array using the .slice() method, it returns a shallow copy of a portion of the array into a new array object. We do this to prevent a mutation of the language's data model.

  • Deep clone
  computed: {
    sortLanguages() {
      const languagesClone = json.parse( json.stringify( this.languages ) );
      return languagesClone.sort( ( a, b ) => { 
        if ( a.name < b.name )  { return -1; }
        if ( a.name > b.name )  { return 1; }
        return 0;
      } )
    }
  }

To deep clone, we can simply use json.parse(json.stringify(()) on our data model.

JSON.stringify converts the data model to a string which removes references from the data model. JSON.parse converts the string back to an array of objects.

In Vue, side effects that modify reactive properties in the store can be hidden and cause unexpected bugs which can be difficult to trace and debug. It's my hope that this article helps you better identify and respond to side effects in VueJS.

If you have any questions or run into any trouble, feel free to reach out on Twitter or Github.

This Dot is a consultancy dedicated to guiding companies through their modernization and digital transformation journeys. Specializing in replatforming, modernizing, and launching new initiatives, we stand out by taking true ownership of your engineering projects.

We love helping teams with projects that have missed their deadlines or helping keep your strategic digital initiatives on course. Check out our case studies and our clients that trust us with their engineering.

You might also like

Awesome 3D experience with VueJS and TresJS: a beginner's guide cover image

Awesome 3D experience with VueJS and TresJS: a beginner's guide

Awesome 3D experience with VueJS and TresJS: a beginner's guide Vue.js developers are renowned for raving about the ease, flexibility, and speed of development their framework offers. Tres.js builds on this love for Vue by becoming the missing piece for seamless 3D integration. As a Vue layer for Three.js, Tres.js allows you to leverage the power of Three.js, a popular 3D library, within the familiar and beloved world of Vue components. This means you can create stunning 3D graphics and animations directly within your Vue applications, all while maintaining the clean and efficient workflow you've come to expect. TresJS is a library specifically designed to make incorporating WebGL (the web's 3D graphics API) into your Vue.js projects a breeze. It boasts several key features that make 3D development with Vue a joy: - Declarative Approach: Build your 3D scenes like you would any other Vue component, leveraging the power and familiarity of Vue's syntax. This makes it intuitive and easy to reason about your 3D elements. - Powered by Vite: Experience blazing-fast development cycles with Vite's Hot Module Replacement (HMR) that keeps your scenes updated in real-time, even as your code changes. - Up-to-date Features: Tres.js stays on top of the latest Three.js releases, ensuring you have immediate access to the newest features and functionality. - Thriving Ecosystem: The Tres.js ecosystem offers many resources to enhance your development experience. This includes: - Cientos: A collection of pre-built components and helpers that extend the capabilities of Tres.js, allowing you to focus on building your scene's functionality rather than reinventing the wheel (https://cientos.tresjs.org/). - TresLeches: A powerful state management solution specifically designed for 3D applications built with Tres.js (https://tresleches.tresjs.org/). You can try TresJS online using their official Playground or on their StackBlitz starter. But now, let's dive into a quick code example to showcase the simplicity of creating a 3D scene with TresJS. Setup First, install the package: npm install @tresjs/core three And then, if you are using Typescript, be sure to install the types: npm install @types/three -D If you are using Vite, now you need to modify your vite.config.ts file in this way to make the template compiler work with the custom renderer: ` Create our Scene Imagine a 3D scene as a virtual stage. To bring this stage to life, we need a few key players working together: 1. Scene: Think of this as the container that holds everything in your 3D world. It acts as the canvas where all the objects, lights, and the camera reside, defining the overall environment. 2. Renderer: This is the magician behind the curtain, responsible for taking all the elements in your scene and translating them into what you see on the screen. It performs the complex calculations needed to transform your 3D scene into 2D pixels displayed on your browser. 3. Camera: Like a real camera, this virtual camera defines the perspective from which you view your scene. You can position and adjust the camera to zoom in, zoom out, or explore different angles within your 3D world. - To make our camera dynamic and allow canvas exploration, we are going to leverage the client's OrbitControls component. Below are our examples. You will see that we just include the component in our canvas, and it just works. 4. Objects: These actors bring your scene to life. They can be anything from simple geometric shapes like spheres and cubes to complex models like characters or buildings. You create the visual elements that tell your story by manipulating and animating these objects. Starting from the beginning: to create our Scene with TresJS we just need to use our component TresCanvas in our Vue component's template: ` The TresCanvas component is going to do some setup work behind the scenes: - It creates a WebGLRenderer that automatically updates every frame. - It sets the render loop to be called on every frame based on the browser refresh rate. Using the window-size property, we force the canvas to take the width and height of our full window. So with TresCanvas component we have created our Renderer and our Scene. Let's move to the Camera: ` We just have to add the TresPerspectiveCamera component to our scene. NOTE: It's important that all scene-related components live between the TresCanvas component. Now, only the main actor is missing, let's add some styles and our object inside the scene. Our Vue component will now look like: ` And our scene will be: A Mesh is a basic scene object in three.js, and it's used to hold the geometry and the material needed to represent a shape in 3D space. As we can see, we can achieve the same with TresJS using the TresMesh component, and between the default slots, we are just passing our object (a Box in our example). One interesting thing to notice is that we don't need to import anything. That's because TresJS automatically generates a Vue Component based on the three objects you want to use in PascalCase with a Tres prefix. Now, if we want to add some color to our object the Three.js Material class comes to help us. We need to add: ` Conclusion Tres.js not only supercharges Vue.js applications with stunning 3D graphics, but it also integrates seamlessly with Nuxt.js, enabling you to harness the performance benefits of server-side rendering (SSR) for your 3D creations. This opens the door to building exceptional web experiences that are both interactive and performant. With Tres.js, Vue.js developers can leverage a declarative approach, cutting-edge features, and a vast ecosystem to bring their immersive web visions to life. If you want to elevate your Vue.js projects with a new dimension, Tres.js is an excellent choice to explore....

Getting started with Vitepress cover image

Getting started with Vitepress

Getting started with Vitepress to create your blog site Have you heard about Vitepress, but you have not checked it out at it yet? Well, in this article, we are going to cover the basic setup and share what all the fuss about this new fantastic static site generator. If you are looking for something that would allow you to quickly create a static site with Markdown support, search, Light/Dark theme, advertisement, navigation, and much more, then Vitepress is what you are looking for. Suppose you want some proof of Vitepress's power without having to invest any further time, I suggest you head over to the main Vitepress site (vitepress.dev) and experience what Vitepress can do, as the official site is built on Vitepress! What is Vitepress Vitepress is a powerful Static Site Generator powered by Vite mainly used for Documentation and Blogs with the default theme, and open to customization to be used for anything you may need it to with custom themes and theme overrides.. Vitepress power comes from its low learning curve, powerful configuration settings, and the ability to easily customize it. For example, internationalization is built-in, Theme toggling is built-in and even full-site searches require a single line in the config to be set up. What makes Vitepress so powerful is its extensive configuration and the fact that it can be customized by overriding the existing theme, creating your theme, or simply enhancing pages with custom Vue code. Prerequisites To successfully run the following demo, you will need: - Node.js version 18 or higher. - Terminal for accessing VitePress via its command line interface (CLI). - Text Editor with Markdown syntax support. - VSCode is recommended, along with the official Vue extension. Create your project To create the project, we will follow the steps shown in the official Getting Started guide. If you want to set up a Vitepress project quickly, run the following steps: - Create a new folder mkdir vitepress-tutorial - Access the folder cd vitepress-tutorial - Install Vitepress npm add -D vitepress - Run the Wizard npx vitepress init - Answer the questions: - Where should VitePress initialize the config? - Site title - Site Description - Theme - Do you want Typescript support? - run npm run docs:dev - Enjoy your site. After you run the above steps, your Vitepress will be ready and running as shown below What is available out of the box The site comes fully set up with enough to get you started. Let's see what features are available within the software: - Navbar: The site comes with a Navbar that already includes links to our blog pages - Light/Dark theme: Out of the box theming - Home page: Basic Homepage layout - Blogs: Two different blog posts with sidebar navigation All of the above is available with just 4 files! Let's move forward and see how to customize our app. Overriding the homepage It is time to modify our site by accessing its folders. What you will probably notice when opening the site, is that Vitepress follows a very simple file structure, in fact, a new installation just includes 4 extra files on top of the expected package.json and node_modules. Let's update our homepage to make it more unique. Because Vitepress follows a "file-system based router" we can find this file within the root of the project within a file called index.md. This file will be accessible at "/" or "/index.html" of your site. The content of the file is the following: ` As you can see, the file has no code in it, and it is just driven by configuration, or more specifically in this case Markdown frontmatter, that is a set of configurations accepted by markdown files that help you set up your options such as title, description, og:image. We will describe frontmatter in more detail later in the article. Before we jump into modifying the configuration of the file, you should know that Vitepress has a very extensive and well-detailed documentation site where you can find help if you are stuck or would like to learn more. In this case, we are overriding the "home" page, so the documentation can be found here: Home Page Default Theme configuration. If you read the current file within the homepage, you will notice that it defines a "layout" of "home". This layout displays a main header with CTAs and a set of feature blocks. There are three different layouts available in the Default theme: "home", "doc" and "page". The title and description have already been set from the information we provided from the installation wizard. But the rest is just a basic boiler template. Let's see what we can change: 1) Add a hero image. This image can either be externally sourced or saved within the repository. ` 2) Update the action buttons. ` As shown above, Action buttons have two themes "brand" or "alt" and can accept internal or external links. Vitepress is clever enough to set the external links to open in a new tab and set the rel="noreferrer". 3) Change the feature blocks: Features blocks are great for engaging with the user and telling them what makes your site special. This accepts an icon and some text, so let's change ours with the following: ` The homepage is now completed and updated and it should look like this: Please note that what we did on the homepage is just changing the markdown front matter of the "home" layout. What this means is that if you want to, you can easily customise the page further by either adding more blocks to the layout file or actually by writing and styling the rest of the page as normal. Site configuration In this step, we are going learn about the main site configuration and how we can use it to customize our site. The configuration file can be found in the .vitepress folder under the name of "config.mjs". Just like the homepage layout, the configuration used in the preset file is self-explanatory: ` This file is very important and you are probably going to have it open at all times as it is going to be responsible for the layout of the sidebar navigations of your site. In this section, we are going to learn how to use the Vitepress configuration file to achieve the following: - Modify the sidebar navigation - Enable Search - Add Favicon to your site Modify the sidebar navigation The sidebar is the component displayed on the left-hand side of the blog pages. This is not automatically generated, but it is manually set in this file. You can have more than one navigation, so, for example, you could specify sidebar navigation that shows in pages that have "/blog/" within their path and another one for all markdown pages that have "/tutorials/". Let's see how to implement this: ` With the above code, there will be 2 different sidebars. One will just show if the URL includes "/blog" and the other will be displayed if the path includes "tutorials". Clicking on the above items will give a 404 error as we do not have any pages in that specific location. Still, we can easily fix the issue by creating the two folders "blog" and "tutorial" and creating the required files within these folders in our case are "index.md" and "one.md" for the blog and "index.md" and "two.md" for tutorials. The sidebar has further settings like the ability to create a nested tree or create collapsable menus. You can learn more by checking out the the official documentation on default theme sidebar. Enable Search No documentation or blog site is complete until a search is fully implemented on it. Luckily for us, enabling a site-wide search is extremely simple with Vitepress. Vitepress supports two different search types: a full-text search using minisearch and Algolia based search. In this tutorial, we are going to enable the full-text search. This is fully built-in and requires no external accounts. To enable search, we need to add a "Search" parameter within our themeConfig and set the provider to "local". We can add this right below the socialLinks. ` With just a simple config change, our site will now have a full site search working as shown below: The official search documentation has further information about the look and functionality of the search. Add Favicon to your site Even if the site configuration is very extensive, there are times when you will need to add something within the site-wise page that is not available. In this section we are going to learn how to add specific attributes to the of our site, and specifically how to add a favicon. To add custom values to the head, we are going to use the "head" properties available with the Vitepress configuration. The "head" configuration is an array that accepts an array with the element type (eg. link, script, meta), and an object including all the attributes for that specific element. So for example to replicate the following HTML: ` we would define the following head config: ` We can use this technique to set up metadata and even load fonts or Google Analytics. More info in the site-config head Writing your post In the last section of this article, we are going to learn how to actually write a blog post and also learn how to customize the pages with JS and styles. Writing your first page In the previous section, we created a couple of markdown files, but they are currently empty. Let's see how to create beautiful documentation using the built-in feature of Vitepress. In this section, we are going to work on the file stored in /blog/index.md. This file can be accessed in your browser by accessing "http://localhost:5174/blog/index.html". Blog Frontmatter Every file needs to have a frontmatter defined. This is used to define basic information on the page, such as the title, description, and more. For best SEO results, it is best practice to always define a title and description for a new page. We can do this by adding the following code at the top of our file: ` Frontmatter in Markdown files are delimited by the "---". In the above code, we set our title and description. Vitepress frontmatter supports further config like lastUpdates, sidebar, outline, and more. You can find info on the frontmatter-config documentation. Frontmatter has some global configuration, such as title and description, but also "layout specific" settings that are just available on specific layouts. This is clearly explained in the documentation. Blog Markdown Now that our post frontmatter is set, it is time to write the content of it. This is done using a very extensive markdown engine. Let's start with the basics and write a heading with some text and a link as shown below: ` After saving, our development environment will show the following results: Let's add a couple of headings and a table of contents to our document using [[toc]] to the top of our page: ` The above will produce an unordered list with all our links. The last feature that I want to share about the Vitepress markdown engine is the code editors. The markdown engine used in Vitepress offers extensive features when it comes to code rendering. Features available are "code highlight", "code focus", external snippets loading and much more. The full list of features can be found in the markdown docs. Let's implement a simple code snippet with a line of code focused. This can be achieved by adding "// [!code focus]" at the end of our row. Let's give it a try: ` The output of this will be: Customize your blog with Vue In this last section, we will learn how to customize our code by adding js logic, style, and external components. Before we begin, it is important to understand that when you use the default template of Vitepress, your pages are going to be rendered with Vue. This means that we can expand the individual page's functionality by rendering other vue components and/or writing logic and styles directly on the page. To better explain this concept, we are going to create a team page. Create a file called team.md within the root of our repository. This file will be accessible on "http://localhost:5174/team.html" and will be just a simple Markdown file. First, we set up the frontmatter as before. In this case, we have to specify an additional config called "layout". This will ensure the page has no style or components loaded such as sidebar or aside. ` Then we will have to create our team variable, just like a normal Vue component; we can do so by defining a script setup tag and defining the constant there. ` In the above code, we have imported the VPTeamMembers component from the vitepress/theme and defined an array of members. The values used in the members array are hardcoded, but as you may expect, you can load this information directly from an API. We now have to use the "members" variable within our file. We can do so by writing normal JavaScript. The markdown file will evaluate the JavaScript and render it, so in the following example it will render a specific component. ` Before we move forward we need to define some style as the page is unstyled since we have loaded the layout of "page". Just like we did with the tag, we can load a tag and update our styles: ` The completed file will look like this: ` The file above now includes: - A frontmatter that specifies a "page" layout - A script tag that loads an external component and defines a variable - Styles to make the page pretty - Markdown with a custom component The completed team page would render the following: Conclusion Vitepress is an extremely flexible static site generator. Its default theme provides you with everything you need to get started quickly. The ability to load external themes, enhance the current theme, and or write custom code within your page makes this tool extremely powerful. In future articles, we will discover what components are available within the Default Theme and see how you can make the most of your Vitepress site but keep on coding....

How to Style Using SCSS in Nuxt cover image

How to Style Using SCSS in Nuxt

Introduction SASS makes working on large projects more organized. It allows you to use variables, nested rules, mixins, and functions. The preferred styling method in Nuxt is component file styling, and integrating SASS into your project can make your component file styling appear more understandable. How to Import SASS in Nuxt To add SASS after setting up your Nuxt application, we will first install SASS and sass-loader. Let's run either of these commands depending on our package manager. ` Component File Styling With SASS and sass-loader installed in our project, we can now write SCSS in our component file. Lets see an example: ` In the example above, all we need to specify is lang="scss" on the style tag, and we can now write scss in that component. Global File Import and Variables To import SCSS files that are global, like variables and mixins files, we need to install style-resources: ` Next, we can update our nuxt.config.js file by adding the module we just installed to the buildModules. ` Next, let's create a global variables.scss file in our assets/style folder. Add a single variable inside: ` Next, we need to import this file inside the nuxt.config file: ` Now we have the variables in our variables.scss available in all our components for use. Next, let's test it out by updating our button component. ` We have updated our button variant color to be our global SCSS variable ($primary and $white). Mixins Mixins in SASS are used to write styles that can be reused in other parts of the code. Let's create a sample mixin to center an item. ` Next, we need to import our mixin in Nuxt config: ` Now, let's update our button component with our mixin: ` Functions Functions in SASS are used to write complex operations or behaviours that can be reused in other parts of the code. Let's create a function to handle a media query for our application. ` This is a basic example of what a function can be used for. More complex cases, like calculating percentage, can also be done. Let's import our mixin in Nuxt config: ` Let's update our button component with our function: ` We have been able to add SASS to our Nuxt project, and also looked at some ways in which SASS can make our codebase look cleaner. I hope this article has been helpful to you. If you encounter any issues, you can reach out to me on Twitter or Github....

What Sets the Best Autonomous Coding Agents Apart? cover image

What Sets the Best Autonomous Coding Agents Apart?

Must-have Features of Coding Agents Autonomous coding agents are no longer experimental, they are becoming an integral part of modern development workflows, redefining how software is built and maintained. As models become more capable, agents have become easier to produce, leading to an explosion of options with varying depth and utility. Drawing insights from our experience using many agents, let's delve into the features that you'll absolutely want to get the best results. 1. Customizable System Prompts Custom agent modes, or roles, allow engineers to tailor the outputs to the desired results of their task. For instance, an agent can be set to operate in a "planning mode" focused on outlining development steps and gathering requirements, a "coding mode" optimized for generating and testing code, or a "documentation mode" emphasizing clarity and completeness of written artifacts. You might start with the off-the-shelf planning prompt, but you'll quickly want your own tailored version. Regardless of which modes are included out of the box, the ability to customize and extend them is critical. Agents must adapt to your unique workflows and prioritize what's important to your project. Without this flexibility, even well-designed defaults can fall short in real-world use. Engineers have preferences, and projects contain existing work. The best agents offer ways to communicate these preferences and decisions effectively. For example, 'pnpm' instead of 'npm' for package management, requiring the agent to seek root causes rather than offer temporary workarounds, or mandating that tests and linting must pass before a task is marked complete. Rules are a layer of control to accomplish this. Rules reinforce technical standards but also shape agent behavior to reflect project priorities and cultural norms. They inform the agent across contexts, think constraints, preferences, or directives that apply regardless of the task. Rules can encode things like style guidelines, risk tolerances, or communication boundaries. By shaping how the agent reasons and responds, rules ensure consistent alignment with desired outcomes. Roo code is an agent that makes great use of custom modes, and rules are ubiquitous across coding agents. These features form a meta-agent framework that allows engineers to construct the most effective agent for their unique project and workflow details. 2. Usage-based Pricing The best agents provide as much relevant information as possible to the model. They give transparency and control over what information is sent. This allows engineers to leverage their knowledge of the project to improve results. Being liberal with relevant information to the models is more expensive however, it also significantly improves results. The pricing model of some agents prioritizes fixed, predictable costs that include model fees. This creates an incentive to minimize the amount of information sent to the model in order to control costs. To get the most out of these tools, you’ve got to get the most out of models, which typically implies usage-based pricing. 3. Autonomous Workflows The way we accomplish work has phases. For example, creating tests and then making them pass, creating diagrams or plans, or reviewing work before submitting PRs. The best agents have mechanisms to facilitate these phases in an autonomous way. For the best results, each phase should have full use of a context window without watering down the main session's context. This should leverage your custom modes, which excel at each phase of your workflow. 4. Working in the Background The best agents are more effective at producing desired results and thus are able to be more autonomous. As agents become more autonomous, the ability to work in the background or work on multiple tasks at once becomes increasingly necessary to unlock their full potential. Agents that leverage local or cloud containers to perform work independently of IDEs or working copies on an engineer's machine further increase their utility. This allows engineers to focus on drafting plans and reviewing proposed changes, ultimately to work toward managing multiple tasks at once, overseeing their agent-powered workflows as if guiding a team. 5. Integrations with your Tools The Model Context Protocol (MCP) serves as a standardized interface, allowing agents to interact with your tools and data sources. The best agents seamlessly integrate with the platforms that engineers rely on, such as Confluence for documentation, Jira for tasks, and GitHub for source control and pull requests. These integrations ensure the agent can participate meaningfully across the full software development lifecycle. 6. Support for Multiple Model Providers Reliance on a single AI provider can be limiting. Top-tier agents support multiple providers, allowing teams to choose the best models for specific tasks. This flexibility enhances performance, the ability to use the latest and greatest, and also safeguards against potential downtimes or vendor-specific issues. Final Thoughts Selecting the right autonomous coding agent is a strategic decision. By prioritizing the features mentioned, technology leaders can adopt agents that can be tuned for their team's success. Tuning agents to projects and teams takes time, as does configuring the plumbing to integrate well with other systems. However, unlocking massive productivity gains is worth the squeeze. Models will become better and better, and the best agents capitalize on these improvements with little to no added effort. Set your organization and teams up to tap into the power of AI-enhanced engineering, and be more effective and more competitive....

Let's innovate together!

We're ready to be your trusted technical partners in your digital innovation journey.

Whether it's modernization or custom software solutions, our team of experts can guide you through best practices and how to build scalable, performant software that lasts.

Prefer email? hi@thisdot.co