Vue3 опыт карты ~

Vue.js
Vue3 опыт карты ~

предисловие

Поскольку vue не совместим с демо в тексте после обновления, позвольте мне еще раз объяснить, что все содержание этой статьи основано на3.0.0-alpha.1Версия написана, друзья, обратите внимание на следующую версию при изучении

Мы все знаем, что сейчас чаще всего используется Vue 2.x, но все мы знаем, что в первой половине этого года, по крайней мере, так сказал автор. Так что многие вещи еще не на 100% уверены, что это так, очень вероятно, что будут изменения, и об этом мы поговорим позже.

Содержимое этой главы в основном написано в соответствии с официальным RFC Vue, потому что содержащаяся в нем информация относительно достоверна.

Отличие от Vue 2.x и личного просмотра

Vue3 чувствует себя немного как Ощущение VUE2 + MOBX + TS + RXJS, если вы использовали эти вещи, вы также можете иметь это чувство

Не сплетничайте о бесполезных, первое - это жизненный цикл Vue3 отказался от beforeCreate, создал и смешал два в одномsetup, На самом деле, в нем также есть основная концепция, то есть vue2.x, каждый, кто ей пользовался, может понять, что это data response, data-centric

То есть наблюдать. Преимущество этого наблюдателя может ощутить каждый, это удобство, а недостаток - производительность, потому что по сути это означает, что я все мониторю.На самом деле, это более неудобно для масштабных приложений, потому что вы не можете это контролировать .И функций больше, и расход тоже большой

Всем известно, что react ничего не отслеживает, если только вы не используете сторонний примерmobxЭто одно, остальные приходится делать вручнуюsetState

Vue3 является одним из этих двух аспектов.Это также то, что Vue официально заявил.Он может не только обеспечить мониторинг, но и иметь нормальную производительность в крупномасштабных приложениях, поэтому вам нужно указать его самостоятельно.Это нужно отслеживать, и тот не отслеживается.


После стольких разговоров, прежде всего, давайтеcloneследующий проект

$ git clone https://github.com/vuejs/vue-next.git
$ cd vue-next && yarn

Клонируйте его, а затем установите.На данный момент вам нужно изменить две вещи, обе в корневом каталоге проекта Соответственноrollup.config.js

плюс output.sourcemap = trueОн был изменен здесь, и друзья, которым это нужно, могут скопировать его напрямую.

import fs from 'fs'
import path from 'path'
import ts from 'rollup-plugin-typescript2'
import replace from '@rollup/plugin-replace'
import json from '@rollup/plugin-json'

if (!process.env.TARGET) {
  throw new Error('TARGET package must be specified via --environment flag.')
}

const masterVersion = require('./package.json').version
const packagesDir = path.resolve(__dirname, 'packages')
const packageDir = path.resolve(packagesDir, process.env.TARGET)
const name = path.basename(packageDir)
const resolve = p => path.resolve(packageDir, p)
const pkg = require(resolve(`package.json`))
const packageOptions = pkg.buildOptions || {}

const knownExternals = fs.readdirSync(packagesDir).filter(p => {
  return p !== '@vue/shared'
})

// ensure TS checks only once for each build
let hasTSChecked = false

const outputConfigs = {
  'esm-bundler': {
    file: resolve(`dist/${name}.esm-bundler.js`),
    format: `es`
  },
  // main "vue" package only
  'esm-bundler-runtime': {
    file: resolve(`dist/${name}.runtime.esm-bundler.js`),
    format: `es`
  },
  cjs: {
    file: resolve(`dist/${name}.cjs.js`),
    format: `cjs`
  },
  global: {
    file: resolve(`dist/${name}.global.js`),
    format: `iife`
  },
  esm: {
    file: resolve(`dist/${name}.esm.js`),
    format: `es`
  }
}

const defaultFormats = ['esm-bundler', 'cjs']
const inlineFormats = process.env.FORMATS && process.env.FORMATS.split(',')
const packageFormats = inlineFormats || packageOptions.formats || defaultFormats
const packageConfigs = process.env.PROD_ONLY
  ? []
  : packageFormats.map(format => createConfig(format, outputConfigs[format]))

