DEV Community

Cover image for Vue.js–Getting started in Dart (Part 2)
Jermaine
Jermaine

Posted on • Originally published at creativebracket.com

Vue.js–Getting started in Dart (Part 2)

In Part 1 of the series we went through several examples of the Vue.js guide, finishing at Conditionals and Loops.

In this part we will be resuming with the tutorial looking at Handling User Input and Composing With Components.

Watch on YouTube


Handling User Input

In order to attach event listeners that can invoke methods on our Vue instances, we are given the v-on directive to help us handle that.

Provided we have this template in our web/index.html:

<div id="app-5">
  <p>{{ message }}</p>
  <button v-on:click="reverseMessage">Reverse Message</button>
</div>
Enter fullscreen mode Exit fullscreen mode

The JS counterpart looks like this:

var app5 = new Vue({
  el: '#app-5',
  data: {
    message: 'Hello Vue.js!'
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
});
Enter fullscreen mode Exit fullscreen mode

From the solution of Part 1 we are now able to create a Vue instance and set the el and data information. In order for us to be able to define methods, we need to inform our instance of this property.

In web/app.dart, amend the VueOptions anonymous class as follows:

@JS()
@anonymous
class VueOptions {
  external factory VueOptions({
    String el,
    VueDataOptions data,
    VueMethodOptions methods, // <-- Add this line
  });
  external String get el;
  external VueDataOptions get data;
  external VueMethodOptions get methods; // <-- Add this line
}
Enter fullscreen mode Exit fullscreen mode

Next, create the VueMethodOptions factory class in the same file:

@JS()
@anonymous
class VueMethodOptions {
  external factory VueMethodOptions({
    Function reverseMessage,
  });
  external Function get reverseMessage;
}
Enter fullscreen mode Exit fullscreen mode

reverseMessage is the method that is invoked once the button is clicked.

Let's use what we have so far in web/main.dart to invoke our method:

Vue(VueOptions(
  el: '#app-5',
  data: VueDataOptions(
    message: 'Hello Vue.js',
  ),
  methods: VueMethodOptions(
    reverseMessage: () {
      print('Hello, World!');
    }
  )
));
Enter fullscreen mode Exit fullscreen mode

Run the local server(webdev serve --live-reload) and visit http://localhost:8080.

Click the button. You should now see "Hello World!" printed to the console.

So what about this bit below?:

this.message = this.message.split('').reverse().join('')
Enter fullscreen mode Exit fullscreen mode

You'll immediately find that attempting that won't work, since the Vue context is not inside that function. In order to use a Dart function in JavaScript, we need to use the allowInterop or allowInteropCaptureThis wrapper functions in the inbuilt dart:js library:

// In main.dart
import 'dart:js'; // <-- Import this first
..
..
..
Vue(VueOptions(
  el: '#app-5',
  data: VueDataOptions(
    message: 'Hello Vue.js',
  ),
  methods: VueMethodOptions(
    reverseMessage: allowInteropCaptureThis((gotThis) {
      window.console.dir(gotThis);
    })
  )
));
Enter fullscreen mode Exit fullscreen mode

Here, allowInteropCaptureThis is used not just to use a Dart function in JavaScript, but it also captures the this context and makes it available through the first argument of the function. Therefore, running that logic and clicking the button will print the Vue instance to the console.

The Vue instance. And we see the message property 😉

You'll immediately find that doing gotThis.message will give you an error. This is because gotThis is set to a dynamic type by default, and dynamic types do not have a message property.

To resolve we need to cast the argument to the correct type:

// `gotThis` is cast to `Vue`
allowInteropCaptureThis((Vue gotThis) {...});
Enter fullscreen mode Exit fullscreen mode

And inform our factory of the message property:

// In web/app.dart
@JS()
class Vue {
  external factory Vue(VueOptions options);
  external void set seen(bool val);
  external List<Todo> get todos;
  external String get message; // <-- Added this line
  external void set message(String updatedMessage); // <-- Added this line
}
Enter fullscreen mode Exit fullscreen mode

Return to web/main.dart and follow through with the method:

allowInteropCaptureThis((Vue gotThis) {
  gotThis.message = gotThis.message.split('').reversed.toList('').join('');
});
Enter fullscreen mode Exit fullscreen mode

And here we go:

Working reverse message

Watch the full video for a walkthrough of the other examples.

Conclusion

I hope this was insightful and you learned something new today.

Subscribe to my YouTube channel for the latest videos on Dart. Thanks!

Like, share and follow me 😍 for more content on Dart.

Further reading

  1. js package
  2. How to Use JavaScript libraries in your Dart applications
  3. Full-stack web development with Dart

Top comments (0)