оригинал:Моя статья о саде в блоге
Обратите внимание на публичный номер: поиск WeChatweb全栈进阶; получить больше галантерейных товаров
1. Официальная ссылка на китайский документ
https://vue3js.cn/docs/zh/
Во-вторых, начало
- Vue3.0 был официально выпущен с разминки прошлого года до вечера 18 сентября.
vue3.0 betaВерсия; -
betaверсия означаетvue3.0Открытие официально занесено в проект, все могут учиться с удовольствием (вы продолжаете разрабатывать новые front-end технологии, а я еще могу учиться...потому что я должен есть, чтобы жить!!!); - Экосистема передовых технологий постоянно обновляется, и многие думают, что Александр больше не может учиться, но если ты не можешь учиться, ты можешь перестать учиться. . .
0.0; Вы должны учиться, если вы не можете учиться, иначе вы будете устранены только в том случае, если вы адаптируетесь к себе.
3. Предложения по проекту vue2.0
Процитирую автора официальной документации:
намекать:
我们仍在开发 Vue 3 的专用迁移版本,该版本的行为与 Vue 2 兼容,运行时警告不兼容。如果你计划迁移一个非常重要的 Vue 2 应用程序,我们强烈建议你等待迁移版本完成以获得更流畅的体验.
В настоящее время автор имеет в виду: для vue2.0проект强烈不建议подняться наvue3.0; потому что текущийbetaВерсии и существующие фреймворки и плагины не очень поддерживаются и совместимыvue3.0синтаксис; так что должно быть много непредвиденных проблем; для стремительных обновленийvue3.0Друзья, нам остается только дождаться разработки официальной совместимой версии и сделать миграцию, ведь онлайн-проект — это не шутки, естьbugможет быть большой потерей. Этот горшок в принципе неподвижен без мин дома...
4. Введение
Что дает Vue3?Общедоступный номер: фронтальные статьи для утреннего чтения
Для получения подробной документации см.:Официальная ссылка на китайский документ
- Быстрее
- рефакторинг
Virtual DOM- Пометка статического контента и выделение динамического контента
- только обновление
diffдинамическая часть
- рефакторинг
双向数据绑定Object.defineProperty() --> Proxy API-
ProxyДля сложных структур данных мониторинг рекурсии цикла уменьшен, рекурсия цикла начального рендеринга очень требовательна к производительности; -
ProxyДля метода мутации массива (который изменит исходный массив) больше не нужно отдельно переписывать и обрабатывать нативный метод массива. - Грамматика также
definePropertyГораздо проще, просто контролируйте свойство напрямую;
- кэш событий
-
vue2, для события привязки каждый раз, когда оно запускается, создается новыйfunctionобновить; -
Vue3, предоставляется объект кэша событийcacheHandlers,когдаcacheHandlersЕсли этот параметр включен, компиляция автоматически сгенерирует встроенную функцию и превратит ее в статический узел, поэтому при повторном запуске события нет необходимости воссоздавать функцию для прямого вызова метода обратного вызова кэшированного события.
-
- рефакторинг
- меньше (
Tree shakingслужба поддержки)- Короче говоря: не упаковывайте все, только то, что вы используете
api; Для больших проектов вы обнаружите, что горячая загрузка и первоначальный рендеринг значительно улучшились. - Значительно сокращает избыточный код при разработке и повышает скорость компиляции.
- Короче говоря: не упаковывайте все, только то, что вы используете
- легче поддерживать
-
Vue3отFlowпереехал вTypeScript- В случае совместной разработки с несколькими людьми используйте
TypeScriptВы после этого будете жаловаться на кислинку, почему не появились раньше?TypeScript
- В случае совместной разработки с несколькими людьми используйте
- Структура каталогов кода соответствует монорепозиторию.
- Основная точка зрения: код разделен на небольшие модули, большинство разработчиков работают только с несколькими папками и будут компилировать только те модули, за которые они несут ответственность, вместо того, чтобы компилировать весь проект.
-
- Новые функции и возможности
Composition API- Не заботьтесь о том, чтобы становиться все более и более похожим на react-hook, в конце концов, чужие преимущества стоит изучить самому;
-
Composition APIФункциональная разработка значительно повышает возможность повторного использования компонентов и бизнес-логики; сильно развязана; улучшает качество кода и эффективность разработки; уменьшает размер кода.
- Повышение эффективности разработки
viteподдержку (конечно покаviteФункция недостаточно мощная и стабильная, но Youda воспринимает ее какvue3Официальный инструмент сборки, который определенно улучшит его; свободный выборwebpackещеvite)-
viteНативный браузер в среде разработкиES importsразработки, в производстве на основеRollupПакет- быстрый холодный пуск
- Мгновенное горячее обновление модуля
- Настоящая компиляция по запросу
-
vue2.0Я считаю, что многие мелкие партнеры объединеныwebpackРазработка; Но заметили ли вы, что первоначальный проект был очень крутым, когда он был маленьким. Запуск, компиляция и горячая загрузка были быстрыми; когда проект был большим... При упаковке, запуске и изменении функции на горячую загрузку ... Давай сначала в туалет/ Набери воды, это раздражает, когда ты занят -
vue3.0комбинироватьviteНа авторское вступление не влияет огромный размер проекта, и то, что было в начале, есть и сейчас, конечно преувеличение немного преувеличено, но разница не должна быть большой;
-
5. Строительство окружающей среды
// 对于 Vue 3,应该 npm 上可用的 Vue CLI v4.5 作为 @vue/cli@next
yarn global add @vue/cli@next
# OR
npm install -g @vue/cli@next
// 创建项目
npm init vite-app <project-name>
# OR
yarn create vite-app <project-name>
// 下载依赖及运行项目, 已 npm 方式为例; 详细步骤官方文档的安装页都有
cd <project-name>
npm install
npm run dev // 项目就能跑起来并且访问了
Расширение: проект представляет другие плагины, такие как vue-router4.0, vuex4.0, typescript и т. д. Пожалуйста, обратитесь кСоздание среды Vue3.0
6. Введение в грамматику
Прежде чем начать, вы должны прочитать некоторые изменения vue3 в vue2; нажмите, чтобы узнать подробностиОсновные изменения в документах официального сайта
vue2используется вOptions API; vue3в томComposition APIЧисто функциональный API для краткости
6.1 настройка
vue3Запись компонентаsetup(){}Функция используется как запись и по умолчанию выполняется только один раз, порядок выполнения указан вbeforeCreateПозжеcreatedДо;
...
// 使用props和this
setup (props, ctx) {
// props 组件间传递的参数;
// ctx 组件的实例的执行上下文(可以理解为 vue2 this)
/* 可执行 下面等操作:例 ctx.$emit()
attrs: Object
emit: ƒ ()
listeners: Object
parent: VueComponent
refs: Object
root: Vue
*/
// 注意 steup 中没有this了, 拿不到this
}
6.2, жизненный цикл
Я помню, как рано сказалvue3устраненbeforeCreate,createdДва жизненных цикла, но на практике я обнаружил, что писать все же можно, потому чтоvue2,vue3Написание в настоящее время совместимо;
created () { console.log('created') }
setup (props, ctx) {
console.log('setup')
// mounted 新写法 记住一句话 所有的方式都是以函数的形式呈现
onMounted(() => {})
}
mounted () { console.log('mounted') }
// 执行顺序 setup created mounted
Хоть и совместимо, но старайтесь не писать так, ждите, настоятельно рекомендуется поставить все это вsteupв функции
6.3, реактивный, ссылка, toRefs, isRef
Создание реактивных объектовreactive、ref、toRefsиспользование, корреспонденцияvue2серединаdata Рекомендуемое письмо 3
// 写法一:响应式数据一多, return 要很多次; 使用数据的时候要通过state拿到
<template>
<div>
<p>{{state.count}}</p>
</div>
</template>
import {reactive} from 'vue'
...
setup(props, ctx) {
const state = reactive({
count: 0
})
return { state }
}
// 写法二
<template>
<div>
<p>{{count}}</p>
</div>
</template>
import {reactive} from 'vue'
...
setup(props, ctx) {
const state = reactive({
count: 0
})
return {
count: state.count
}
}
// 写法三:推荐 通过 toRefs 代理对象, 再通过解构的方式取值
<template>
<div>
<p>{{count}}</p>
</div>
</template>
import {reactive, toRefs} from 'vue'
...
setup(props, ctx) {
const state = reactive({
count: 0
})
return {
...toRefs(state)
}
}
// 写法四:通过 ref() 函数包装, 返回值是一个对象,对象上只包含一个 value 属性, 就是要的属性值
<template>
<div>
<p>{{count}}</p>
<p>{{count1}}</p>
</div>
</template>
import {reactive, toRefs, ref} from 'vue'
...
setup(props, ctx) {
// 父组件传递count属性
// 写法1
const count = ref(props.count)
console.log(count.value) // 对应props.count的值
// 写法2
const state = reactive({
count1: ref(props.count)
})
return {
count,
...toRefs(state)
}
}
// isRef 来判断某个值是否为 ref() 创建出来的对象
import { ref, isRef } from 'vue';
export default {
setup(props, ctx) {
const refCount = ref(0)
const count = isRef(refCount) ? refCount : 1
}
};
6.4, рассчитано
Пример сценария: объединениеvue-routerПо текущей прочности дорогиcountназначить, а также расширитьvue-routerПрименение
<template>
<div>
<p>{{count}}</p>
<p>{{count1}}</p>
</div>
</template>
import {reactive, toRefs, computed} from 'vue'
import {useRoute} from 'vue-router'
...
setup(props, ctx) {
const route = useRoute()
const state = reactive({
// 计算属性 写法1
count: computed(() => {
return route.path
})
})
// 计算属性 写法2
const count1 = computed(() => {
return route.path
})
return {
...toRefs(state),
// 计算属性不需要通过 toRefs 结构, 因为他就是一个具体的值就是响应式的
count1
}
}
6.5, часы, часы
Пример сценария: такой же, как вычислено
watchEffectа такжеwatchв чем разница:
-
watchEffectНет необходимости указывать отслеживаемые свойства, он будет автоматически собирать зависимости, пока мы обращаемся к отзывчивым свойствам в обратном вызове, тогда при изменении этих свойств будет выполняться обратный вызов -
watchСлушайте только указанные свойства -
watchможет получить новое значение и старое значение, иwatchEffectнет -
watchEffectОн выполняется один раз, когда компонент инициализируется для сбора зависимостей (сcomputedТочно так же обратный вызов будет выполняться снова, когда впоследствии изменятся собранные зависимости.
// watch 用法 监听单个属性
<template>
<div>
<p>{{count}}</p>
</div>
</template>
import {reactive, toRefs, watch} from 'vue'
import {useRoute} from 'vue-router'
...
setup(props, ctx) {
const route = useRoute()
const state = reactive({
count: 0,
})
// 监听路由路劲, immediate 是否立即执行一次
watch(() => route.path, (newValue) => {
state.count = newValue
}, { immediate: true })
return {
...toRefs(state),
}
}
// watch 用法 监听ref数据源
<template>
<div>
<p>{{count}}</p>
</div>
</template>
import {reactive, toRefs, ref, watch} from 'vue'
...
setup(props, ctx) {
// 定义数据源
let count = ref(0);
// 指定要监视的数据源
watch(count, (count, prevCount) => {
console.log(count, prevCount)
})
setInterval(() => {
count.value += 2
}, 2000)
console.log(count.value)
return {
count
}
}
// watch 用法 监听多个属性
<template>
<div>
<p>{{count}}</p>
</div>
</template>
import {reactive, toRefs, watch} from 'vue'
...
setup(props, ctx) {
const state = reactive({
name: 'vue',
age: 3
})
watch(
// 监听name、 age
[() => state.name, () => state.age],
// 如果属性改变、则执行以下回调
([newName, newAge], [oldname, oldAge]) => {
console.log(oldname, oldname)
console.log(oldAge, oldAge)
},
{ lazy: true} // 在 watch 被创建的时候,不执行回调函数中的代码
)
setTimeout(() => {
state.name = 'react'
state.age += 1
}, 3000)
return {
...toRefs(state),
}
}
// watchEffect 用法
<template>
<div>
<p>{{count}}</p>
</div>
</template>
import {reactive, toRefs, ref, watchEffect} from 'vue'
import {useRoute} from 'vue-router'
...
setup(props, ctx) {
const route = useRoute()
const state = reactive({
count: 0,
})
// 当 route.path 变化时就会执行打印, 有点类似 react-hook 的 useEffect 第二个参数效果
watchEffect(() => {
count = route.path
console.log(route.path)
})
// watchEffect、 watch 都可以主动停止监听
const stop = watchEffect(() => {
count = route.path
console.log(route.path)
})
// 在某个时机下 执行 stop() 停止watchEffect监听
if (...) { stop() }
return {
...toRefs(state),
}
}
Семь, некоторые API и методы удалены из Vue3.
7.1 Отмена KeyboardEvent.keyCode
существуетVue2.x, для привязки событий клавиатуры используется следующий код:
<!-- keyCode version -->
<input v-on:keyup.13="submit" />
<!-- alias version -->
<input v-on:keyup.enter="submit" />
или:
Vue.config.keyCodes = {
f1: 112
}
<!-- keyCode version -->
<input v-on:keyup.112="showHelpText" />
<!-- custom alias version -->
<input v-on:keyup.f1="showHelpText" />
В случае чего датьkeyupНастроить конкретную кнопкуkeyCode(число) вVue3не вступит в силу, но псевдонимы по-прежнему можно будет использовать, например:
<input v-on:keyup.delete="confirmDelete" />
7.2 Удалитьметоды off и $once
существуетVue2.xсквозьEventBusметод для реализации связи компонентов:
var EventBus = new Vue()
Vue.prototype.$EventBus = EventBus
...
this.$EventBus.$on() this.$EventBus.$emit()
Это использование находится вVue3Это не будет работать вVue3удалено в $on,$offи другие методы (см. rfc), но рекомендуется использоватьmittпрограмма вместо:
import mitt from 'mitt'
const emitter = mitt()
// listen to an event
emitter.on('foo', e => console.log('foo', e) )
// fire an event
emitter.emit('foo', { a: 'b' })
7.3 Удаление фильтров
существуетVue3, компонентаfiltersпункт, вы можете использоватьmethodsилиcomputedзаменить:
<template>
<p>{{ accountBalance | currencyUSD }}</p>
</template>
<script>
export default {
filters: {
currencyUSD(value) {
return '$' + value
}
}
}
</script>
Заменить:
<template>
<p>{{ accountInUSD }}</p>
</template>
<script>
export default {
props: {
accountBalance: {
type: Number,
required: true
}
},
computed: {
accountInUSD() {
return '$' + this.accountBalance
}
}
}
</script>
Восемь, API и метод записи изменились в Vue3
8.1 Инициализация экземпляра
существуетvue2.xпрошедшийnew Vue()метод инициализации:
import App from './App.vue'
new Vue({
store,
render: h => h(App)
}).$mount('#app')
существуетvue3серединаVueбольше не является конструктором, черезcreateAppИнициализация метода:
import App from './App.vue'
createApp(App).use(store).mount('#app')
8.2 Изменения в способе вызова глобального API
существуетVue2.x, большая часть мировогоAPIна всем протяженииVue.xxxилиVue.abc()вызов метода, например:
import Vue from 'vue'
Vue.mixin()
Vue.use()
пока вVue3, эти способы будут изменены и заменены следующими:
import { createApp } from 'vue'
const app = createApp({})
app.mixin()
app.use()
При этом можно лишь ввести некоторые необходимыеAPI, вводить не нужно, это тоже соответствует Тhree Shakingтребования, такие как:
import { nextTick,reactive,onMounted } from 'vue'
nextTick(() => {
})
onMounted(() => {
})
из-заVue3Средний и глобальныйAPIпройдешьapp.xxxвызов метода, поэтому перед передачейVue.prototype.xxxПривязка глобальных методов и переменных будет недоступна и может быть заменена на:
//在main.js中:
app.config.globalProperties.http = function(){}
//在vue组件中:
this.http()
8.3 Модификация метода рендеринга
существуетVue2.x, иногда по индивидуальному заказуrenderметод для возврата содержимого шаблона следующим образом:
export default {
render(h) {
return h('div')
}
}
существуетVue3середина,hпройти черезvueимпортировать следующим образом:
import { h } from 'vue'
export default {
render() {
return h('div')
}
}
8.4 Новый метод создания асинхронного компонента
существуетVue2.xв, особенно вVue Router, часто используются асинхронные компоненты, с помощьюwebpackМетод упаковки может асинхронно получить код компонента, например:
const asyncPage = () => import('./NextPage.vue')
const asyncPage = {
component: () => import('./NextPage.vue'),
delay: 200,
timeout: 3000,
error: ErrorComponent,
loading: LoadingComponent
}
существуетVue3, обеспечиваетdefineAsyncComponent()Метод создает асинхронный компонент и может возвращатьPromiseОбъект сам контролирует время завершения загрузки следующим образом:
import { defineAsyncComponent } from 'vue'
const asyncPageWithOptions = defineAsyncComponent({
loader: () => import('./NextPage.vue'),
delay: 200,
timeout: 3000,
error: ErrorComponent,
loading: LoadingComponent
})
const asyncComponent = defineAsyncComponent(
() =>
new Promise((resolve, reject) => {
/* ... */
})
)
IX. ВРЕМЕННОЕ КОНЕЦ:
- Я пишу давно, и это немного многословно.Новый API в основном пишет несколько методов кодирования, и выбирает в соответствии с моими собственными предпочтениями.
- В будущем я буду постепенно добавлять собственное понимание и использование некоторых новых API.
- Ссылки на эту статью в заголовке:
- Передовые статьи для утреннего чтения:Самое полное руководство по обновлению Vue3.0
- Статьи китайского сообщества Vue:Статья для начала работы с новыми API в Vue3.