Учебник по уровню няни vue3

внешний интерфейс Vue.js
Учебник по уровню няни vue3

Начинающий vue3

Стыдно сказать, что vue3 уже около года как выпускается.Я только пришел изучать vue3.Кажется, я совсем слабый цыпленок.Сейчас стою на плечах гигантов учиться.Когда vue3 только вышел , это все на английском. Я не понимаю, по крайней мере, у меня сейчас китайский. Xiaobai, написанный путем объединения мнений многих больших парней, легко понять и понять vue3.

ладно, ладно товарищи, без пафосных вступлений, сегодня мы познакомимся с vue3.

Понять, как создается vue3

Прежде всего, давайте создадим файл vue3.Конечно, этот шаг такой же, как и vue2, поэтому я не буду описывать его по порядку, все его знают.

Это все создано, давайте поговорим об этомvite😝

Сначала нам нужно понятьviteЧто это такое, vite — это новое поколение инструментов для создания интерфейса, разработанное командой You Yuxi, которое призвано заменитьwebpack, сначала давайте посмотрим на преимущества vite

vite.jpg

  • Нет необходимости упаковать, быстро холодный сервер запуска
  • Мгновенная замена горячего модуля (HMR, горячее обновление)
  • Настоящая компиляция по запросу

Webpack - это входной файл в начале, затем анализирует маршрут, затем модуль и, наконец, упаковывает его, а затем сообщает вам, что сервер готов (по умолчанию 8080)

bundler.37740380.pngОднако, что такое vite, он сначала сообщает вам, что сервер готов, а затем ждет, когда вы отправите HTTP-запрос, затем файл входа,Dynamic import(динамический импорт)code split point(разделение кода)esm.3070012d.pngКак использовать Vite, каждый может пойтиОфициальный сайт, вы также можете увидеть, что я написал

//要构建一个 Vite + Vue 项目,运行,使用 NPM:
npm init @vitejs/app 项目名
//使用 Yarn:
yarn create @vitejs/app 项目名
你会觉得非常快速的创建了项目,然而它并没有给你下载依赖,你还有进入文件然后
npm install (or yarn)

Затем он открывается с неserveсталdev 1636687125(1).png Edit components/HelloWorld.vue to test hot module replacement.

Отредактируйте component/HelloWorld.vue, чтобы протестировать горячую замену модуля. (То есть горячие обновления быстрее)

1636687189(1).jpgТем не менее, у нас есть только краткое понимание.Сейчас мы сосредоточены на vue3.Если vite станет мейнстримом в будущем, мы также можем оглянуться назад. 😜

Он по-прежнему создается и объясняется общепринятым способом.

Анализ vue3

базовое понимание

Когда мы создадим проект vue3, щелкните его main.js, вы обнаружите, что написание изменилось

1636688554(1).jpg

1636688564(1).jpgВведение - это не конструктор vue, аcreateAppФабричная функция Однако создание объектов экземпляра фактически эквивалентно vue2.vm,mount('#app')эквивалентно$mount('#app'), а написание vue2 несовместимо с vue3

Теперь мы входим в компонент приложения, вы найдете, что отличается, у него нет корневого тега, в vue2 мы все пишем в корневом теге div, поэтому в vue3 не может быть корневого тега.

1636697972(1).jpg

Часто используемый составной API (акцент!!!)

setup

Функция настройки — это вход в Composition API (композиционный API)

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

<script>
 export default {
  name: 'App',
  setup(){
   let name = '流星'
   let age = 18
   //方法
   function say(){
    console.log(`我叫${name},今年${age}岁`)
   }

   //返回一个对象
   return {
    name,
    age,
    say
   }
  }
 }
</script>

Конечно, это не реактивно, и тогда вы можете спросить, почему это не работает.this, прежде чем мы подумаем, почему мы используемthis, еще не вопрос размаха, но на этот раз мы всеsetupвнутри, так что он не будет использоватьсяthis, а здесь совместимо с написанием vue2, например:data,methods..., и конфигурация в vue3 может быть прочитана в vue2, но конфигурация vue2 не может быть прочитана в vue3, поэтому не смешивайте vue3 и vue2, если есть повторяющееся имя, то предпочтительнееsetup.

пс если не нравитсяreturnТаким образом, вы можете использовать новый синтаксический сахар vue3.<script setup>,<script setup>Это эквивалентно запуску кода в функции настройки при компиляции и запуске, а затем определению экспортируемых переменных в контекст и включению их в возвращаемый объект. Для конкретных операций вы можете увидеть других больших парней в Nuggets.

Основное использование настройки скрипта

После начала работы я понял, что синтаксис настройки скрипта Vue3 действительно классный.

Новый синтаксический сахар Vue3 — скрипт установки