if (process.env.NODE_ENV === 'production') {
  packageFormats.forEach(format => {
    if (format === 'cjs' && packageOptions.prod !== false) {
      packageConfigs.push(createProductionConfig(format))
    }
    if (format === 'global' || format === 'esm') {
      packageConfigs.push(createMinifiedConfig(format))
    }
  })
}

export default packageConfigs

function createConfig(format, output, plugins = []) {
  if (!output) {
    console.log(require('chalk').yellow(`invalid format: "${format}"`))
    process.exit(1)
  }

  output.externalLiveBindings = false
  output.sourcemap = true

  const isProductionBuild =
    process.env.__DEV__ === 'false' || /\.prod\.js$/.test(output.file)
  const isGlobalBuild = format === 'global'
  const isRawESMBuild = format === 'esm'
  const isBundlerESMBuild = /esm-bundler/.test(format)
  const isRuntimeCompileBuild = /vue\./.test(output.file)

  if (isGlobalBuild) {
    output.name = packageOptions.name
  }

  const shouldEmitDeclarations =
    process.env.TYPES != null &&
    process.env.NODE_ENV === 'production' &&
    !hasTSChecked

  const tsPlugin = ts({
    check: process.env.NODE_ENV === 'production' && !hasTSChecked,
    tsconfig: path.resolve(__dirname, 'tsconfig.json'),
    cacheRoot: path.resolve(__dirname, 'node_modules/.rts2_cache'),
    tsconfigOverride: {
      compilerOptions: {
        declaration: shouldEmitDeclarations,
        declarationMap: shouldEmitDeclarations
      },
      exclude: ['**/__tests__', 'test-dts']
    }
  })
  // we only need to check TS and generate declarations once for each build.
  // it also seems to run into weird issues when checking multiple times
  // during a single build.
  hasTSChecked = true

  const entryFile =
    format === 'esm-bundler-runtime' ? `src/runtime.ts` : `src/index.ts`

  return {
    input: resolve(entryFile),
    // Global and Browser ESM builds inlines everything so that they can be
    // used alone.
    external:
      isGlobalBuild || isRawESMBuild
        ? []
        : knownExternals.concat(Object.keys(pkg.dependencies || [])),
    plugins: [
      json({
        namedExports: false
      }),
      tsPlugin,
      createReplacePlugin(
        isProductionBuild,
        isBundlerESMBuild,
        (isGlobalBuild || isRawESMBuild || isBundlerESMBuild) &&
          !packageOptions.enableNonBrowserBranches,
        isRuntimeCompileBuild
      ),
      ...plugins
    ],
    output,
    onwarn: (msg, warn) => {
      if (!/Circular/.test(msg)) {
        warn(msg)
      }
    }
  }
}

function createReplacePlugin(
  isProduction,
  isBundlerESMBuild,
  isBrowserBuild,
  isRuntimeCompileBuild
) {
  const replacements = {
    __COMMIT__: `"${process.env.COMMIT}"`,
    __VERSION__: `"${masterVersion}"`,
    __DEV__: isBundlerESMBuild
      ? // preserve to be handled by bundlers
        `(process.env.NODE_ENV !== 'production')`
      : // hard coded dev/prod builds
        !isProduction,
    // this is only used during tests
    __TEST__: isBundlerESMBuild ? `(process.env.NODE_ENV === 'test')` : false,
    // If the build is expected to run directly in the browser (global / esm builds)
    __BROWSER__: isBrowserBuild,
    // is targeting bundlers?
    __BUNDLER__: isBundlerESMBuild,
    // support compile in browser?
    __RUNTIME_COMPILE__: isRuntimeCompileBuild,
    // support options?
    // the lean build drops options related code with buildOptions.lean: true
    __FEATURE_OPTIONS__: !packageOptions.lean && !process.env.LEAN,
    __FEATURE_SUSPENSE__: true
  }
  // allow inline overrides like
  //__RUNTIME_COMPILE__=true yarn build runtime-core
  Object.keys(replacements).forEach(key => {
    if (key in process.env) {
      replacements[key] = process.env[key]
    }
  })
  return replace(replacements)
}

