diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
similarity index 62%
rename from app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js
rename to app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
index 3c781ccddc89be8ef11512b003b8c2c28456a7cb..0264625a526e22023ef08d208a45841ceda8efa4 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
@@ -1,3 +1,4 @@
+<script>
 import successSvg from 'icons/_icon_status_success.svg';
 import warningSvg from 'icons/_icon_status_warning.svg';
 import simplePoll from '~/lib/utils/simple_poll';
@@ -7,7 +8,10 @@ import statusIcon from '../mr_widget_status_icon.vue';
 import eventHub from '../../event_hub';
 
 export default {
-  name: 'MRWidgetReadyToMerge',
+  name: 'ReadyToMerge',
+  components: {
+    statusIcon,
+  },
   props: {
     mr: { type: Object, required: true },
     service: { type: Object, required: true },
@@ -26,9 +30,6 @@ export default {
       warningSvg,
     };
   },
-  components: {
-    statusIcon,
-  },
   computed: {
     shouldShowMergeWhenPipelineSucceedsText() {
       return this.mr.isPipelineActive;
@@ -217,136 +218,146 @@ export default {
         });
     },
   },
-  template: `
-    <div class="mr-widget-body media">
-      <status-icon :status="iconClass" />
-      <div class="media-body">
-        <div class="mr-widget-body-controls media space-children">
-          <span class="btn-group append-bottom-5">
-            <button
-              @click="handleMergeButtonClick()"
-              :disabled="isMergeButtonDisabled"
-              :class="mergeButtonClass"
-              type="button"
-              class="qa-merge-button">
-              <i
-                v-if="isMakingRequest"
-                class="fa fa-spinner fa-spin"
-                aria-hidden="true" />
-              {{mergeButtonText}}
-            </button>
+};
+</script>
+
+<template>
+  <div class="mr-widget-body media">
+    <status-icon :status="iconClass" />
+    <div class="media-body">
+      <div class="mr-widget-body-controls media space-children">
+        <span class="btn-group append-bottom-5">
+          <button
+            @click="handleMergeButtonClick()"
+            :disabled="isMergeButtonDisabled"
+            :class="mergeButtonClass"
+            type="button"
+            class="qa-merge-button">
+            <i
+              v-if="isMakingRequest"
+              class="fa fa-spinner fa-spin"
+              aria-hidden="true"
+            ></i>
+            {{ mergeButtonText }}
+          </button>
+          <button
+            v-if="shouldShowMergeOptionsDropdown"
+            :disabled="isMergeButtonDisabled"
+            type="button"
+            class="btn btn-sm btn-info dropdown-toggle js-merge-moment"
+            data-toggle="dropdown"
+            aria-label="Select merge moment">
+            <i
+              class="fa fa-chevron-down"
+              aria-hidden="true"
+            ></i>
+          </button>
+          <ul
+            v-if="shouldShowMergeOptionsDropdown"
+            class="dropdown-menu dropdown-menu-right"
+            role="menu">
+            <li>
+              <a
+                @click.prevent="handleMergeButtonClick(true)"
+                class="merge_when_pipeline_succeeds"
+                href="#">
+                <span class="media">
+                  <span
+                    v-html="successSvg"
+                    class="merge-opt-icon"
+                    aria-hidden="true"></span>
+                  <span class="media-body merge-opt-title">Merge when pipeline succeeds</span>
+                </span>
+              </a>
+            </li>
+            <li>
+              <a
+                @click.prevent="handleMergeButtonClick(false, true)"
+                class="accept-merge-request"
+                href="#">
+                <span class="media">
+                  <span
+                    v-html="warningSvg"
+                    class="merge-opt-icon"
+                    aria-hidden="true"></span>
+                  <span class="media-body merge-opt-title">Merge immediately</span>
+                </span>
+              </a>
+            </li>
+          </ul>
+        </span>
+        <div class="media-body-wrap space-children">
+          <template v-if="shouldShowMergeControls()">
+            <label v-if="mr.canRemoveSourceBranch">
+              <input
+                id="remove-source-branch-input"
+                v-model="removeSourceBranch"
+                class="js-remove-source-branch-checkbox"
+                :disabled="isRemoveSourceBranchButtonDisabled"
+                type="checkbox"/> Remove source branch
+            </label>
+
+            <!-- Placeholder for EE extension of this component -->
+            <squash-before-merge
+              v-if="shouldShowSquashBeforeMerge"
+              :mr="mr"
+              :is-merge-button-disabled="isMergeButtonDisabled" />
+
+            <span
+              v-if="mr.ffOnlyEnabled"
+              class="js-fast-forward-message">
+              Fast-forward merge without a merge commit
+            </span>
             <button
-              v-if="shouldShowMergeOptionsDropdown"
+              v-else
+              @click="toggleCommitMessageEditor"
               :disabled="isMergeButtonDisabled"
-              type="button"
-              class="btn btn-sm btn-info dropdown-toggle js-merge-moment"
-              data-toggle="dropdown"
-              aria-label="Select merge moment">
-              <i
-                class="fa fa-chevron-down"
-                aria-hidden="true" />
+              class="js-modify-commit-message-button btn btn-default btn-xs"
+              type="button">
+              Modify commit message
             </button>
-            <ul
-              v-if="shouldShowMergeOptionsDropdown"
-              class="dropdown-menu dropdown-menu-right"
-              role="menu">
-              <li>
-                <a
-                  @click.prevent="handleMergeButtonClick(true)"
-                  class="merge_when_pipeline_succeeds"
-                  href="#">
-                  <span class="media">
-                    <span
-                      v-html="successSvg"
-                      class="merge-opt-icon"
-                      aria-hidden="true"></span>
-                    <span class="media-body merge-opt-title">Merge when pipeline succeeds</span>
-                  </span>
-                </a>
-              </li>
-              <li>
-                <a
-                  @click.prevent="handleMergeButtonClick(false, true)"
-                  class="accept-merge-request"
-                  href="#">
-                  <span class="media">
-                    <span
-                      v-html="warningSvg"
-                      class="merge-opt-icon"
-                      aria-hidden="true"></span>
-                    <span class="media-body merge-opt-title">Merge immediately</span>
-                  </span>
-                </a>
-              </li>
-            </ul>
-          </span>
-          <div class="media-body-wrap space-children">
-            <template v-if="shouldShowMergeControls()">
-              <label v-if="mr.canRemoveSourceBranch">
-                <input
-                  id="remove-source-branch-input"
-                  v-model="removeSourceBranch"
-                  class="js-remove-source-branch-checkbox"
-                  :disabled="isRemoveSourceBranchButtonDisabled"
-                  type="checkbox"/> Remove source branch
-              </label>
-
-              <!-- Placeholder for EE extension of this component -->
-              <squash-before-merge
-                v-if="shouldShowSquashBeforeMerge"
-                :mr="mr"
-                :is-merge-button-disabled="isMergeButtonDisabled" />
-
-              <span
-                v-if="mr.ffOnlyEnabled"
-                class="js-fast-forward-message">
-                Fast-forward merge without a merge commit
-              </span>
-              <button
-                v-else
-                @click="toggleCommitMessageEditor"
-                :disabled="isMergeButtonDisabled"
-                class="js-modify-commit-message-button btn btn-default btn-xs"
-                type="button">
-                Modify commit message
-              </button>
-            </template>
-            <template v-else>
-              <span class="bold js-resolve-mr-widget-items-message">
-                You can only merge once the items above are resolved
-              </span>
-            </template>
-          </div>
+          </template>
+          <template v-else>
+            <span class="bold js-resolve-mr-widget-items-message">
+              You can only merge once the items above are resolved
+            </span>
+          </template>
         </div>
-        <div
-          v-if="showCommitMessageEditor"
-          class="prepend-top-default commit-message-editor">
-          <div class="form-group clearfix">
-            <label
-              class="control-label"
-              for="commit-message">
-              Commit message
-            </label>
-            <div class="col-sm-10">
-              <div class="commit-message-container">
-                <div class="max-width-marker"></div>
-                <textarea
-                  v-model="commitMessage"
-                  class="form-control js-commit-message"
-                  required="required"
-                  rows="14"
-                  name="Commit message"></textarea>
-              </div>
-              <p class="hint">Try to keep the first line under 52 characters and the others under 72</p>
-              <div class="hint">
-                <a
-                  @click.prevent="updateCommitMessage"
-                  href="#">{{commitMessageLinkTitle}}</a>
-              </div>
+      </div>
+      <div
+        v-if="showCommitMessageEditor"
+        class="prepend-top-default commit-message-editor">
+        <div class="form-group clearfix">
+          <label
+            class="control-label"
+            for="commit-message">
+            Commit message
+          </label>
+          <div class="col-sm-10">
+            <div class="commit-message-container">
+              <div class="max-width-marker"></div>
+              <textarea
+                id="commit-message"
+                v-model="commitMessage"
+                class="form-control js-commit-message"
+                required="required"
+                rows="14"
+                name="Commit message"></textarea>
+            </div>
+            <p class="hint">
+              Try to keep the first line under 52 characters and the others under 72
+            </p>
+            <div class="hint">
+              <a
+                @click.prevent="updateCommitMessage"
+                href="#"
+              >
+                {{ commitMessageLinkTitle }}
+              </a>
             </div>
           </div>
         </div>
       </div>
     </div>
-  `,
-};
+  </div>
+</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/dependencies.js b/app/assets/javascripts/vue_merge_request_widget/dependencies.js
index ed15fc6ab0f7ae900764ece35c5a23b302429230..86d52f89d387d1318235914425c9b102b65580a5 100644
--- a/app/assets/javascripts/vue_merge_request_widget/dependencies.js
+++ b/app/assets/javascripts/vue_merge_request_widget/dependencies.js
@@ -27,7 +27,7 @@ export { default as ConflictsState } from './components/states/mr_widget_conflic
 export { default as NothingToMergeState } from './components/states/nothing_to_merge.vue';
 export { default as MissingBranchState } from './components/states/mr_widget_missing_branch.vue';
 export { default as NotAllowedState } from './components/states/mr_widget_not_allowed.vue';