......

Есть еще несколько моментов, на которые стоит обратить внимание при настройке

  • это лучше, чемbeforeCreateа такжеcreatedЭти два жизненных цикла должны бытьбыстро, то есть установкаbeforeCreate,createdРаньше this внутри него распечатывалось какundefined
  • setup может принимать два параметра, первый параметрprops, то есть значение прохода компонента, второй параметрcontext, объект контекста,contextЕсть три очень важные вещиattrs,slots,emit, они эквивалентны тем, что в vue2this.$attrs,this.$slots,this.$emit.

При выводе видно, что значение передано, но будет предупреждение, т.к. я передаю два значения, а получаю только одно, если будут получены оба, предупреждения не будет1636791090(1).jpgЭто потому, что vue3 требует, чтобы мы использовалиemitsЧтобы получить, после получения не будет предупреждения, но вы также можете игнорировать предупреждение и использовать его напрямую.1636794022.jpgПри использовании слота его нельзя использоватьslot="XXX", нужно использоватьv-slot, иначе сообщит об ошибке

父
<template>
  <div class="home">
    <HelloWorld wish="不掉发" wishes="变瘦" @carried="carried">
      <h3>实现插槽1</h3>
      <template v-slot:dome>
        <h4>实现插槽2</h4>
      </template>
    </HelloWorld>
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld";
export default {
  name: 'Home',
  components:{
    HelloWorld
  },
  setup(){
    function carried(value){
      alert(`牛呀,都实现了!!!${value}`)
    }
    return {
      carried
    }
  }
}
</script>
-------
子
<template>
  <h1>HelloWorld</h1>
  <h1>{{ wish }}</h1>
  <button @click="dream">点击实现</button>
  <slot></slot>
  <slot name="dome"></slot>
</template>

<script>
export default {
  name: "HelloWorld",
  props: ["wish",'wishes'],
  emits:['carried'],
  setup(props,context) {
    console.log(props)
    console.log(context.attrs)
    function dream(){
      context.emit('carried',666)
    }
    return{
      dream
    }
  },
};
</script>

<style scoped></style>

реф и реактивный

ref

Как я уже сказал выше, то, что мы пишем, не является адаптивными данными, мы пишем только строки и числа, так как же они становятся адаптивными данными, а затем импортируют их?ref, но если мы изменим его прямо в коде, его нельзя изменить, лучше напечатать имя и возраст, вы обнаружите, что ref превращает их в объекты И ещеRefImplэкземпляр объекта

<template>
  <div class="home">
    <h1>姓名:{{name}}</h1>
    <h1>年龄:{{age}}</h1>
    <button @click="say">修改</button>
  </div>
</template>

<script>
import {ref} from 'vue'
export default {
  name: 'Home',
  setup(){
    let name = ref('燕儿')
    let age = ref(18)
    console.log(name)
    console.log(age)
    //方法
    function say(){
      name='苒苒'
      age=20
    }
    return {
      name,
      age,
      say
    }
  }
}
</script>

Поэтому при изменении нам нужно изменить .value, и мы по-прежнему используем get и set для изменения страницы.1636706595(1).jpgНа самом деле, если это имеет смысл, если мы используем его на странице, он должен быть{{name.value}}Отображается, но поскольку vue3 определяет, что вы являетесь объектом ref, он автоматически дает вам .value

function say(){
  name.value='苒苒'
  age.value=20
}

Так что, если ссылка, которую я определяю, является объектом, потому что мы знаем, что хотя ссылка станетRefImplобъект экземпляра, поэтому мы просто используемXX.value.xxмодифицировать

<template>
  <div class="home">
    <h1>姓名:{{name}}</h1>
    <h1>年龄:{{age}}</h1>
    <h2>职业:{{job.occupation}}</h2>
    <h2>薪资:{{job.salary}}</h2>
    <button @click="say">修改</button>
  </div>
</template>

<script>
import {ref} from 'vue'
export default {
  name: 'Home',
  setup(){
    let name = ref('燕儿')
    let age = ref(18)
    let job=ref({
      occupation:'程序员',
      salary:'10k'
    })
    console.log(name)
    console.log(age)
    //方法
    function say(){
      job.value.salary='12k'
    }
    return {
      name,
      age,
      job,
      say
    }
  }
}
</script>

Но если мы напечатаем job.value, вы обнаружите, что его больше нет.RefImplобъект экземпляра становитсяProxyЭкземплярный объект, он просто нижний слой vue3, превращающий все объекты вProxyОбъекты-экземпляры для примитивных типов данныхObject.definePropertyвнутриgetа такжеsetПерехват данных, а затем реактивный, но если это тип объекта, он используетсяProxy, но vue3 оборачивает его в новую функциюreactive, он эквивалентен объекту в ref, который будет вызываться автоматическиreactive.