function createProductionConfig(format) {
  return createConfig(format, {
    file: resolve(`dist/${name}.${format}.prod.js`),
    format: outputConfigs[format].format
  })
}

function createMinifiedConfig(format) {
  const { terser } = require('rollup-plugin-terser')
  return createConfig(
    format,
    {
      file: resolve(`dist/${name}.${format}.prod.js`),
      format: outputConfigs[format].format
    },
    [
      terser({
        module: /^esm/.test(format)
      })
    ]
  )
}

И естьtsconfig.json, нужно этоsourceMapизменить наtrue, вот код непосредственно

{
  "compilerOptions": {
    "baseUrl": ".",
    "outDir": "dist",
    "sourceMap": true,
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "allowJs": false,
    "noUnusedLocals": true,
    "strictNullChecks": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "experimentalDecorators": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "removeComments": false,
    "jsx": "preserve",
    "lib": ["esnext", "dom"],
    "types": ["jest", "puppeteer", "node"],
    "rootDir": ".",
    "paths": {
      "@vue/*": ["packages/*/src"]
    }
  },
  "include": [
    "packages/global.d.ts",
    "packages/runtime-dom/jsx.d.ts",
    "packages/*/src",
    "packages/*/__tests__",
    "test-dts"
  ]
}

Затем просто создайте каталог, я называю его здесьpublic, так

затем выполнитьyarn devилиcnpm run dev

затем вhtmlначать импортvue.js

path : ../packages/vue/dist/vue.global.js

упомянутый вышеvueизbeforeCreateа такжеcreatedзаменяетсяsetup, то давайте попробуем.Конечно пример в этой статье непосредственно экспериментировал с cdn.Ведь сейчасvueОфициального релиза нет, многое непонятно, и не обязательно все это сопоставлять

Сделаем немного шаблон, и перейдем непосредственно к коду

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script src="../packages/vue/dist/vue.global.js"></script>
  <div id="app"></div>
  <script>
    var App = {
      template: `
        <div class="container">
        </div>`,

      setup() {
      }
    }
    Vue.createApp().mount(App, '#app')
  </script>
</body>
</html>

Вероятно, это чувство, как было сказано выше,vueТеперь он сложен посередине, так чтоvue3Две обновки (собственно одна, другая вариант)

реактивный - слушать данные

Перейдем непосредственно к примеру Обычно, когда ничего не используется, если вы хотите использовать данные, запишите их прямо вsetupвозвращается функциейjsonты можешь вот так

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script src="../packages/vue/dist/vue.global.js"></script>
  <div id="app"></div>
  <script>
    const { reactive } = Vue
    var App = {
      template: `
        <div class="container">
          {{aaa}}
        </div>`,

      setup() {
        return {
          aaa: 123
        }
      }
    }
    Vue.createApp().mount(App, '#app')
  </script>
</body>
</html>

Но те данные, которые у нас есть сейчас, фактически не отслеживаются, можно попробовать сделать это отдельно.json, а затем изменение значения страницы не будет отображаться, в это время мы можем использовать нашreactiveохватывать

Использование также очень простое, параметр в функции вызывается непосредственно вашими данными, а возвращаемое значение является отслеживаемыми данными.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script src="../packages/vue/dist/vue.global.js"></script>
  <div id="app"></div>
  <script>
    const { reactive } = Vue
    var App = {
      template: `
        <div class="container">
          名字 {{data.name}} <br/>
          年龄 {{data.age}} <br/>
        </div>`,

      setup() {
        let data = reactive({name: 'name', age: 18})
        return {
          data
        }
      }
    }
    Vue.createApp().mount(App, '#app')
  </script>
</body>
</html>

Вот и все

Конечно, некоторые люди могут испытывать трудности и считают, что все данные нужно отслеживать вручную.На самом деле, если вы сначала устраните неполадки, вы можете напрямую войти в систему.setupВозвращенный json упаковывается напрямуюreactive, так что вы приедетеvue2написано так

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script src="../packages/vue/dist/vue.global.js"></script>
  <div id="app"></div>
  <script>
    const { reactive } = Vue
    var App = {
      template: `
        <div class="container">
          名字 {{data.name}} <br/>
          年龄 {{data.age}} <br/>
        </div>`,

      setup() {
        let data = {name: 'name', age: 18}
        return reactive({
          data
        })
      }
    }
    Vue.createApp().mount(App, '#app')
  </script>