-export { default as ReadyToMergeState } from './components/states/mr_widget_ready_to_merge';
+export { default as ReadyToMergeState } from './components/states/ready_to_merge.vue';
 export { default as ShaMismatchState } from './components/states/sha_mismatch.vue';
 export { default as UnresolvedDiscussionsState } from './components/states/unresolved_discussions.vue';
 export { default as PipelineBlockedState } from './components/states/mr_widget_pipeline_blocked.vue';
diff --git a/changelogs/unreleased/refactor-move-mr-widget-ready-to-merge-vue-component.yml b/changelogs/unreleased/refactor-move-mr-widget-ready-to-merge-vue-component.yml
new file mode 100644
index 0000000000000000000000000000000000000000..90192fae0303e891e64ec069a5863ca200c6d4af
--- /dev/null
+++ b/changelogs/unreleased/refactor-move-mr-widget-ready-to-merge-vue-component.yml
@@ -0,0 +1,5 @@
+---
+title: Move ReadyToMerge vue component
+merge_request: 17545
+author: George Tsiolis
+type: performance
diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb
index 2f2506f08fb5aaea84431fcf935da7b1f870d709..166861e6c4af589dabcb6cc8cf9cbcb02e0164bf 100644
--- a/qa/qa/page/merge_request/show.rb
+++ b/qa/qa/page/merge_request/show.rb
@@ -2,7 +2,7 @@ module QA
   module Page
     module MergeRequest
       class Show < Page::Base
