diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestComputedField.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestComputedField.php
new file mode 100644
index 0000000000..c873ccc00e
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestComputedField.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Drupal\entity_test\Entity;
+
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Field\BaseFieldDefinition;
+use Drupal\entity_test\Plugin\Field\ComputedTestFieldItemList;
+
+/**
+ * An entity used for testing computed field values.
+ *
+ * @ContentEntityType(
+ *   id = "entity_test_computed_field",
+ *   label = @Translation("Entity Test computed field"),
+ *   base_table = "entity_test_computed_field",
+ *   handlers = {
+ *     "views_data" = "Drupal\entity_test\EntityTestViewsData"
+ *   },
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "label" = "name",
+ *   },
+ *   admin_permission = "administer entity_test content",
+ *   links = {
+ *     "add-form" = "/entity_test_computed_field/add",
+ *   },
+ * )
+ */
+class EntityTestComputedField extends EntityTest {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
+    $fields = parent::baseFieldDefinitions($entity_type);
+
+    $fields['computed_string_field'] = BaseFieldDefinition::create('string')
+      ->setLabel('Computed Field Test')
+      ->setComputed(TRUE)
+      ->setClass(ComputedTestFieldItemList::class);
+
+    return $fields;
+  }
+
+}
diff --git a/core/modules/system/tests/modules/entity_test/src/EntityTestViewsData.php b/core/modules/system/tests/modules/entity_test/src/EntityTestViewsData.php
index 3bb0d24c64..eca7335d7e 100644
--- a/core/modules/system/tests/modules/entity_test/src/EntityTestViewsData.php
+++ b/core/modules/system/tests/modules/entity_test/src/EntityTestViewsData.php
@@ -16,6 +16,17 @@ class EntityTestViewsData extends EntityViewsData {
   public function getViewsData() {
     $views_data = parent::getViewsData();
 
+    if ($this->entityType->id() === 'entity_test_computed_field') {
+      $views_data['entity_test_computed_field']['computed_string_field'] = [
+        'title' => t('Computed String Field'),
+        'field' => [
+          'id' => 'field',
+          'default_formatter' => 'string',
+          'field_name' => 'computed_string_field',
+        ],
+      ];
+    }
+
     if ($this->entityType->id() != 'entity_test') {
       return $views_data;
     }
diff --git a/core/modules/system/tests/modules/entity_test/src/Plugin/Field/ComputedTestFieldItemList.php b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/ComputedTestFieldItemList.php
new file mode 100644
index 0000000000..864d33fe06
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/ComputedTestFieldItemList.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Drupal\entity_test\Plugin\Field;
+
+use Drupal\Core\Field\FieldItemList;
+
+/**
+ * A computed field item list.
+ */
+class ComputedTestFieldItemList extends FieldItemList {
+
+  /**
+   * Compute the list property from state.
+   */
+  protected function computedListProperty() {
+    foreach (\Drupal::state()->get('entity_test_computed_field_item_list_value', []) as $delta => $item) {
+      $this->list[$delta] = $this->createItem($delta, $item);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function get($index) {
+    $this->computedListProperty();
+    return isset($this->list[$index]) ? $this->list[$index] : NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIterator() {
+    $this->computedListProperty();
+    return parent::getIterator();
+  }
+
+}
diff --git a/core/modules/views/src/FieldAPIHandlerTrait.php b/core/modules/views/src/FieldAPIHandlerTrait.php
index 74db756cae..ddfd0dae38 100644
--- a/core/modules/views/src/FieldAPIHandlerTrait.php
+++ b/core/modules/views/src/FieldAPIHandlerTrait.php
@@ -45,16 +45,36 @@ protected function getFieldDefinition() {
   }
 
   /**
-   * Gets the field storage configuration.
+   * Gets the field storage definition.
    *
-   * @return \Drupal\field\FieldStorageConfigInterface
-   *   The field storage definition used by this handler
+   * @return \Drupal\Core\Field\FieldStorageDefinitionInterface
+   *   The field storage definition used by this handler.
    */
   protected function getFieldStorageDefinition() {
-    if (!$this->fieldStorageDefinition) {
-      $field_storage_definitions = $this->getEntityManager()->getFieldStorageDefinitions($this->definition['entity_type']);
+    if ($this->fieldStorageDefinition) {
+      return $this->fieldStorageDefinition;
+    }
+
+    $entity_type_id = $this->definition['entity_type'];
+    $base_fields = $this->getEntityManager()->getBaseFieldDefinitions($entity_type_id);
+    $field_storage_definitions = $this->getEntityManager()->getFieldStorageDefinitions($entity_type_id);
+
+    $field_storage = NULL;
+    // @todo Unify 'entity field'/'field_name' instead of converting back and
+    //   forth. https://www.drupal.org/node/2410779
+    if (isset($this->definition['field_name']) && isset($field_storage_definitions[$this->definition['field_name']])) {
       $this->fieldStorageDefinition = $field_storage_definitions[$this->definition['field_name']];
     }
+    elseif (isset($this->definition['entity field']) && isset($field_storage_definitions[$this->definition['entity field']])) {
+      $this->fieldStorageDefinition = $field_storage_definitions[$this->definition['entity field']];
+    }
+    elseif (isset($this->definition['field_name']) && isset($base_fields[$this->definition['field_name']])) {
+      // Add support for base field definitions which are compatible with
+      // storage definitions, for fields which are computed (such as
+      // moderation_state) and do not have storage.
+      $this->fieldStorageDefinition = $base_fields[$this->definition['field_name']]->getFieldStorageDefinition();
+    }
+
     return $this->fieldStorageDefinition;
   }
 
diff --git a/core/modules/views/src/Plugin/views/field/EntityField.php b/core/modules/views/src/Plugin/views/field/EntityField.php
index 25b0a556a5..340ab84275 100644
--- a/core/modules/views/src/Plugin/views/field/EntityField.php
+++ b/core/modules/views/src/Plugin/views/field/EntityField.php
@@ -316,27 +316,6 @@ public function clickSort($order) {
   }
 
   /**
-   * Gets the field storage of the used field.
-   *
-   * @return \Drupal\Core\Field\FieldStorageDefinitionInterface
-   */
-  protected function getFieldStorageDefinition() {
-    $entity_type_id = $this->definition['entity_type'];
-    $field_storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id);
-
-    $field_storage = NULL;
-    // @todo Unify 'entity field'/'field_name' instead of converting back and
-    //   forth. https://www.drupal.org/node/2410779
-    if (isset($this->definition['field_name'])) {
-      $field_storage = $field_storage_definitions[$this->definition['field_name']];
-    }
-    elseif (isset($this->definition['entity field'])) {
-      $field_storage = $field_storage_definitions[$this->definition['entity field']];
-    }
-    return $field_storage;
-  }
-
-  /**
    * {@inheritdoc}
    */
   protected function defineOptions() {
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.computed_field_view.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.computed_field_view.yml
new file mode 100644
index 0000000000..d8de3f1883
--- /dev/null
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.computed_field_view.yml
@@ -0,0 +1,171 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - entity_test
+id: computed_field_view
+label: 'Computed Field View'
+module: views
+description: ''
+tag: ''
+base_table: entity_test_computed_field
+base_field: id
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: none
+        options: {  }
+      cache:
+        type: tag
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: mini
+        options:
+          items_per_page: 10
+          offset: 0
+          id: 0
+          total_pages: null
+          expose:
+            items_per_page: false
+            items_per_page_label: 'Items per page'
+            items_per_page_options: '5, 10, 25, 50'
+            items_per_page_options_all: false
+            items_per_page_options_all_label: '- All -'
+            offset: false
+            offset_label: Offset
+          tags:
+            previous: ‹‹
+            next: ››
+      style:
+        type: default
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          uses_fields: false
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        computed_string_field:
+          id: computed_string_field
+          table: entity_test_computed_field
+          field: computed_string_field
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: string
+          settings:
+            link_to_entity: false
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: entity_test_computed_field
+          plugin_id: field
+      filters: {  }
+      sorts: {  }
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments: {  }
+      display_extenders: {  }
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url.query_args
+      tags: {  }
+  page_1:
+    display_plugin: page
+    id: page_1
+    display_title: Page
+    position: 1
+    display_options:
+      display_extenders: {  }
+      path: foo
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url.query_args
+      tags: {  }
diff --git a/core/modules/views/tests/src/Kernel/Handler/ComputedFieldTest.php b/core/modules/views/tests/src/Kernel/Handler/ComputedFieldTest.php
new file mode 100644
index 0000000000..8f85f69018
--- /dev/null
+++ b/core/modules/views/tests/src/Kernel/Handler/ComputedFieldTest.php
@@ -0,0 +1,57 @@
+<?php
+
+namespace Drupal\Tests\views\Kernel\Handler;
+
+use Drupal\entity_test\Entity\EntityTestComputedField;
+use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
+use Drupal\views\Views;
+
+/**
+ * Provides some integration tests for the Field handler.
+ *
+ * @see \Drupal\views\Plugin\views\field\EntityField
+ * @group views
+ */
+class ComputedFieldTest extends ViewsKernelTestBase {
+
+  /**
+   * Views to be enabled.
+   *
+   * @var array
+   */
+  public static $testViews = ['computed_field_view'];
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['entity_test'];
+
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
+
+    $this->installEntitySchema('entity_test_computed_field');
+  }
+
+  /**
+   * Test the computed field handler.
+   */
+  public function testComputedFieldHandler() {
+    \Drupal::state()->set('entity_test_computed_field_item_list_value', ['computed string']);
+
+    $entity = EntityTestComputedField::create([]);
+    $entity->save();
+
+    $view = Views::getView('computed_field_view');
+
+    $rendered_view = $view->preview();
+    $output = $this->container->get('renderer')->renderRoot($rendered_view);
+    $this->assertContains('computed string', (string) $output);
+  }
+
+}
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php
index e0bf6551ff..12c4c75855 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php
@@ -16,6 +16,7 @@
 use Drupal\Core\TypedData\ListInterface;
 use Drupal\Core\TypedData\Type\StringInterface;
 use Drupal\Core\TypedData\TypedDataInterface;
+use Drupal\entity_test\Entity\EntityTestComputedField;
 use Drupal\node\Entity\Node;
 use Drupal\node\Entity\NodeType;
 
@@ -738,6 +739,16 @@ public function testComputedProperties() {
   }
 
   /**
+   * Test computed fields.
+   */
+  public function testComputedFields() {
+    \Drupal::state()->set('entity_test_computed_field_item_list_value', ['foo computed']);
+
+    $entity = EntityTestComputedField::create([]);
+    $this->assertEquals($entity->computed_string_field->value, 'foo computed');
+  }
+
+  /**
    * Executes the computed properties tests for the given entity type.
    *
    * @param string $entity_type