</body>
</html>

а также,reactiveОн имеет собственный глубокий мониторинг, а это значит, что независимо от того, сколько слоев охватывают ваши данные,jsonСколько массивов будет отслеживаться

ref

ЭтоreactiveМладший брат, возможно, некоторые люди будут чувствовать себя странно в это время,refне получитьdomиспользуемый элемент, сreactiveКак это может все еще иметь значение?Вообще-то официалы еще не решили,будет ли это получение элементов или пакетных данных,это может нужно определить.vueузнаю после публикации

Давай не будем об этом, давай поговорим об этомrefКак использовать, в первую очередьvue3внутриrefОн также может загружать данные, но они передаются черезreactiveдобиться, а за ним ещеreactive

На самом деле, вы можете увидеть это с первого взгляда, взглянув на пример

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script src="../packages/vue/dist/vue.global.js"></script>
  <div id="app"></div>
  <script>
    const { reactive, ref } = Vue
    var App = {
      template: `
        <div class="container">
          {{refData}} <button @click="handleClick()">按钮</button>
        </div>`,

      setup() {
        let refData = ref(0);

        const handleClick = () =>{
          refData.value+=1
        }
        console.log(refData)
        return {
          refData, 
          handleClick
        }
      }
    }
    Vue.createApp().mount(App, '#app')
  </script>
</body>
</html>

Вы можете увидеть, что я изменил, когда я модифицировал его.refData.value, да, на самом деле

let refData = ref(0); == let refData = reactive({value: 0 })

Но его не нужно использовать в шаблоне.value,после всегоvueвещи в собственном доме,vueПочему это делается, зависит от того, как выглядит окончательный релиз.

Наверняка некоторые люди подумают, что если я просто хочу получитьref, напримерinput,Что мы можем сделать по этому поводу? Очень просто, вот код напрямую, а потом объяснять

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script src="../packages/vue/dist/vue.global.js"></script>
  <div id="app"></div>
  <script>
    const { reactive, ref, watch, onMounted } = Vue

    var App = {
      template: `
        <div class="container">
          <input ref="input1" value="321" />
        </div>`,

      setup() {
        const input1 = ref(null);

        console.log(input1.value)

        onMounted(()=>{
          console.log(input1.value.value)
        })

        return {
          input1
        }
      }
    }
    Vue.createApp().mount(App, '#app')
  </script>
</body>
</html>

Вот сначала дайте этоrefпервоначальныйnullА затем выйти, чтобы вернуться к нашей стихии, которая находится в нашейsetupЯ не могу получить это напрямуюvalueПричина, потому что это еще не конец, когда он будет доступен,onMountedНа данный момент это жизненный цикл, я думаю, все его знают, жизненный цикл будет описан ниже, здесь я не буду вдаваться в подробности.

правильноreactЗнакомые братья много переживают в это время, верно?

Props

На самом деле этоpropsИзменений не так уж и много, это можно объяснить в нескольких предложениях, и соглашение о параметрах все еще существует, вот так

Небольшое различие в том, что когда мы использовали реквизитные данные ранее, мы можем напрямуюthis.props.xxxЭто получается, и теперь он непосредственно помещается вsetupв параметрах вот так

Конечно, когда вы видите это, вы должны чувствовать, что это больше похоже на что?

Конечно, ведьvue3является основным толчкомtsверсия, так что, конечноtsЭтот набор также можно использовать, например, этот

Конечно,htmlНапрямую писать однозначно нельзяtsДа вот в чем смысл

computed

этоcomputedЕсть два способа написания, один из которых заключается в прямой передаче функции, что на самом деле эквивалентно прошедшему времени.computedТолькоget, поэтому, когда вы установите значение, он сообщит об ошибке

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script src="../packages/vue/dist/vue.global.js"></script>
  <div id="app"></div>
  <script>
    const { reactive, ref, computed } = Vue

    var App = {
      template: `
        <div class="container">
          {{count}} <button @click="handleClick()">按钮</button>
        </div>`,

      setup() {
        let refData = ref(0);

        let count = computed(()=>{
          return refData.value; 
        })

        const handleClick = () =>{
          count.value+=1
        }
        console.log(refData)
        return {
          count, 
          handleClick
        }
      }
    }
    Vue.createApp().mount(App, '#app')
  </script>