1636707807(1).jpg

reactive

Reactive может определять только отзывчивые данные типа объекта.Если ссылка, упомянутая выше, является объектом, она будет автоматически вызванаreactive,ПучокObjectПеревести вProxy, то давайте напечатаем его, вы обнаружите, что он становится прямоProxy, а почему .value раньше, ведь чтобы получить значение, а потом передатьreactiveсталиProxy, но теперь напрямую черезreactiveсталиProxy, и это глубоко реагирующий тип, и он также может выполнять тип, реагирующий на массив

<template>
  <div class="home">
    <h1>姓名:{{name}}</h1>
    <h1>年龄:{{age}}</h1>
    <h2>职业:{{job.occupation}}<br>薪资:{{job.salary}}</h2>
    <h3>爱好:{{hobby[0]}},{{hobby[1]}},{{ hobby[2] }}</h3>
    <button @click="say">修改</button>
  </div>
</template>

<script>
import {ref,reactive} from 'vue'
export default {
  name: 'Home',
  setup(){
    let name = ref('燕儿')
    let age = ref(18)
    let job=reactive({
      occupation:'程序员',
      salary:'10k'
    })
    let hobby=reactive(['刷剧','吃鸡','睡觉'])
    console.log(name)
    console.log(age)
    //方法
    function say(){
      job.salary='12k'
      hobby[0]='学习'
    }
    return {
      name,
      age,
      job,
      say,
      hobby
    }
  }
}
</script>

Некоторые люди могут подумать, ой, я не могу вспомнить, я просто используюref, каждый раз.valueВсе в порядке, ароматный. Он мяу, ты нормальный, если на странице мало данных, это нормально, если это куча данных, ты не можешь.valueЭто курение? , на самом деле, вы можете записать это в виде данных в vue2 до этого, так что вы будете чувствовать себяreactiveАроматная партия 😁

<template>
  <div class="home">
    <h1>姓名:{{data.name}}</h1>
    <h1>年龄:{{data.age}}</h1>
    <h2>职业:{{data.job.occupation}}<br>薪资:{{data.job.salary}}</h2>
    <h3>爱好:{{data.hobby[0]}},{{data.hobby[1]}},{{ data.hobby[2] }}</h3>
    <button @click="say">修改</button>
  </div>
</template>

<script>
import {reactive} from 'vue'
export default {
  name: 'Home',
  setup(){
    let data=reactive({
      name:'燕儿',
      age:18,
      job:{
        occupation:'程序员',
        salary:'10k'
      },
      hobby:['刷剧','吃鸡','睡觉']
    })
    //方法
    function say(){
      data.job.salary='12k'
      data.hobby[0]='学习'
    }
    return {
      data,
      say,
    }
  }
}
</script>

А как насчет того, не лучше ли выставлять данные напрямую, чтобы хоть было понятнее, и не вводило людей в заблуждение, почему.value, да 😊

Разница между ref и реактивным

  • ref используется для определения:данные основного типа.
  • рефериObject.defineProperty()изgetа такжеsetдля достижения оперативности (перехват данных).
  • Данные, определенные ссылкой: необходимы для управления данными.value, при чтении данных не обязательно читать прямо в шаблоне.value.
  • реактивный используется для определения:Данные типа объекта или массива.
  • реактивный с использованиемProxyреализовать отзывчивость (перехват данных) и передатьReflectМанипулировать данными внутри исходного кода.
  • Данные, определяемые реактивным: рабочие данные и данные чтения: не требуются.value.

Конечно, как я уже говорил, ref может определять объекты или массивы, он просто автоматически вызывается внутри.reactiveдля преобразования.

Отзывчивый принцип vue3

Когда дело доходит до принципа отзывчивости vue3, мы должны упомянуть отзывчивость vue2 (предложение, известное всем собакам) черезObject.definePropertyизget,setЧтобы выполнить захват данных, модификацию и, следовательно, отзывчивость, но какие у этого недостатки 😶

  • Так как есть только методы get() и set(), можно захватить только операции чтения и модификации свойств, при добавлении или удалении свойств они не могут быть захвачены, в результате чего интерфейс не обновляется.
  • Измените массив напрямую по нижнему индексу, и интерфейс не будет обновляться автоматически.

хорошо, vue2 так много говорит, что? Вы все еще хотите слушать нижний слой vue2? Затем вы Alt + ←, до свидания.

Для отзывчивости в vue3 мы используемProxy, конечно, мы знаем в vue2,ProxyЧто это такое, это же прокси, конечно, он не просто так используется, есть еще и встроенный объект на WindowReflect(反射)

  • Через прокси: перехват изменений любого атрибута в объекте, в том числе: чтение и запись значений атрибутов, добавление атрибутов, удаление атрибутов и т. д.
  • Через Reflect: управляйте свойствами исходного объекта.
