# 与 Vue 一起使用

¥Usage with Vue

Vue 应用中 XState 的使用可能会有所不同,具体取决于应用运行的 Vue 版本。本页面仅关注 Vue 2。要了解如何将 XState 与 Vue 3 结合使用,请查看 XState @xstate/vue 的文档。

¥Usage of XState in a Vue application may vary depending on which version of Vue your application is running. This page focuses on Vue 2 only. To see how to use XState with Vue 3 check the documentation for the XState @xstate/vue package.

你可以通过两种方式将 XState 与 Vue 2 结合使用:

¥There are two ways you can use XState with Vue 2:

  1. 自 Vue ^2.7 起:使用 xstate-vue2 (opens new window)(第 3 方)插件提供的 useMachine 钩子;

    ¥Since Vue ^2.7: using the useMachine hook provided by the xstate-vue2 package (opens new window) (3rd-party) plugin;

  2. 使用 XState interpret 实用程序创建服务并将其注入到你的应用中。

    ¥Using XState interpret utility to create a service and inject it into your app.

提示

如果你想使用 Vue Composition API,我们建议使用以下包:

¥If you want to use the Vue Composition API, we recommend using the following packages:

Vue 遵循与 React 类似的模式:

¥Vue follows a similar pattern to React:

  • 机器可以外部定义;

    ¥The machine can be defined externally;

  • 该服务被放置在 data 对象上;

    ¥The service is placed on the data object;

  • 通过 service.onTransition(state => ...) 观察状态变化,你可以在其中将某些数据属性设置为下一个 state

    ¥State changes are observed via service.onTransition(state => ...), where you set some data property to the next state;

  • 机器的上下文可以被应用引用为外部数据存储。还可以通过 service.onTransition(state => ...) 观察上下文更改,你可以在其中将另一个数据属性设置为更新的上下文;

    ¥The machine's context can be referenced as an external data store by the app. Context changes are also observed via service.onTransition(state => ...), where you set another data property to the updated context;

  • 当组件为 created() 时,服务启动(service.start());

    ¥The service is started (service.start()) when the component is created();

  • 事件通过 service.send(event) 发送到服务。

    ¥Events are sent to the service via service.send(event).

以下秘诀使用以下 toggleMachine

¥The following recipes use the following toggleMachine:

import { createMachine } from 'xstate';

// This machine is completely decoupled from Vue
export const toggleMachine = createMachine({
  id: 'toggle',
  context: {
    /* some data */
  },
  initial: 'inactive',
  states: {
    inactive: {
      on: { TOGGLE: 'active' }
    },
    active: {
      on: { TOGGLE: 'inactive' }
    }
  }
});

# 使用 xstate-vue2 插件中的 useMachine 钩子

¥Using useMachine hook from xstate-vue2 plugin

<!-- toggle.vue -->
<!-- Top level bindigs are pre-processed via "setup" -->
<script setup>
  import { useMachine } from 'xstate-vue2';
  import toggleMachine from '../path/to/toggleMachine';

  const { state, send } = useMachine(toggleMachine);
</script>

<template>
  <main>
    <button @click="send('TOGGLE')">
      {{ state.value === "inactive" ? "Click to activate" : "Active! Click to
      deactivate" }}
    </button>
  </main>
</template>

# 使用 XState interpret

¥Using XState interpret

<!-- Toggle.vue -->
<template>
  <button v-on:click="send('TOGGLE');">
    {{ current.matches("inactive") ? "Off" : "On" }}
  </button>
</template>

<script>
  import { interpret } from 'xstate';
  import { toggleMachine } from '../path/to/toggleMachine';

  export default {
    name: 'Toggle',
    created() {
      // Start service on component creation
      this.toggleService
        .onTransition((state) => {
          // Update the current state component data property with the next state
          this.current = state;
          // Update the context component data property with the updated context
          this.context = state.context;
        })
        .start();
    },
    data() {
      return {
        // Interpret the machine and store it in data
        toggleService: interpret(toggleMachine),

        // Start with the machine's initial state
        current: toggleMachine.initialState,

        // Start with the machine's initial context
        context: toggleMachine.context
      };
    },
    methods: {
      // Send events to the service
      send(event) {
        this.toggleService.send(event);
      }
    }
  };
</script>