</body>
</html>

Конечно можно конечно хотеть писать точно так же как и в прошлом, то есть вторым способом написания, передать один сразуjson

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script src="../packages/vue/dist/vue.global.js"></script>
  <div id="app"></div>
  <script>
    const { reactive, ref, computed } = Vue

    var App = {
      template: `
        <div class="container">
          {{count}} <button @click="handleClick()">按钮</button>
        </div>`,

      setup() {
        let refData = ref(0);

        let count = computed({
          get(){
            return refData.value;
          },
          set(value){
            console.log(value)
            refData.value = value; 
          }
        })

        const handleClick = () =>{
          count.value+=1
        }
        console.log(refData)
        return {
          count, 
          handleClick
        }
      }
    }
    Vue.createApp().mount(App, '#app')
  </script>
</body>
</html>

Это в основном и2.xНет разницы, нет больше объяснений

Но будьте осторожны, этоcomputedбез всякого рендеринга, то есть если этоrefDataНе одинrefИли скорееreactiveЕсли данные изменены, это будет правильно, но весьvueПеререндерить не будет, это тоже для гибкости, если эти штуки довести, нет возможности повысить производительность, так чтоreactiveявляетсяvue3все ядро

readonly

Это использование на самом деле похоже на приведенное выше, вызовите функцию, чтобы вернуть значение, например

let Version = readonly(1.1.3)

В это время некоторые люди могут чувствовать себя немного странно, зачем эта штука, используйте ее напрямуюconstилиtsизreadonlyНе хорошо ли было бы, конечно, это должно быть правдой, сconstЭто действительно сообщит об ошибке, если объявление будет изменено в этой функции, но не забывайте, это значение — это то, что нам нужно сделать вsetupвозвращались из него или переходили в другие места, т. е. черезvueЭто немного перенос, он не будет работать в это время, это тоже полезно

watch

Обратите внимание, что эти часы должны слушатьreactiveДанные, если это обычные данные, используйте этоwatchЭто не может быть отслеживается, то давайте попробуем

Также используйте предыдущий пример, чтобы изменить его

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script src="../packages/vue/dist/vue.global.js"></script>
  <div id="app"></div>
  <script>
    const { reactive, ref, watch } = Vue

    var App = {
      template: `
        <div class="container">
          {{refData}} <button @click="handleClick()">按钮</button>
        </div>`,

      setup() {
        let refData = ref(0);

        const handleClick = () =>{
          refData.value+=1
        }

        watch(refData,(val, oldVal)=>{
          console.log(val, oldVal)
        })

        return {
          refData, 
          handleClick
        }
      }
    }
    Vue.createApp().mount(App, '#app')
  </script>
</body>
</html>

Это также похоже на прошлое, но с небольшой разницей, иногда нам, возможно, придется контролировать в определенное особое время, и после этого особого времени мы не будем отслеживать, этоwatchВернет функцию, если она будет выполнена, она прекратит прослушивание напрямую

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script src="../packages/vue/dist/vue.global.js"></script>
  <div id="app"></div>
  <script>
    const { reactive, ref, watch } = Vue

    var App = {
      template: `
        <div class="container">
          {{refData}} <button @click="handleClick()">按钮</button>
          <button @click="handleStop">停止</button>
        </div>`,

      setup() {
        let refData = ref(0);

        const handleClick = () =>{
          refData.value+=1
        }

        let stop = watch(refData,(val, oldVal)=>{
          console.log(val, oldVal)
        })

        const handleStop = () =>{
          stop()
        }

        return {
          refData, 
          handleClick,
          handleStop
        }
      }
    }
    Vue.createApp().mount(App, '#app')
  </script>
</body>
</html>

Это довольно удобно, правда?

Жизненный цикл