const p=new Proxy(data, {
// 读取属性时调用
    get (target, propName) {
    	return Reflect.get(target, propName)
    },
//修改属性或添加属性时调用
    set (target, propName, value) {
    	return Reflect.set(target, propName, value)
    },
//删除属性时调用
    deleteProperty (target, propName) {
    	return Reflect.deleteProperty(target, propName)
    }
}) 

вычисляется, смотрите и смотритеЭффект

computed

В vue3 поместитеcomputedЭто становится составным API, а это значит, что вы должны его ввести.Код выглядит следующим образом, и простой расчет завершен.

<template>
  <div class="home">
    姓:<input type="text" v-model="names.familyName"><br>
    名:<input type="text" v-model="names.lastName"><br>
    姓名:{{fullName}}<br>
  </div>
</template>

<script>
import {reactive,computed} from 'vue'
export default {
  name: 'Home',
  setup(){
    let names=reactive({
      familyName:'阿',
      lastName:'斌'
    })
    fullName=computed(()=>{
      return names.familyName+'.'+names.lastName
    })
    return {
      names,
      fullName
    }
  }
}
</script>

Знаете ли вы, что произойдет, если вы пойдете и измените что-то рассчитанное? Предупреждение означает, что вычисляемая вещь является свойством только для чтения.

1636807524(1).jpgТогда что, если мы хотим изменить его, тогда нам нужно использоватьcomputedокончание написания

<template>
  <div class="home">
    姓:<input type="text" v-model="names.familyName"><br>
    名:<input type="text" v-model="names.lastName"><br>
    姓名:<input type="text" v-model="names.fullName"><br>
  </div>
</template>

<script>
import {reactive,computed} from 'vue'
export default {
  name: 'Home',
  setup(){
    let names=reactive({
      familyName:'阿',
      lastName:'斌'
    })
    names.fullName=computed({
      get(){
        return names.familyName+'.'+names.lastName
      },
      set(value){
        let  nameList=value.split('.')
        names.familyName=nameList[0]
        names.lastName=nameList[1]
      }
    })
    return {
      names
    }
  }
}
</script>

Впрочем, ыысы (один сказал один), он же мяу, я думаю, вычисляемый атрибут никто менять не будет, да? Если есть, просто сделай вид, что я этого не говорил 😷

watch

ты можешь подуматьcomputedвсе составные API, тоwatchБудет ли это составной API? Будьте смелее, это слишком, тогда будем следить

<template>
  <div class="home">
    <h1>当前数字为:{{num}}</h1>
    <button @click="num++">点击数字加一</button>
  </div>
</template>

<script>
import {ref,watch} from 'vue'
export default {
  name: 'Home',
  setup(){
    let num=ref('0')
    watch(num,(newValue,oldValue)=>{
      console.log(`当前数字增加了,${newValue},${oldValue}`)
    })
    return {
      num
    }
  }
}
</script>

Конечно слушаетrefЧто мне делать, если я отслеживаю несколько данных, если определены отдельные реагирующие данные? На самом деле несколькоwatchМониторить, конечно, это не лучший способ, лучший способ - собственно мониторить массив

 watch([num,msg],(newValue,oldValue)=>{
      console.log('当前改变了',newValue,oldValue)
    })

Поскольку мы слушаем массив, мы получаемnewValueа такжеoldValueТо есть массив, то первый в массиве - это первый отслеживаемый параметр.

ps конечно это было в vue2 раньшеwatchДругих параметров нет, они есть и в vue3, они в конце написаны.

watch([num,msg],(newValue,oldValue)=>{
      console.log('当前改变了',newValue,oldValue)
    },{immediate:true,deep:true})

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

<template>
  <div class="home">
    <h1>当前姓名:{{names.familyName}}</h1>
    <h1>当前年龄:{{names.age}}</h1>
    <h1>当前薪水:{{names.job.salary}}K</h1>
    <button @click="names.familyName+='!'">点击加!</button>
    <button @click="names.age++">点击加一</button>
    <button @click="names.job.salary++">点击薪水加一</button>
  </div>
</template>

<script>
import {reactive,watch} from 'vue'
export default {
  name: 'Home',
  setup(){
    let names=reactive({
      familyName: '鳌',
      age:23,
      job:{
        salary:10
      }
    })
    watch(names,(newValue,oldValue)=>{
      console.log(`names改变了`,newValue,oldValue)
    },{deep:false})
    return {
      names
    }
  }
}
</script>

