docsifyjs / docsify

🃏 A magical documentation site generator.
https://docsify.js.org
MIT License
27.47k stars 5.67k forks source link

v-model directive not functional when using Vue 3 but works when using Vue 2 #2217

Closed cbalbin closed 1 year ago

cbalbin commented 1 year ago

Bug Report

Steps to reproduce

Created reproducible sandbox below

Create starter project

docsify init ./docs

Add Vue 3 and a global Vue var in VueGlobalOptions. Resulting index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  <meta name="description" content="Description">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
  <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css">

  <!-- Vue 3 -->
  <script src="//cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
</head>
<body>
  <div id="app"></div>
  <script>
    window.$docsify = {
      name: '',
      repo: '',
      vueGlobalOptions: {
        data() {
          return {
            message : '',
          }
        }
      }
    }
  </script>
  <!-- Docsify v4 -->
  <script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
</body>
</html>

Add input with v-model against the message ref defined in vueGlobalOptions to README.md

# Headline
> An awesome project.
<p>Message is: {{ message }}</p>
<input v-model="message">

Start local server

docsify serve docs

Current behaviour

v-model not functional image

Expected behaviour

Expect "Message is:" to update with input

Other relevant information

Swap Vue 3 script tag in index.html with that for Vue 2 and the problem goes away.

<script src="//cdn.jsdelivr.net/npm/vue@2/dist/vue.min.js"></script>

image

Please create a reproducible sandbox

Please see reproducible sandbox below Edit 307qqv236

Mention the docsify version in which this bug was not present (if any)

Unkown

sy-records commented 1 year ago

Vue.js 3.x introduced some significant changes, one of which is the working method of the v-model directive.

In Vue.js 2.x, v-model was used to implement two-way data binding between parent and child components. You could use v-model on any custom components, and this would automatically translate into a value prop and an input event. However, this design seemed too rigid in some use cases.

Therefore, in Vue.js 3.x, components using v-model need to explicitly define receiving a modelValue prop and emitting an update:modelValue event. This means that you can run custom operations when the model value updates. But inversely, this also implies that you can no longer just use v-model on root instances as in Vue 2.x.

see https://v3-migration.vuejs.org/breaking-changes/v-model.html

<p>Message is: {{ message }}</p>

<custom-input v-model="message"></custom-input>
window.$docsify = {
  vueComponents: {
    'custom-input': {
      props: ['modelValue'],
      emits: ['update:modelValue'],
      template: `
        <input
          type="text"
          :value="modelValue"
          @input="$emit('update:modelValue', $event.target.value)"
        />
      `
    }
  }
};
trusktr commented 1 year ago

I think we can close this because this is a difference in Vue 3 API from Vue 2, not a difference in Docsify. Please re-open if I missed something.