На самом деле я верю生命周期Это то, что всех больше беспокоит, например,mountedПросто напишите это снаружи, конечно, я считаю, что все должны понять, когда вы видите этоvue3Способ написания проектов - да, это тоже функция, вsetupвызывать прямо в код

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script src="../packages/vue/dist/vue.global.js"></script>
  <div id="app"></div>
  <script>
    const { reactive, ref, watch, onMounted } = Vue

    var App = {
      template: `
        <div class="container">
          {{refData}} <button @click="handleClick()">按钮</button>
          <button @click="handleStop">停止</button>
        </div>`,

      setup() {

        onMounted(()=>{
          console.log('mounted~');
        })

        let refData = ref(0);

        const handleClick = () =>{
          refData.value+=1
        }

        let stop = watch(refData,(val, oldVal)=>{
          console.log(val, oldVal)
        })

        const handleStop = () =>{
          stop()
        }

        return {
          refData, 
          handleClick,
          handleStop
        }
      }
    }
    Vue.createApp().mount(App, '#app')
  </script>
</body>
</html>

Это относительно просто, конечно, естьonMountedимеютonВ остальном все тоже самое, только деинсталлятор переименовали, назвалonUnmounted

Делитесь данными между компонентами

существуетvue2.xМожно ли обмениваться данными только между нашими компонентами?props, вам нужно использовать немного более сложный обменvuex, но когда вещей слишком много, становится слишком грязно

такvue3Есть еще две вещи

Предоставить - предоставить данные

вводить - получать данные

Здесь я напишу псевдокод напрямую.

const userData = Symbol();
const Cmp1 = {
    setup(){
        let user = reactive({name: "aaa", age: 18});
        provide(userData, user);
    }
}

const Cmp2 = {
    setup(){
        const user = inject(userData, {});
    }
}

Это очень просто, каждый должен быть в состоянии понять, но зачем использоватьSymbolну все знаютSymbolВещи, которые выходят, всегда уникальны, что также является официальным рекомендуемым способом написания.Если вы чисто обычай, легко иметь то же имя или ввести неправильную букву или что-то еще, поэтому нам просто нужно сохранить этоkey, обмен данными станет очень удобным

Второй параметр этого ввода является значением по умолчанию, то есть то, что является значением по умолчанию, когда таких данных нет, это все еще относительно легко понять

Еще одно, что можно сказать по этому поводу, на самом деле, лично мне это нравится больше. На самом деле, вы можете хорошенько подумать об этом. Я уже писал об этом ранее.vueКогда я это делал, я тратил много времени на работу над компонентами «родитель-потомок», на то, что родственные компоненты, и на передачу того и другого друг другу.

несмотря на то что2.xТам тоже есть, но официалы тоже сказали, что рекомендуется использовать в продвинутых компонентах или библиотеках, а вам писать не рекомендуется, ведь недоделок еще много.

Суммировать

На самом деле, каждый должен был почувствовать это, когда увидел это.vue3На этот раз я все еще обращаю внимание на этоsetupфункция, на самом деле, это также имеет большие преимущества, что эквивалентно высказываниюvueНа этот раз за вами остается много полномочий по принятию решений, и уже не все за ним, что тоже очень удобно

Конечно, некоторые люди могут подумать, что собирать все в одном месте слишком грязно, но на самом деле это нормально, потому что вы можете делать такие вещи, как модульность самостоятельно.Это зависит от вашего собственного руководства, но у меня есть подозрение, что это может быть официально. быть спецификацией или что-то?

Однако нынешние сплетни не заслуживают доверия, и нам еще нужно дождаться конкретики.vue3Отпустите, чтобы знать

Может быть, другу больше нравитсяvue 2.xСпособ написания декоратора, вот официальное объяснение, декоратор все-таки не стабилен, да и рамка неудобная.thisчто, тоже не помогает с наследованием, так чтоvue3просто сдавайсяclassНаписано, но. . . В настоящее время нам нужно посмотреть, как это будет работать в Интернете.

Наконец, Амвей одинvue3Статья тоже написана моим другом.Если вы правыvue3Если вам интересно, вы можете пойти и посмотретьnuggets.capable/post/684490…

В чем проблема, желающих задавать вопросы в комментариях, или добавить ME QQ или Micro-Channel Communication с

qq

916829411

WeChat

Thank You