Но вы найдете проблему, почемуnewValueа такжеoldValueТоже самое, смущает, это все новые данные, даже если пользоватьсяrefопределить, еще нет возможности контролироватьoldValue(Он мяукает, он сказал вам всеrefОпределенный объект автоматически вызываетсяreactive),такoldValue не получает правильно при мониторинге реактивных данных, определенных реактивным, и вы обнаружите, что этоПринудительно включить глубокий мониторинг (deep:true) и не может быть закрыт.

Но сейчас мы наблюдаемreactiveВсе свойства определенных отзывчивых данных отслеживаются только для одного из них, так что же нам делать?

watch(names.age,(newValue,oldValue)=>{
  console.log(`names改变了`,newValue,oldValue)
})

для мониторинга, однако, vue3 предупредит, что вы можете отслеживать толькоreactiveопределено илиrefопределены и не могут быть прослушаны.1636813377(1).jpgТогда мы должны написать это (никто не узнаетreturnМожно ли его опустить? Ни за что? Ни за что? Нет, этот человек ты, верно? )

watch(()=>names.age,(newValue,oldValue)=>{
  console.log('names改变了',newValue,oldValue)
})

Так что, если мы будем отслеживать несколько свойств? Эмммм, ты нормальный, я написал в монитор несколькоrefОпределенные отзывчивые данные, вы не будете делать выводы из одного случая? Вводить код утомительно! ! ! Он мяукает, чтобы вы не спросили больше одногоreactiveСвойство определено, я могу только сказать, что это то же самое, что и это! ! ! Можете ли вы быть умным! ! !

watch([()=>names.age,()=>names.familyName],(newValue,oldValue)=>{
  console.log('names改变了',newValue,oldValue)
})

хорошо, а что, если мы будем отслеживать атрибут глубины? Вы обнаружите, что если я отслеживаю только первый слой, я не могу его отслеживать, тогда у нас есть два способа записать его.

//第一种
watch(()=> names.job.salary,(newValue,oldValue)=>{
  console.log('names改变了',newValue,oldValue)
})
//第二种
watch(()=> names.job,(newValue,oldValue)=>{
  console.log('names改变了',newValue,oldValue)
},{deep:true})

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

(Все тупые, написали более 4000 слов и еще не закончили...)

watchEffect

watchEffectэто новая функция vue3, она пришла иwatchполучить работу, это иwatchЭто одна и та же функция, так какие у нее преимущества?

  • Автоматически включен по умолчаниюimmediate:true
  • Следите за тем, кто используется
watchEffect(()=>{
    const one = num.value
    const tow = person.age
    console.log('watchEffect执行了')
})

Фактически,watchEffectНемного какcomputed, он вызывается один раз при изменении значения внутри, но что?computedЧтобы записать возвращаемое значение иwatchEffectНе записывайте возвращаемое значение.

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

lifecycle.png

2021060423231561.pngСначала проведем простой анализ.В vue2 мы первыеnew Vue(), затем выполнитеbeforeCreateа такжеcreatedЗатем спросите, есть ли у васvm.$mount(el), да и дальше выполнять дальше, но в vue3, это все готово и дальше функция.

На самом деле изменений в жизненном цикле в vue3 не так много, но изменения до уничтожения и уничтожения делают его более семантичным.beforeDestroyпереименовать вbeforeUnmount,destroyedпереименовать вunmounted

Затем в vue3,beforeCreateа такжеcreatedи API композиции отсутствует,setupЭто эквивалентно этим двум функциям жизненного цикла

В vue3 это также может быть записано как предыдущая функция жизненного цикла, только помните, что имена некоторых функций изменились.

существуетsetupЭто должно быть написано так

  • beforeCreate===>Not needed*
  • created=======>Not needed*
  • beforeMount ===>onBeforeMount
  • mounted=======>onMounted
  • beforeUpdate===>onBeforeUpdate
  • updated =======>onUpdated
  • beforeUnmount ==>onBeforeUnmount
  • unmounted =====>onUnmounted

функция крючков

  • Хук-функция Vue3 эквивалентна миксину vue2, разница в том, что хуки — это функции.
  • Функция ловушки Vue3 может помочь нам улучшить возможность повторного использования кода, позволяя нам использовать функции ловушек в разных компонентах.

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

//一般都是建一个hooks文件夹,都写在里面
import {reactive,onMounted,onBeforeUnmount} from 'vue'
export default function (){
   //鼠标点击坐标
   let point = reactive({
      x:0,
      y:0
   })

   //实现鼠标点击获取坐标的方法
   function savePoint(event){
      point.x = event.pageX
      point.y = event.pageY
      console.log(event.pageX,event.pageY)
   }

   //实现鼠标点击获取坐标的方法的生命周期钩子
   onMounted(()=>{
      window.addEventListener('click',savePoint)
   })

   onBeforeUnmount(()=>{
      window.removeEventListener('click',savePoint)
   })

   return point
}
//在其他地方调用
import useMousePosition from './hooks/useMousePosition'
let point = useMousePosition()

