viteCreate a project
1. Run the create project command:
# 使用npm
npm create vite@latest
# 使用yarn
yarn create vite
# 使用pnpm
pnpm create vite
2. Summarize the differences in vue3 writing
Common components
<template>
<div>节点1</div>
<div>节点2</div>
</template>
main.js
import { createApp } from 'vue'
import App from './App.vue'
// 根据App组件创建一个应用实例
const app = createApp(App)
// app应用挂载(管理)index.html的 #app 容器
app.mount('#app')
index.html
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
vue3 combined api
1. setup function
setup
Functions areVue3
unique options and serve as starting points for compositional APIs- From the perspective of component life cycle, it
beforeCreate
executes before - The function
this
is not a component instance, it isundefined
- If the data or function is used in the template, it needs to be
setup
returned - In the future, it will hardly be used in vue3 projects
this
, and all things will be obtained through functions.
2. reactivel function
vue
Exportreactive
functions from- In
setup
the function, usereactive
the function, pass in a normal object, and return a responsive data object - Finally,
setup
the function returns an object that contains the responsive object, which can be used in the template reactive
Functions are usually defined: Reactive data of complex types- Cannot convert simple data
- Usage scenario: used when determining the type of the defined object
<template>
<div>
<p>姓名:{
{state.name}}</p>
<p>年龄:{
{state.age}} <button @click="state.age++">一年又一年</button></p>
</div>
</template>
<script>
// 1. 导入函数
import { reactive } from "vue";
export default {
setup() {
// 2. 创建响应式数据对象
const state = reactive({ name: 'tom', age: 18 })
// 3. 返回数据
return { state }
}
};
</script>
3. ref function
vue
Exportref
functions from- In
setup
the function, useref
the function, pass in common data (simple or complex), and return a responsive data - Finally,
setup
the function returns an object containing the responsive data - Note: Use
ref
the created data,js
which is required.value
andtemplate
can be omitted ref
Simple data or complex data can be converted into responsive data, pay attention to use plus.value
, but the template can be omitted.- Use scene: Any scene can be used.
<template>
<div>
<p>
计数器:{
{ count }}
<button @click="count++">累加1</button>
<!-- template中使用可省略.value -->
<button @click="increment">累加10</button>
</p>
</div>
</template>
<script>
// 1. 导入函数
import { ref } from "vue";
export default {
setup() {
// 2. 创建响应式数据对象
const count = ref(0);
const increment = () => {
// js中使用需要.value
count.value += 10;
};
// 3. 返回数据
return { count, increment };
},
};
</script>
4. The choice of reactive and ref
reactive
Objects can be converted into reactive data objects, but simple data types are not supported.ref
Simple data types can be converted to responsive data objects, and complex data types are also supported, but they are required during operation.value
.- It can be determined that the data is an object and the field name is also determined, which can be
reactive
converted into responsive data, and all others will be usedref
Code reference:
// 1. 明确表单对象有两个字段
const form = reactive({
username: '',
password: ''
})
// 2. 后台返回的数据对象
const data = ref(null)
const res = await axios.get('/user/100')
data.value = res.data
5. setup syntactic sugar
The so-called syntactic sugar of setup is to add setup directly in the script tag, and the script setup
top-level variables in it can be used in the template, data, functions, components, and do not need to return data functions
experience:
<script setup>
// 显示隐藏
const show = ref(true)
const toggle = () => {
show.value = !show.value
}
// 计数器
const count = ref(0)
const increment = () => {
count.value ++
}
</script>
<template>
<button @click="toggle">显示隐藏图片</button>
<img v-show="show" alt="Vue logo" src="./assets/logo.png" />
<hr />
计数器:{
{ count }} <button @click="increment">累加</button>
</template>
6. computed function
- Use to
computed
define computed properties, scenario: use computed properties when you need to rely on a data to get new data vue
Exportcomputed
functions from- In
setup
the function, usecomputed
the function, pass in a function, and the function returns the calculated data - Finally,
setup
the function returns an object that contains the calculated attribute data, and then used in the template
<script setup>
import { ref, computed } from "vue";
const scoreList = ref([80, 100, 90, 70, 60]);
// 计算属性
const betterList = computed(
() => scoreList.value.filter((item) => item >= 90)
);
// 改变数据,计算属性改变
setTimeout(() => {
scoreList.value.push(92, 66);
}, 3000);
</script>
<template>
<div>
<p>分数:{
{ scoreList }}</p>
<p>优秀:{
{ betterList }}</p>
</div>
</template>
7. watch function
grammar:
watch(需要监听的数据,数据改变执行函数,配置对象)
to listen for data- Data: single data, multiple data, function returns object properties, complex properties need to enable in-depth monitoring
- Configuration object:
deep
deep monitoringimmediate
is executed by default
- Use
watch
listener for a responsive data
const count = ref(0);
// 监听一个响应式数据
// watch(数据, 改变后回调函数)
watch(count, () => {
console.log("count改变了");
});
- Use
watch
listener for multiple responsive data
const count = ref(0);
const user = reactive({
name: "tom",
info: {
gender: "男",
age: 18,
},
});
// 监听多个响应式数据
// watch([数据1, 数据2, ...], 改变后回调函数)
watch([count, user], () => {
console.log("数据改变了");
});
- Use
watch
a (simple) property that listens to a reactive object's data
const user = reactive({
name: "tom",
info: {
gender: "男",
age: 18,
},
});
// 监听响应式对象数据的一个数据,简单类型
// watch(()=>数据, 改变后回调函数)
watch(()=>user.name, () => {
console.log("数据改变了");
});
- Configure deep listening using
watch
a (complex) property in the listening reactive object data
const user = reactive({
name: "tom",
info: {
gender: "男",
age: 18,
},
});
// 4. 监听响应式对象数据的一个数据,复杂类型
// watch(()=>数据, 改变后回调函数, {deep: true})
watch(
() => user.info,
() => {
console.log("数据改变了");
},
{
// 开启深度监听
deep: true,
}
);
- Use
watch
monitoring, configure default execution
{
// 开启深度监听
deep: true,
// 默认执行一次
immediate: true
}
8. Lifecycle functions
Steps for usage:
- First import the following life cycle hook function from vue , the life cycle needs to be introduced
on打头
before calling - Call the lifecycle function in the setup function and pass in the callback function
- The life cycle hook function can be called multiple times (emphasis)
- Life cycle comparison between Vue3 and vue2
Lifecycle function usage under optional API | Use of life cycle functions under combined API |
---|---|
beforeCreate | No need (write directly to the setup function) |
created | No need (write directly to the setup function) |
beforeMount | onBeforeMount 组件渲染挂载页面之前触发 |
mounted | onMounted 组件渲染完毕触发: Send requests, operate dom, initialize charts... |
beforeUpdate | onBeforeUpdate 组件更新之前触发 |
updated | onUpdated 组件更新之后触发 |
beforeDestroyed | onBeforeUnmount 组件卸载之前触发 |
destroyed | onUnmounted 组件卸载完成触发 |
activated | onActivated Components included in the page will have two more life cycle hook functions. Executed when activated . |
deactivated | onDeactivated For example, switch from A component to B component, and execute when A component disappears. |
9. ref to get DOM element
-
createref =>
const hRef = ref(null)
-
Create an association in the template =>
<h1 ref="hRef">我是标题</h1>
-
use =>
hRef.value
<script setup>
import { ref } from 'vue'
注意:默认值是null,需要在渲染完毕后访问DOM属性。
const hRef = ref(null)
const clickFn = () => {
hRef.value.innerText = '我不是标题'
}
</script>
<template>
<div>
<h1 ref="hRef">我是标题</h1>
<button @click="clickFn">操作DOM</button>
</div>
</template>
10. ref operation component-defineExpose
- The used
<script setup>
components are closed by default , and component instances cannot use top-level data and functions. - It needs to
defineExpose
be used in conjunction with exposure to component instances, and the exposed responsive data will automatically cancel the responsive.
Create a Form component defineExpose
to expose the components' members
Form组件:
<script setup>
import { ref } from 'vue'
const count = ref(0)
const validate = () => {
console.log('表单校验方法')
}
// 暴露属性给外部组件使用
defineExpose({count, validate})
</script>
<template>
<h3>我是Form组件</h3>
</template>
ref operation components :
- With
defineExpose
the exposure of data and methods, the component instance obtained by ref can be used
<script setup>
import { ref } from 'vue'
import Form from './components/Form.vue'
// 1. 提供一个ref
const formRef = ref(null)
// 2. 使用组件组件和方法
const fn = () => {
console.log(formRef.value.count)
formRef.value.validate()
}
</script>
<template>
<Form ref="formRef"></Form>
</template>
11. Parent-child-defineProps function
- Parent component provides data
- Parent component passes data to child component
- Subcomponents
defineProps
receive via - The child component renders the data passed by the parent component
ParentCom.vue父组件
<script setup>
import { ref } from 'vue'
import ChildCom from './components/ChildCom.vue'
const money = ref(100)
const car = ref('玛莎拉蒂')
</script>
<template>
<div>
<h1>我是父组件</h1>
<div>金钱:{
{ money }}</div>
<div>车辆:{
{ car }}</div>
<hr />
<ChildCom :money="money" :car="car"></ChildCom>
</div>
</template>
ChildCom.vue child component
<script setup>
import { computed } from 'vue'
// defineProps: 接收父组件传递的数据
const props = defineProps({
money: Number,
car: String,
})
// 如果想要在 script 中也操作 props 属性,应该接收返回值
// 使用props接收返回值
console.log(props.money)
</script>
<template>
如果使用 defineProps 接收数据,这个数据只能在模板中渲染
<div>
<h3>我是子组件</h3>
<div>{
{ money }} --- {
{ car }}</div>
</div>
</template>
- If
defineProps
receiving data is used, this data can only be rendered in the template - If you want to
script
also operate onprops
attributes, you should receive the return value
12. Pass from child to parent - defineEmits function
- The subcomponent gets
defineEmits
theemit
function (because there is no this) - Subcomponents
emit
trigger events and pass data - The method provided by the parent component
- The parent component registers events for the child components through custom events
ChildCom.vue child component
defineEmits
Getemit
the function, and the event that the component needs to trigger needs to be explicitly declared
<script setup>
defineProps({
money: Number,
car: String,
})
// 得到emit函数,显性声明事件名称
const emit = defineEmits(['changeMoney'])
const change = () => {
emit('changeMoney', 10)
}
</script>
PrarentCom.vue parent component
<script setup>
import { ref } from 'vue'
import ChildCom from './components/ChildCom.vue'
const money = ref(100)
const car = ref('玛莎拉蒂')
const changeMoney = (num) => {
money.value = money.value - num
}
</script>
<ChildCom :money="money" :car="car" @changeMoney="changeMoney"></ChildCom>
13. Cross-level component communication provide and inject functions
-
Provide and inject are solutions for cross-level component communication
- provide provides data or functions that descendant components need to depend on
- inject Inject (obtain) the data or function provided by provide
Ancestor component:App.vue
import { provide, ref } from 'vue';
import ParentCom from './ParentCom.vue';
// 1. app组件数据传递给child
const count = ref(0);
provide('count', count);
// 2. app组件函数传递给child,调用的时候可以回传数据
const updateCount = (num) => {
count.value += num;
};
provide('updateCount', updateCount);
Descendant child components:ChildCom.vue
<script setup>
import { inject } from 'vue';
const count = inject('count');
const updateCount = inject('updateCount');
</script>
<template>
<div class="child-page" style="padding: 50px; border: 10px solid #ccc">
child 组件 {
{ count }} <button @click="updateCount(100)">修改count</button>
</div>
</template>
14. Keep Responsive - toRefs function
- Use toRefs to maintain responsiveness when reactive data created with reactive is unwrapped or destructured
- Use deconstructed responsive data to expand responsive data stepping
基础写法:
<script setup>
import { reactive } from "vue";
const user = reactive({ name: "tom", age: 18 });
</script>
<template>
<div>
<p>姓名:{
{ user.name }}</p>
<p>年龄:{
{ user.age }} <button @click="user.age++">一年又一年</button></p>
</div>
</template>
解构写法: 响应式丢失
<script setup>
import { reactive } from "vue";
const { name, age } = reactive({ name: "tom", age: 18 });
</script>
<template>
<div>
<p>姓名:{
{ name }}</p>
<!-- 响应式丢失 -->
<p>年龄:{
{ age }} <button @click="age++">一年又一年</button></p>
</div>
</template>
- Use to
toRefs
process responsive data, crawling pits
import { reactive, toRefs } from "vue";
const user = reactive({ name: "tom", age: 18 });
const { name, age } = toRefs(user)
toRefs
Functions and usage scenarios
- Function: wrap each attribute in the object into responsive data
- Used when the responsive data is expanded, used when deconstructing the responsive data