-        view 'app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js' do
+        view 'app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue' do
           element :merge_button
           element :fast_forward_message, 'Fast-forward merge without a merge commit'
         end
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
index 58f683fb3e66a66c3134190da27f500332d60c6e..300b7882d03545574d0ba9ca8b5bbdcb30739b94 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
@@ -1,12 +1,12 @@
 import Vue from 'vue';
-import readyToMergeComponent from '~/vue_merge_request_widget/components/states/mr_widget_ready_to_merge';
+import ReadyToMerge from '~/vue_merge_request_widget/components/states/ready_to_merge.vue';
 import eventHub from '~/vue_merge_request_widget/event_hub';
 import * as simplePoll from '~/lib/utils/simple_poll';
 
 const commitMessage = 'This is the commit message';
 const commitMessageWithDescription = 'This is the commit message description';
 const createComponent = (customConfig = {}) => {
-  const Component = Vue.extend(readyToMergeComponent);
+  const Component = Vue.extend(ReadyToMerge);
   const mr = {
     isPipelineActive: false,
     pipeline: null,
@@ -36,7 +36,7 @@ const createComponent = (customConfig = {}) => {
   });
 };
 
-describe('MRWidgetReadyToMerge', () => {
+describe('ReadyToMerge', () => {
   let vm;
 
   beforeEach(() => {
@@ -49,7 +49,7 @@ describe('MRWidgetReadyToMerge', () => {
 
   describe('props', () => {
     it('should have props', () => {
-      const { mr, service } = readyToMergeComponent.props;
+      const { mr, service } = ReadyToMerge.props;
 
       expect(mr.type instanceof Object).toBeTruthy();
       expect(mr.required).toBeTruthy();