toRef и toRefs

toRef

toRefПеревод на самом деле изменить то, чтоrefТип данных, вы можете найти его бесполезным, в конце концов, мы определили его какref, а ты подумай, как же мы это раньше писали

<template>
  <div class="home">
    <h1>当前姓名:{{names.name}}</h1>
    <h1>当前年龄:{{names.age}}</h1>
    <h1>当前薪水:{{names.job.salary}}K</h1>
    <button @click="names.name+='!'">点击加!</button>
    <button @click="names.age++">点击加一</button>
    <button @click="names.job.salary++">点击薪水加一</button>
  </div>
</template>

<script>
import {reactive} from 'vue'
export default {
  name: 'Home',
  setup(){
    let names=reactive({
      name:'老谭',
      age:23,
      job:{
        salary:10
      }
    })
    return {
      names
    }
  }
}
</script>

Вы всегда использовали кодname.xx, можно сказать, тогда яreturnКогда это не написано так, измените это на это

return {
  name:names.name,
  age:names.age,
  salary:names.job.salary
}

Но если вы работаете со страницей, она не отвечает, почему? Это потому, что то, что вы сейчас выставляете, представляет собой простую строку, будет ли строка реагировать? Конечно нет, но если вы используете егоtoRef, то есть поставитьname.xxСделайте его отзывчивым, а затем автоматически изменяйте его при работе с ним.nameданные внутри

return {
  name:toRef(names,'name'),
  age:toRef(names,'age'),
  salary:toRef(names.job,'salary')
}

Но некоторые люди могут сказать, почему я неrefизменить? Может быть, вы обнаружите, что он также отзывчив на странице, но я вам говорю, что он вообще не используется.namesДанные в нем — это данные, которые вы определяете отдельно, поэтому, если вы запишете их так, независимо от того, как вы их модифицируете, они не будут изменены наnamesданные в

return {
  name:ref(names.name),
  age:ref(names.age),
  salary:ref(names.job.salary),
}

toRefs

быть умным,toRefsа такжеtoRefКакая разница, добавьs,toRefоднократное преобразование в адаптивное, т.е.toRefsПросто конвертируйте несколько в адаптивные, в этом случае код уменьшится, а то если их тысячи, неужели вы не хотите их писать как дурак? (...Это структура, просто alt+ ←), если вы не понимаете

 <h1>当前姓名:{{name}}</h1>
 <h1>当前薪水:{{job.salary}}K</h1>
return {
    ...toRefs(names)
}

Другие компонуемые API (да, я думаю, вы их практически не используете)

Мелкореактивный и мелкийRef

shallowReactiveПоверхностный уровень реагирования означает, что только первый слой данных становится реагирующим, а данные глубокого уровня не реагируют.shallowRefЕсли данные определены как примитивный тип, то они иrefТо же самое, ничего не изменится, но если данные определены как объектный тип, то они не будут реактивными, как мы говорили ранее, еслиrefобъект определен, то он автоматически вызоветreactiveсталиProxy, но если вы используетеshallowRefтогда не будет звонитьreactiveбыть отзывчивым.

smallReactive: Reactive (поверхностный реактивный), который обрабатывает только самые внешние свойства объекта. smallRef: обрабатывает скорость отклика только базовых типов данных и не выполняет обработку отклика объектов.

let person = shallowReactive({
 name:'大理段氏',
 age:10,
 job:{
   salary:20
 }
})
let x = shallowRef({
 y:0
})

только для чтения и мелкий только для чтения

readonlyЭто получение ответных данных, а затем их переназначение, а возвращенные данные не могут быть изменены (только для глубокого чтения),shallowReadonlyНо только мелкий только для чтения (первый слой только для чтения, остальные можно модифицировать)

names=readonly(names)
names=shallowReadonly(names)

toRaw и markRaw

toRawФактически,reactiveСгенерированореактивный объектПеревести внормальный объект. еслиrefпо определению не оказывает влияния (в т.ч.refопределенный объект)Если данные добавляются в последующих операциях, добавленные данные являются ответными данными., конечно, если данныеmarkRawПосле операции отзываться не станет.Может все скажут нет иreadonlyЭто то же самое? Это должно быть иначе.readonlyНет способа изменить это, ноmarkRawНе конвертируется в адаптивный, но данные изменятся.

