предисловие
Автор в настоящее время является старшим и прошел стажировку в Пекине.Поскольку мой наставник попросил меня сделать технический обмен, я решил поделиться vue3, который я недавно изучил, и поскольку форма обмена не ограничена, поэтому я планирую написать в Наггетс.
Автор находится в контакте с vue3 уже почти 100 дней.Возможны ошибки в понимании vue3.Если есть неправильное понимание прошу меня простить. И поскольку vue3 предпочитает машинописный текст машинописному тексту, а автор предпочитает использовать машинописный текст, ниже автор использует машинописный текст, но даже если читатель не знает машинописный текст, это не должно влиять на чтение.
Учитывая объем статьи, эта статья будет разделена на три части: верхняя, средняя и нижняя части.В первой части в основном рассказывается о рутинном использовании vue3. Средняя часть в основном рассказывает о некоторых небольших принципах vue3, а вторая часть представляет собой книгу, написанную автором с использованием vue3+deno/node (используя и deno, и node для написания рваного интерфейса, в основном авторские нодовые блюда, deno больше блюд ), небольшой проект оценивается примерно в 3000 строк кода.Эта статья — первая.
Я надеюсь, что каждый может поставить небольшой лайк, добавить в избранное и не развивать привычку заниматься проституцией, как я.
Добавьте демо-адрес github:GitHub.com/1131446340 Аааа…
g
Добавлен vue3 от входа до реального боя) (посередине)Наггетс.Талант/пост/687072…
Жизненный цикл vue3 и использование nextTick
В vue3 сначала знакомятся с большинством применений, а затем вызываются функции, а стоимость обучения чрезвычайно низка.Если у вас есть опыт разработки vue2, начать работу должно быть легко.Давайте рассмотрим небольшой пример.
<script lang="ts">
import { onMounted, onBeforeMount, nextTick} from 'vue'
export default {
name: 'App',
setup() {
nextTick(() => {
console.log('nextTick');
})
onMounted(() => {
console.log('mounted');
})
onBeforeMount(() => {
console.log('beforeMounted');
})
console.log('hello vite Vue3')
}
}
</script>
В vue3 setup() — это функция входа, которая эквивалентна ранее созданному и ранее созданному жизненным циклам. Вы можете видеть, что другие жизненные циклы могут быть вызваны в функции настройки.Я думаю, что этот код нечего объяснять, и каждый может понять порядок вывода с первого взгляда.
vue реактивная система и методы
Давайте сначала посмотрим на код
<template>
<div>
<h3>vue3响应式系统和methods</h3>
<div>年龄:{{ myAge }}</div>
<div>明年的年龄:{{ mylastAge }}</div>
<button @click="AgeAdd">年龄+1</button>
<div>姓名:{{ myName }}</div>
<div>
爱好:
<div v-for="(hoppy, index) in hoppys" :key="index">{{ hoppy }}</div>
</div>
<div>来自 {{ state1.from }}</div>
</div>
</template>
<script lang="ts">
import HelloWorld from './components/HelloWorld.vue'
import {
ref,
toRefs,
reactive,
watchEffect,
watch,
computed,
onMounted
} from 'vue'
export default {
name: 'App',
setup () {
let myAge = ref(23) //响应式数据
let myName = '黄力豪' //非响应式数据
const state = reactive({
//复杂数据响应式 类似data 基于proxy 操作数组也会触发响应式
hoppys: ['中国象棋', 'javaScript']
})
const state1 = reactive({
// 可以定义多个数据源
from: '江西抚州'
})
watchEffect(() => {
// watch 副作用函数 首次加载会触发,当值发生变化也会触发
console.log('年龄:' + myAge.value)
console.log('爱好:' + state.hoppys)
})
let mylastAge = computed(() => {
return myAge.value + 1
})
setTimeout(() => {
state.hoppys[1] = 'typeScript'
myAge.value += 1
myName = '力豪'
}, 1000)
watch([state.hoppys, myAge], newVal => {
//可以监听多个值
console.log('watch:' + newVal)
})
const methods = {
AgeAdd () {
myAge.value += 1
}
}
return {
myName,
myAge,
...toRefs(state), //将reactive转化为ref
state1,
mylastAge,
...methods
}
}
}
</script>
Вам не составит труда увидеть, что способ использования шаблона в vue 3 практически не изменился. ).
Давайте взглянем на код ts. Говорят, что это ts. На самом деле эти данные можно вывести с помощью вывода типов. На самом деле он выглядит так же, как js.
Во-первых, в шаблоне можно использовать любые данные, возвращаемые функцией настройки, но не реактивные данные.
В vue3 автор обнаружил, что существует два способа преобразования неотзывчивых данных в отзывчивые, то есть функция ref и реактивная функция. ref должен быть реализован на основе Object.defineProperty. Реактив реализован на основе прокси, поэтому рекомендуется использовать ref для общих типов данных и прокси для сложных типов данных. Но следует отметить, что использование ref означает манипулирование его атрибутом value для изменения значения, но нет необходимости добавлять значение в шаблон. На самом деле, я предпочитаю такой способ написания:
const state = reactive({
name:"",
age:0,
Array:[]
})
Таким образом, достаточно напрямую определить источник данных, который используется в vue2, и то же самое верно для методов. Внимательные читатели должны найти эти методы деконструкции и состояние деконструкции в функции настройки, чтобы данные можно было легко записать в шаблон.Вы можете спросить, что такое toRefs.Данные преобразуются в данные ссылок.
Использование вычислений в vue3 в основном такое же, как и раньше, но выражение изменено на форму компонентного API, так что разговоров мало.
Есть некоторые изменения в watch в vue3, то есть он может мониторить несколько значений одновременно, и при изменении одного из них сработает watch.
То, что вы, возможно, не видели здесь, это watchEffect.Друзья, которые узнали о реакции, должны быть знакомы с этим. watchEffct будет вызываться один раз в начале и будет выполняться повторно при изменении данных, используемых в watchEffect.
props и ref bind dom
<template>
<div>
<h3 ref="H3">ref,props 和一些小功能</h3>
</div>
</template>
<script>
import { ref, onMounted } from 'vue'
export default {
setup () {
let H3 = ref(null)
onMounted(() => {
H3.value.style.color = 'red'
})
//还有一些小功能
// readonly 数据只读
// shallow -( reactive,ref,readonly) 只代理一层
// toRaw 将reactive或者readonly 的值还原
//markRow 永远不会被代理
//isRef isReactive 等
//unref 如果参数是ref返回他的value否则返回参数
return { H3 }
}
}
</script>
Прежде всего, друзья, которые использовали vue2, знают, что ref можно использовать для получения элементов dom.В vue3 вам нужно только передать пустое значение в ref, а затем привязать его в don, чтобы использовать его.Обратите внимание, что для этого нужно использоваться в mount.Кроме того, следует помнить, что значение ref получается через его атрибут value. Есть также некоторые небольшие функции, о которых вы можете понять, посмотрев комментарии.
система компонентов
Существует много способов определения компонентов в vue 3. Самая большая разница заключается в том, что использование jsx/tsx для определения компонентов в vue 3 намного проще, чем в vue 2. Кроме того, компоненты включают в себя дочерние элементы, реквизиты, атрибуты, эмиссию, слот и т.д. Поэтому об этом можно сказать подробнее.
<template>
<div>
<h3>组件</h3>
<Hello name="黄力豪" @updateName="updateName"></Hello>
<Age :age="33"></Age>
<myInput>
<template v-slot:desc>
<div>
这是输入框
</div>
</template>
</myInput>
</div>
</template>
<script lang="ts">
import Hello from './TSX/Hello'
import Age from './components/Age.vue'
export default {
components:{
Hello,Age
},
setup(){
const updateName =()=>{
console.log(1);
}
return {updateName}
}
}
</script>
Как видите, я написал три компонента: hello, age и myInput, которые на самом деле являются тремя компонентами.
Сначала давайте посмотрим на компонент возраста
<template>
<div>
<div>{{ props.age }}</div>
</div>
</template>
<script lang="ts">
import { reactive, isReadonly, toRaw, inject, ref, readonly } from 'vue'
interface Props {
age: number
}
import vuex from '../shared/vuex'
export default {
props: {
age: {
type: Number,
default: 0
}
},
setup (props: Props) {
// props 是readonly
//不要尝试去解构props,因为这样会让props失去响应式
// props.age = 23
// console.log(isReadonly(props))
props = reactive(toRaw(props))
return {
props
}
}
}
</script>
Первый компонент в основном похож на vue2.Обратите внимание, что функция настройки на самом деле имеет два параметра.Первый из них - реквизит.Стоит отметить, что вы не должны пытаться деконструировать реквизит, иначе он сделает реквизит не отвечающим. , реквизит доступен только для чтения упомянутое выше, которое является свойством только для чтения.Если вы попытаетесь изменить свойства, будет сообщено предупреждение. О readonly, я думаю, я сделал следующее
let proxy = new Proxy(obj, {
set(target, key, value) {
target[key] = value
},
get(target, key) {
return target[key]
}
})
function readonly(proxy) {
return new Proxy(proxy, {
get(target, key) {
return target[key]
},
set() {
throw Error()
}
})
}
Если вы настаиваете на изменении реквизита, вы можете восстановить реквизит в Reactive с помощью toRaw.
Давайте посмотрим на компонент hello, компонент hello написан с использованием tsx.
export default {
setup (
props: object,
{ attrs, emit }: { attrs: { name: string }; emit: Function }
) {
return { attrs, emit }
},
render (props: { attrs: { name: string }; emit: Function }) {
return (
<div
onClick={() => {
props.emit('updateName')
}}
>
hello {props.attrs.name}
</div>
)
}
}
Если вам нравится использовать синтаксис tsx, вы можете напрямую экспортировать объект ts. Этот объект в основном похож на использование файла .vue, за исключением того, что есть дополнительная функция рендеринга для записи html. Кроме того, я лично считаю, что tsx vue3 лучше, чем реагировать.
Сначала давайте посмотрим на функцию настройки, на этот раз я дал второй параметр и разобрал его, чтобы разобрать attrs и выдать. Все знакомы с emit, поэтому я не буду слишком подробно о нем рассказывать. Посмотрим на attrs, по интерфейсу ts нетрудно заметить, что есть атрибут name, да, именно атрибут name, переданный из родительского компонента. Некоторые друзья здесь могут спросить, а разве не обязательно передавать реквизит от отца к сыну? Да, мы можем использовать props, как и раньше, но чтобы использовать props, мы должны объявить объект props выше, теперь мы можем получить его напрямую через attrs, так почему бы не сделать это. Также обратите внимание, что атрибуты по-прежнему доступны для чтения и записи, но не только для чтения.Если вы попытаетесь изменить атрибуты, будет сообщено об ошибке. Если вы выполняете модификации, вы можете попытаться сделать глубокие и мелкие копии в соответствии с данными и потребностями.
Давайте взглянем на функцию рендеринга. Первый параметр функции рендеринга обычно называется реквизитом. Реквизитом рендеринга является объект со многими свойствами, такими какСлоты, $attrs и т. д. Кроме того, также комбинируется возвращаемое значение функции настройки.
attrs и $emit заменяют attrs и emit и удаляют функцию установки.
Мы видим, что функцию emit можно использовать в сын-к-отцу, намного ли это удобнее, чем реагировать сын-к-отцу?
Еще одним преимуществом использования tsx является то, что если вы используете шаблон шаблона, мы требуем, чтобы функция передавала данные типа number, но другие типы параметров, передаваемые в шаблоне, вообще нельзя проверить, но вы можете легко проверить это с помощью tsx.
Последний — это глобальный компонент myInput.
import {
reactive,
vShow,
vModelText,
withDirectives,
App,
isReadonly
} from 'vue'
interface Props {
number: number
$slots: {
desc: () => any[]
}
desc: () => {}
input: any
isShow: boolean
}
import { toRefs } from 'vue'
const install = (app: App) => {
app.component('myInput', {
props: {
number: {
type: String
}
},
setup (props: Props, { slots }) {
const state = reactive({ input: 0, isShow: false })
return { ...toRefs(slots), ...toRefs(state) }
},
data () {
return {
number: 0
}
},
render (props: Props) {
console.log(isReadonly(props))
return (
<div>
<div v-show={props.isShow}>你看不见我</div>
{props.desc()}
{props.$slots.desc()[0]}
{/* {withDirectives(<input type='text' />, [[vModelText, this.number]])} */}
<div>{this.number}</div>
{withDirectives(<h1>Count: 2</h1>, [[vShow, true]])}
</div>
)
}
})
}
export default {
install
}
Глобальный компонент в основном аналогичен предыдущему использованию.Передается функция установки.Обратите внимание, что первый параметр не является классом Vue, и нет никакого прототипа.Вы можете использовать функцию app.component для регистрации плагина.Использование в основном похож на прошлый.Первый - это имя компонента, а второй - компонент. Здесь я все еще выбираю синтаксис tsx. Видно, что второй параметр функции установки деконструирует слоты.
Давайте посмотрим на функцию рендеринга ниже Я пытался использовать v-show, но это не сработало. Я погуглил кое-что и обнаружил, что для того, чтобы написать подобное, нужно использовать babel. Что касается слота, родительский компонент передает слот desc.В vue3 слот имеет форму вызова функции. Вышеуказанные два метода использования слотов могут быть использованы, и каждый может обратить внимание на разницу. Инструкции действительно можно использовать в функции vue3, withDirectives(). После попытки использовать vShow вступает в силу. VModel присваивает только начальное значение. После ввода содержимого будет сообщено об ошибке. Конкретный метод использования еще не определен нашел. Тем не менее, эти записи все еще относительно громоздки, и я надеюсь, что официальный натив поддерживает те же инструкции по написанию, что и Templete.
Директивы и свойства css реагируют
<template>
<div>
css 属性响应式与指令
<h1 v-highlight="红色">这是一串被高亮为红色的字</h1>
</div>
</template>
<script>
export default {
setup(){
return {
"红色": 'red',
"字体大小": '40px',
}
}
}
</script>
<style vars='{红色, 字体大小}'>
div{
color: var(--红色);
font-size: var(--字体大小);
}
</style>
Я не знаю, задумывались ли мои друзья об использовании адаптивного css в vue, но я думал об этом, и теперь vue3 его поддерживает.
Способ использования тоже очень простой.Добавьте vars={} в стиль и затем разделите переменные запятыми.При этом он поддерживает использование китайского языка,и тогда переменные css используются нормально.
Инструкции, используемые в vue3
const app = createApp(Demo)
app.directive('highlight', {
beforeMount(el, binding, vnode) {
el.style.color = binding.value;
},
pdated(){},
mounted(){},
created(){}
});
Вы должны знать, как использовать его с первого взгляда, так что вы не будете тратить слишком много слов.
глобальная связь
Я нашел три типа глобальной связи в vue3, первый — использовать предоставление и внедрение
<template>
<div>
<h3>全局通信</h3>
{{myName}}
<Age></Age>
爱好:{{hoppy}}
</div>
</template>
<script lang="ts">
import {toRefs, provide,ref, inject} from 'vue'
import vuex from './shared/vuex'
import Age from './components/Age.vue'
export default {
components:{
Age
},
setup(){
const {myStore, updateName, updatedAge } = vuex
updateName('力豪')
updatedAge(18)
provide('hoppy',ref('javascript'))
let hoppy = ref(inject('hoppy') as string)
return {...toRefs(myStore),hoppy}
}
}
</script>
Предоставить и внедрить производные от Vue.Если в компоненте используется предоставление, его потомки и потомки могут получить значение, предоставленное предоставлением. Первый параметр — это предоставленное имя, может использоваться либо строка, либо символ. Во-вторых, данные, переданные в прошлом, Но учтите, что если вы хотите сделать его реактивным, вам нужно обернуть его ref или реактивным. Подкомпоненты можно использовать с помощью inject. В vuex vue3 он тоже основан на этом API.
Второй метод
Создайте файл напрямую, используйте функцию модуля es6 и экспортируйте объект, после чего оба компонента смогут импортировать этот объект. Лично мне этот способ до сих пор нравится, он достаточно прост и понятен и багов в использовании пока не обнаружено.
import { reactive } from 'vue';
const myStore = {
myName: '黄力豪',
myAge: 23
};
const updateName = (newName: string) => {
myStore.myName = newName;
};
const updatedAge = (newAge: number) => {
myStore.myAge = newAge;
};
export default { myStore, updateName, updatedAge };
Кроме того, этот метод также имеет то преимущество, что экспортируемый объект превращается в функцию, а объект возвращается в функцию.При его использовании вместо вызова функции эти атрибуты не будут использоваться совместно, что аналогично миксинам в vue2. .
Третье, несомненно, использование vuex, но лично мне кажется, что от vuex можно вообще отказаться в vue 3. В следующей статье я кратко разберу его принцип, но не буду здесь слишком много описывать.
Первый компонент пользовательского интерфейса vue3
Этот компонент является второй версией antd design Vue, вышедшей на 9.1.Это должна быть бета-версия.Вы можете использовать его по инструкции на официальном сайте. Когда автор писал небольшой проект vue3, стороннего компонента ui не было, автор просто немного модифицировал elementUI, чтобы можно было использовать определенный компонент в vue3, но наступил на некоторые ямы, компонент лучше переписать на сами.
Эпилог
В дополнение к vue-router, vuex и фильтрам основные операции vue3 в основном закончены. Однако в vue3 нет фильтра, вы можете просто использовать вызов функции напрямую, поэтому вы сможете построить колесо после изучения vue-router.
В следующей статье будет кратко рассказано о некоторых известных принципах API отключенной версии vue.