Vue.js–Getting started in Dart (Part 2)
Tags: dart, vue, showdev, javascript
Published: 2018-11-12 12:25:56

In [Part 1](https://dev.to/graphicbeacon/vuejsgetting-started-in-dart-part-1-4i3o) 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_.

{% youtube O1E1TAeRlX8 %}

→ [**Watch on YouTube**](https://youtu.be/O1E1TAeRlX8)

---

## 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`:

```html
<div id="app-5">
  <p>{{ message }}</p>
  <button v-on:click="reverseMessage">Reverse Message</button>
</div>
```
The JS counterpart looks like this:

```js
var app5 = new Vue({
  el: '#app-5',
  data: {
    message: 'Hello Vue.js!'
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
});
```
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:

```dart
@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
}
```
Next, create the `VueMethodOptions` factory class in the same file:

```dart
@JS()
@anonymous
class VueMethodOptions {
  external factory VueMethodOptions({
    Function reverseMessage,
  });
  external Function get reverseMessage;
}
```
`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:

```dart
Vue(VueOptions(
  el: '#app-5',
  data: VueDataOptions(
    message: 'Hello Vue.js',
  ),
  methods: VueMethodOptions(
    reverseMessage: () {
      print('Hello, World!');
    }
  )
));
```
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?:

```js
this.message = this.message.split('').reverse().join('')
```
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:

```dart
// 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);
    })
  )
));
```
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 😉](https://thepracticaldev.s3.amazonaws.com/i/mkqrko5yt7xwmjs6hxny.png)

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:

```dart
// `gotThis` is cast to `Vue`
allowInteropCaptureThis((Vue gotThis) {...});
```
And inform our factory of the `message` property:

```dart
// 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
}
```
Return to `web/main.dart` and follow through with the method:

```dart
allowInteropCaptureThis((Vue gotThis) {
  gotThis.message = gotThis.message.split('').reversed.toList('').join('');
});
```
And here we go:

![Working reverse message](https://thepracticaldev.s3.amazonaws.com/i/434evxbf4oatdq3rfsrt.gif)

[**Watch the full video**](https://youtu.be/O1E1TAeRlX8) for a walkthrough of the other examples.

## Conclusion

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

Subscribe to [**my YouTube channel**](https://www.youtube.com/channel/UCHSRZk4k6e-hqIXBBM4b2iA?view_as=subscriber) for the latest videos on Dart. Thanks!

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

## Further reading

1. [js package](https://pub.dartlang.org/packages/js)
2. [How to Use JavaScript libraries in your Dart applications](https://dev.to/graphicbeacon/how-to-use-javascript-libraries-in-your-dart-applications--4mc6)
3. [**Full-stack web development with Dart**](http://bit.ly/2P2N1jC)