<template>
  <div class="home">
    <h1>当前姓名:{{names.name}}</h1>
    <h1>当前年龄:{{names.age}}</h1>
    <h1>当前薪水:{{names.job.salary}}K</h1>
    <h1 v-if="names.girlFriend">女朋友:{{names.girlFriend}}</h1>
    <button @click="names.name+='!'">点击加!</button>
    <button @click="addAges">点击加一</button>
    <button @click="addSalary">点击薪水加一</button>
    <button @click="add">添加女朋友</button>
    <button @click="addAge">添加女朋友年龄</button>
  </div>
</template>

<script>
import {reactive,toRaw,markRaw} from 'vue'
export default {
  name: 'Home',
  setup(){
    let names=reactive({
      name:'老伍',
      age:23,
      job:{
        salary:10
      }
    })
    function addAges(){
      names.age++
      console.log(names)
    }
    function addSalary(){
      let fullName=toRaw(names)
      fullName.job.salary++
      console.log(fullName)
    }
    function add(){
      let girlFriend={sex:'女',age:40}
      names.girlFriend=markRaw(girlFriend)
    }
    function addAge(){
      names.girlFriend.age++
      console.log(names.girlFriend.age)
    }
    return {
      names,
      add,
      addAge,
      addAges,
      addSalary
    }
  }
}
</script>

customRef

customRefСоздайте пользовательскую ссылку с явным контролем над ее отслеживанием зависимостей и инициированием обновлений.

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

<template>
  <input type="text" v-model="keyWord">
  <h3>{{keyWord}}</h3>
</template>

<script>
import {customRef} from 'vue'
export default {
  name: 'App',
  setup() {
    //自定义一个ref——名为:myRef
    function myRef(value,times){
      let time
      return customRef((track,trigger)=>{
        return {
          get(){
            console.log(`有人从myRef中读取数据了,我把${value}给他了`)
            track() //通知Vue追踪value的变化(必须要有,并且必须要在return之前)
            return value
          },
          set(newValue){
            console.log(`有人把myRef中数据改为了:${newValue}`)
            clearTimeout(time)
            time = setTimeout(()=>{
              value = newValue
              trigger() //通知Vue去重新解析模板(必须要有)
            },times)
          },
        }
      })
    }
    let keyWord = myRef('HelloWorld',1000) //使用自定义的ref

    return {keyWord}
  }
}
</script>

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

я так понимаю

Anti-shake: Когда событие запускается в первый раз, функция не выполняется немедленно, а задается период времени.Если одно и то же событие запускается в большом количестве за короткий промежуток времени, функция будет только выполнен один раз.

Регулирование: после того, как функция выполняется один раз, она будет временно недействительна в течение определенного периода времени, а затем повторно активируется по истечении этого периода времени.Если одно и то же событие запускается в большом количестве за короткий период времени, после выполняется один раз, функция будет активирована в течение указанного периода времени, она больше не будет действовать в течение этого периода и не будет действовать снова, пока не истечет этот период времени.(Можно понимать как период охлаждения игровых навыков)

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

обеспечить и ввести

Вы все знаете, что компоненты передают значения.В vue2, если вы хотите использовать данные родительского компонента в компонентах-потомках, вам нужно передавать значение или использовать компоненты родитель-потомок слой за слоем.vuex, но теперь родительский компонент может действовать как поставщик зависимостей для всех своих дочерних компонентов, независимо от того, насколько глубока иерархия компонентов. Эта функция состоит из двух частей: родительский компонент имеетprovideвозможность предоставления данных, подкомпоненты имеютinjectвозможность начать использовать данные.

components_provide.png

//父
import { provide } from 'vue'
setup(){
 let fullname = reactive({name:'阿月',salary:'15k'})
 provide('fullname',fullname) //给自己的后代组件传递数据
 return {...toRefs(fullname)}
}
//后代
import {inject} from 'vue'
setup(){
 let fullname = inject('fullname')
 return {fullname}
}

Конечно, можно использовать и дочерние компоненты, но помните, что существуют способы передачи параметров между родительским и дочерним компонентами! ! ! Не дурачьтесь.

Отзывчивое решение

Ниже приведены некоторые методы оценки, предоставленные vue3.

isRef: проверяет, является ли значение объектом ссылки.

isReactive: проверяет, создан ли объектreactiveСоздал реактивный прокси.

isReadonly: проверяет, прочитан ли объектreadonlyСоздал прокси только для чтения.

isProxy: проверяет, представлен ли объектreactive или readonlyСоздал прокси.

import {ref, reactive,readonly,isRef,isReactive,isReadonly,isProxy } from 'vue'
export default {
  name:'App',
  setup(){
    let fullName = reactive({name:'小唐',price:'20k'})
    let num = ref(0)
    let fullNames = readonly(fullName)
    console.log(isRef(num))
    console.log(isReactive(fullName))
    console.log(isReadonly(fullNames))
    console.log(isProxy(fullName))
    console.log(isProxy(fullNames))
    console.log(isProxy(num))
    return {}
  }
}

