Эта статья мояофициальный сайт вьюА также некоторые учебные записи и опыт изучения v3 в других местах, если есть что-то, что вы не можете понять, пожалуйста, поправьте меня.
1. Изменения в данных
В версии v3 возвращаемое значение данных стандартизировано и принимается толькоФункция, возвращающая объект, а в версии v2 также поддерживается возвратObjectа такжеФункция, возвращающая объект.
2. Изменения в слиянии миксинов
Слияние объектов в v3 — это перезапись, а не слияние.
const mixinObject = {
data(){
return {
user:{
id:1,
name:'jack'
}
}
}
}
const CompA = {
mixins: [mixinObject],
data() {
return {
user: {
id: 2
}
}
}
}
// 结果是
user: {
id: 2
}
3. Удалены методы $on, $off, $once
В версии v2 $on и $off обычно используются для реализации глобальной шины событий, а $once используется для привязки пользовательского события. На самом деле в реальных проектах они почти не используются. После удаления версии v3, и соответствующие требования могут быть выполнены с помощью некоторых внешних библиотек. Напримерmitt
4. Убран фильтр
Фильтры были удалены в версии v3,{{ calcNum | filter }}
Больше не будет поддерживаться, официальная рекомендация - использоватьcomputed
Фильтр замены атрибутов (молодцы ~).
5. Фрагменты
В версии v3 поддерживаются компоненты, которые могут иметь несколько корневых узлов, что может уменьшить глубину иерархии узлов. Но я также надеюсь, что разработчики смогут прояснить семантику.
<template>
<header></header>
<main></main>
<footer></footer>
</template>
6. Функциональные компоненты
Прежде чем мы изменим версию v3, давайте рассмотрим версию функционального компонента v2, которую можно создать двумя способами:functional
атрибуты и{ functional : true }
варианты, коды следующие
// attribute 方式
<template functional>
<img :src="src" />
</template>
<script>
...
</script>
// 选项方式
export default = {
functional:true,
props:{
...
},
render:function(createElement,context){
...
/**
context传递了一些参数:
props,slots,parent,listeners,injections
**/
}
}
В версии v2 есть два типа компонентов: компоненты с состоянием и функциональные компоненты (компоненты без состояния).По сравнению с компонентами с состоянием, функциональные компоненты не требуют создания экземпляров, не имеют состояния и не имеют обработчиков жизненного цикла.Рендеринг намного быстрее, чем у компонентов с отслеживанием состояния. Часто используется для статических компонентов представления с единственной функцией для оптимизации производительности. Кроме того, функциональные компонентыВозможность возврата нескольких корневых узлов.
В версии 3 разница в производительности между компонентами с отслеживанием состояния и функциональными компонентами была значительно уменьшена и в большинстве сценариев почти незначительна. Таким образом, единственным преимуществом функциональных компонентов является возможность возврата нескольких узлов, но это обычно используется меньше, и компоненты часто проще Конкретный синтаксический сахар выглядит следующим образом:
// 函数创建
import { h } from 'vue'
const DynamicHeading = (props, context) => {
// context是一个包含 attrs,slots,emit的对象
return h(`h${props.level}`, context.attrs, context.slots)
}
DynamicHeading.props = ['level']
export default DynamicHeading
// 单文件组件(SFC)
<template>
<component
v-bind:is="`h${$props.level}`"
v-bind="$attrs"
/>
</template>
<script>
export default {
props: ['level']
}
</script>
7. Глобальная настройка API
В версию v3 добавлен новый глобальный API.createApp
, импортированный через модуль ES. передачаcreateApp
Возвращает экземпляр приложения, который предоставляет глобальный API, который представляет собой новую концепцию Vue3, которая в основном решает возможность совместного использования ресурсов (конфигурация, глобальные компоненты, директивы и т. д.) между различными «приложениями». Давайте сравним изменения в v3 и v2 для создания приложений соответственно.
// v2 创建
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
// v3 创建
import { createApp } from 'vue'
import App from './App.vue'
var app = createApp(App);
app.mount('#app')
Одним из способов обмена конфигурацией между «приложениями» является заводской шаблон:
import { createApp } from 'vue'
import App1 from './App1.vue'
import App2 from './App2.vue'
const createMyApp = options => {
const app = createApp(options)
app.directive('focus' /* ... */)
return app
}
createMyApp(App1).mount('#foo')
createMyApp(App2).mount('#bar')
v3 перемещает API, который может глобально изменить поведение Vue, из исходного конструктора Vue в экземпляр. Список выглядит следующим образом
глобальный API v2 | глобальный API v3 |
---|---|
Vue.config | app.config |
Vue.config.productionTip | Удалить |
Vue.config.ignoredElements | app.config.ignoredElement |
Vue.component | app.component |
Vue.directive | app.directive |
Vue.mixin | app.mixin |
Vue.use | app.use |
Кроме того, некоторые глобальные API и внутренние компоненты подверглись рефакторингу, учитывая tree-shaking, их можно импортировать только через ES-модули, а это значит, что когда компоненты и интерфейсы, которые не используются в вашем приложении, не будут упакованы. Список затронутых API выглядит следующим образом:
- Vue.nextTick
- Vue.observable (заменен на Vue.reactive)
- Vue.version
- Vue.compile (только полная сборка)
- Vue.set (только совместимые сборки)
- Vue.delete (только совместимые сборки)
// 错误使用
import Vue from 'vue'
Vue.nextTick(() => {
// 一些和DOM有关的东西
})
// 正确使用
import { nextTick } from 'vue'
nextTick(() => {
// 一些和DOM有关的东西
})
8. API композиции
основное событие! ! !
Это новая концепция в версии 3, vue предоставляет нам несколько новых API, эти новые API используются в одном месте, и это место принадлежит нам.новыйПредоставляет место, где мы можем сделать что-то от инициализации компонента до его уничтожения, что я понимаю как функцию ловушки -Setup
, В настройках вы можете делать все, что вы можете делать в компонентах vue, например, когда выcreated
,mounted
,computed
,watch
,methods
Все, что вы там делаете, может бытьSetup
Он выполнен внутри, так как мы можем это сделать, то есть через новые API, предоставляемые Vue.
Так что же в основном решает эта штука? Все мы знаем, что роль компонентов заключается в извлечении функций и повторном использовании кода. Это заставляет нашу программу идти дальше с точки зрения гибкости и ремонтопригодности, но этого недостаточно.Когда логика внутри компонента очень сложная, мы будем выделять логику вcreated
,mounted
,methods
,computed
,watch
Внутри, а затем и весь код файла состоит из сотен строк. Это, несомненно, самое хлопотное для людей, которые не писали этот компонент, пытаясь понять эти логические коды. а такжеSetup
Это то, что решает эту проблему, централизуя всю логику вSetup
в процессе. Отныне, когда вы хотите построить автомобиль, вам больше не нужно ездить по всему миру, чтобы импортировать все виды деталей, вы находитесь вSetup
можно сделать на заводе.
давай познакомимсяSetup
и эти новыеAPI
Использование и функции (я слышал, что такие вещи называются галантерейными товарами???):
Setup
Если вы понимаете, что я сказал выше, вы должны понимать и то, что я написал в начале:
<template>
<div class="demo">
</div>
</template>
<script>
export default {
name:"Demo",
data(){
return {}
},
setup () {
console.log('run');
}
}
</script>
// 当运行起来打印了run
Setup
Может возвращать объект, и вы можете получить доступ к свойствам этого объекта в другом месте компонента.
Примечание: при выполнении
Setup
Когда экземпляр компонента не был создан, поэтому вSetup
Нет вthis
. Однако он предоставляет два параметра приема -props
а такжеcontext
. существуетSetup
не может получить доступ к каким-либо другим свойствам в компоненте.
// 调用Demo组件
<Demo :name="'jac" a="1" b="2"></Demo>
// Demo 组件
<template>
<div class="demo">
</div>
</template>
<script>
export default {
name:"Demo",
props:{
name:String,
},
data(){
return {}
},
setup (props,context) {
console.log('props',props); // {name:jac}
console.log('attrs', context.attrs); // {a:1,b:2}
console.log('slots', context.slots); // {}
console.log('emit', context.emit); // function
let shareProp = 'hallo,v3';
// 返回两个属性 shareProp, changeProp
return {
shareProp
}
},
mounted() {
this.shareProp = 'changed';
},
}
</script>
Мы обнаружим, что пытаясь и не обновляя, мы находимsetup
Возвращаемый объект не является реактивным,ОтзывчивыйМы не должны быть незнакомы, все свойства в опции data() являются адаптивными, то есть Vue должен был создать зависимость от свойств в data() во время процесса инициализации компонента. Поэтому, когда свойство изменяется, представление автоматически обновляется, что является отзывчивым. Так как же сделать его отзывчивым?
ref & reactive
мы можем пройтиref
,reactive
СоздайтеОтзывчивыйусловие,
Мы используемref
Вы можете создавать реактивные состояния примитивных и сложных типов данных, используяreactive
Создавать можно только реактивные состояния сложных типов данных, если созданный тип данных неверный, консоль выдаст соответствующее предупреждениеvalue cannot be made reactive: **
. Этоref
а такжеreactive
В чем разница?
const refNum = ref(10);
const refObj = ref({
name:'jac',
age:20
});
const reactiveNum = reactive(10);
const reactiveObj = reactive({
name: 'jac',
age: 20
})
console.log('refNum',refNum);
console.log('refObj',refObj);
console.log('reactiveNum', reactiveNum);
console.log('reactiveObj', reactiveObj);
Результат выглядит следующим образом:
когдаref
Когда создается сложный тип данных, он фактически создается внутри с помощью реактивного. такref
Также возможно создавать состояния ответа сложных типов данных, просто вsetup
Китайская орфография будет другой.
setup(){
const refObj = ref({
name:'jac',
age:20
});
const reactiveObj = reactive({
name: 'jac',
age: 20
})
// ref 方式的更新
const changeRefObj = () => {
refObj.value.name="mac"
}
// reactive 方式的更新
const changeReactiveObj = () => {
reactiveObj.name = 'mac'
}
return {
...
}
}
Уведомление: пройти через
ref
Значение завернуто вSetup
в вам нужно использоватьпеременная.значениеспособ доступа и установки значений изSetup
Вы можете напрямую передавать объекты, выставленные вэта переменнаядоступ.
<template>
...
</template>
<script>
import { ref,reactive } from 'vue';
export default {
...
setup (props,context) {
...
let shareProp = ref('hallo,v2');
let info = reactive({name:'jac'});
const changeProp = ()=>{
shareProp.value = 'hallow,v3';
}
return {
shareProp,
...
}
},
mounted() {
console.log(this.shareProp)
},
}
</script>
Небольшие партнеры могут выбрать использование в соответствии со своими привычками кодирования.
toRef & toRefs
Иногда, когда мы хотим удалить некоторые переменные из сложной реактивной переменной путем деструктурирования, наш код может выглядеть так:
<template>
<button @click="changeObj">my name is {{info.name}}</button>
</template>
<script>
import { ref, provide, reactive } from 'vue';
export default {
name: 'Demo',
setup(){
const info = reactive({name:'jac',sex:'男',age:18});
return {
info
}
},
methods:{
changeObj(){
let { name,sex } = this.info;
name = 'make'
// 视图不会更新
}
}
}
</script>
Это приведет к тому, что два свойства, которые мы деконструировали, перестанут отвечать на запросы.toRef
а такжеtoRefs
деконструируется из него,toRef
Реактивные переменные для деконструкции одного свойства,toRefs
Это создание адаптивных переменных для всех свойств в исходном объекте и создание соответствующих переменных путем деструктурирования.
<template>
<button @click="changeObj">my name is {{info.name}}</button>
</template>
<script>
import { ref, provide, reactive, toRef, toRefs} from 'vue';
export default {
name: 'Demo',
setup(){
const info = reactive({name:'jac',sex:'男',age:18});
return {
info
}
},
methods:{
changeObj(){
// toRef
// let name = toRef(this.info,'name'); // arg1: 源对象, arg2: 属性名称
// name.value = 'make'
// toRefs
// let { name } = toRefs(this.info); // arg1: 源对象
// name.value = 'make'
// 视图成功刷新
}
}
}
</script>
смотреть, вычислять и регистрировать хуки жизненного цикла
существуетSetup
мы все еще можемwatch
свойства, создавать независимыеcomputed
, вы также можете зарегистрировать различные хуки жизненного цикла, так какSetup
Этапы выполнения вращаются вокругbeforeCreate
а такжеcreated
и прогресс, поэтому то, что изначально было сделано в этих двух жизненных циклах, может быть помещено вSetup
в процессе.
<template>
...
</template>
<script>
import { ref, toRefs, watch, computed, onMounted } from 'vue';
export default {
name:"Demo",
props:{
name:String,
},
...
setup (props,context) {
console.log('我首先执行');
// 通过toRefs方法创建props的响应式变量
const { name: listenName } = toRefs(props);
const count = ref(0);
const changCount = ()=>{
count.value++;
}
const totalCount = computed(() => {
return `总计数:${count.value}`
})
// watch 会监听listenName变量,当listenName变量改变的时候会触发回调方法
watch(listenName,(newValue, oldValue)=>{
console.log(listenName.value);
})
onMounted(()=>{
console.log('onMounted也执行了,结果输出如下');
console.log(count.value);
changCount();
console.log(totalCount.value)
})
return {
count,
changCount,
totalCount,
}
},
created() {
console.log('created执行了');
},
mounted() {
console.log('mounted执行了');
},
}
</script>
// 输出结果如下:
我首先执行
created执行了
onMounted也执行了,结果输出如下
0
总计数:1
mounted执行了
могу видеть,Setup
Функция ловушки жизненного цикла, зарегистрированная во внешнем регистре, выполняется раньше функции ловушки, зарегистрированной снаружи!
provide & inject
provide
а такжеinject
Обычно мы не используем его много в бизнес-сценариях, но он все еще полезен при записи библиотек плагинов или компонентов.provide
а такжеinject
Используется для предоставления свойств в компонентах-предках и внедрения их в дочерние компоненты. Как это использовать в настройках?
// demo组件中提供
<template>
<Test />
</template>
<script>
import { provide } from 'vue';
export default {
name:"Demo",
setup (props,context) {
provide('name','jac')
},
}
</script>
// test组件中注入使用
<template>
...
</template>
<script>
import { inject } from 'vue';
export default {
name:"Test",
setup (props,context) {
console.log(inject('name')); // jac
},
}
</script>
Вышеsetup
Основное применение , вам нужно хорошо его прочувствовать и использовать в различных сценариях, чтобы лучше понять, в чем он хорош, например следующий код:
// a.js
import { ref, onMounted } from 'vue'
export default function doSomething(refName,fn){
const a = ref(0);
const b = ref(0);
// ...,
onMounted(() => {
fn();
})
return {
a,
b
}
}
//b.js
import doSomething from './a.js';
setup(){
const {a,b} = doSomething('box',()=>{
console.log('执行');
})
}
Я просто привожу пример Предположим у вас есть кусок логики, который нужно использовать на нескольких страницах, тогда мы можем извлечь эту логику, чтобы наш код был более упорядоченным, мы можем не только повторно использовать компоненты, но и значительно улучшить повторное использование некоторых бизнес-кодов и централизацию обработки бизнес-кодов Я считаю, что это будет очень полезно для нашего опыта разработки и качества кода.
9. v-model
В версии 3 значение атрибута по умолчанию и метод триггера v-модели были изменены.value
=>modelVale
,input
=>update
. В пользовательском компоненте он позволяет нам устанавливать несколько V-моделей одновременно.
// Demo.vue
export default {
name: "Demo",
props: {
title:String,
label:String
},
methods: {
titleEmit(value) {
this.$emit('update:title', value)
},
labelEmit(value) {
this.$emit('update:label', value)
}
},
}
// 调用Demo.vue
<Demo v-model:title="" v-model:label="" />
10. Поддержка машинописного текста
рекомендуется v3Typescript
,Typescript
не только поддерживаетES6
Он также имеет вывод типов, который может помочь нам избежать многих ошибок типов в процессе разработки.Теперь, когда внешний интерфейс становится все более и более сложным,Typescript
Он может помочь приложению двигаться дальше, быть более совершенным с точки зрения ремонтопригодности и масштабируемости, а также принимать изменения.
Как создать приложение vue3+typescript?
1. Используйте vue-кли
yarn global add @vue/cli@next
# OR
npm install -g @vue/cli@next
// 下面按部就班的创建
2. Используйте vite (личная рекомендация, просто и легко)
yarn create vite-app my-vue-ts --template vue-ts
Снято! Неа
В этом разделе мы кратко разберем некоторые изменения в v3 с уровня приложения, не вникая в принцип и реализацию.
v3 Одно зеркало 999 карт!