интересные компоненты

Fragment

Для меня это больше похоже на концепт, это значит, что при создании страницы дается виртуальный корневой тэгVNode, потому что мы знаем, что в vue2 у нас есть концепция корневого тега, но когда дело доходит до vue3, он автоматически создает для вас виртуальный корневой тег.VNode(Fragment), поэтому корневой тег можно опустить. ПреимуществоУменьшите уровень меток, уменьшите использование памяти

Teleport

teleportПредоставляет интересный способ, позволяющий нам контролировать, под каким родителем HTML отображается в DOM, без необходимости прибегать к глобальному состоянию или разбивать его на два компонента.

На самом деле не надо считать где пишешь, можно определитьteleportПозиционирование в любом теге (общая операция - модальное окно), помимо тела, можно также писать css-селекторы (id,class)

//id定位
 <teleport to="#app">
            <div class="four">
              <div class="five"></div>
            </div>
 </teleport>
//class定位
 <teleport to=".one">
            <div class="four">
              <div class="five"></div>
            </div>
 </teleport>
//示例
<template>
  <div class="one">
    <h1>第一层</h1>
    <div class="two">
      <h1>第二层</h1>
      <div class="three">
        <h1>第三层</h1>
        <teleport to="body">
            <div class="four">
              <div class="five"></div>
            </div>
        </teleport>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name:'App',
  setup(){
    return {}
  }
}
</script>

<style lang="less">
.one{
  width: 100%;
  background-color: blue;
  .two{
    margin: 20px;
    background-color: aqua;
    .three{
      margin: 20px;
      background-color: aliceblue;
    }
  }
}
.four{
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: rgba(0, 0, 0, 0.5);
  .five{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
    width: 300px;
    height: 300px;
    left: 50%;
    background-color:#f60;
  }
}
</style>

Откройте консоль и запустите событие, чтобы увидеть эффект

Suspense

Всем известно, что очень часто перед рендерингом компонентов делаются асинхронные запросы.suspenseКомпоненты предоставляют решение, которое позволяет поднимать ожидающие процессы вверх по дереву компонентов для обработки, а не в одном компоненте. но! ! ! Это специально указано в vue3,Приостановка — это экспериментальная новая функция, и ее API может быть изменен в любое время. Настоящим объявляется, чтобы сообщество могло оставить отзыв о текущей реализации., я просто смущен, предполагается, что это изменится в будущем, но вы можете прочитать статью, если вы готовы ее катитьНасколько удивителен телепорт vue3? Насколько просто саспенс инициировать асинхронные запросы?эм, не забудьте написать 800 слов

Другие изменения в Vue3

router

Может быть, вы подумаете о проблеме маршрутизации переходов, может быть, вы подумаете, что все еще используетеthis.$router.pushпрыгать, но в vue3 таких вещей не существует, он определяетvue-routerзатем импортировалuseRoute,useRouterЭквивалент vue2this.$route,this.$router, а затем могут быть выполнены другие предыдущие операции vue2

import {useRouter,useRoute} from "vue-router";
setup(){
  const router= useRouter()
  const route= useRoute()
  function fn(){
    this.$route.push('/about')
  }
  onMounted(()=>{
    console.log(route.query.code)
  })
  return{
    fn
  }
}

Передача глобального API

2.x глобальный API (Vue) API экземпляра 3.x (app)
Vue.config.xxxx app.config.xxxx
Vue.config.productionTip Удалить
Vue.component app.component
Vue.directive app.directive
Vue.mixin app.mixin
Vue.use app.use
Vue.prototype app.config.globalProperties

другие изменения

УдалитьKeyCode используется в качестве модификатора для V-On и больше не поддерживаетсяconfig.keyCodes

Удалитьv-on.nativeмодификатор

Удалитьфильтр(filter)

...

Кстати, если у вас чешутся руки и вы хотите практический проект, вы можете пойти и увидеть большого парня.🎉🎉Система управления фоном Vue 3 + Element Plus + Vite 2 имеет открытый исходный код🎉🎉

🎉🎉Заканчиваем цветы🎉🎉

Спасибо за ваши объяснения vue3 здесь, спасибо за их сильную поддержку! ! !

Спасибо монгольскому флоту за мощную поддержку этой колонны. Монгольский флот: «То, что мы хотим завоевать, — это море звезд!» '

Спасибо моей девушке, с которой я никогда раньше не встречался, за поддержку этой рубрики. «Прятки, верно? Ты прячешься так тайно, как я могу найти его? Оставь мне подсказку! ! ! немедленно! '