1、vue3 新特性
vue3 新特性:性能更高、体积更小、更利于复用、代码维护更方便
-
数据响应式原理重新实现(
ES6的proxy替代ES5的Object.definedPropety),大大优化了响应式监听的性能 -
原来检测对象属性的变化,需要一个个对属性递归监听,
proxy可以直接对整个对象劫持 -
vue3源码用TypeScript(ts)重写了,更好的类型推导,类型检测更为严格、更稳定 -
模块可以有多个根元素(
template里面可以有多个根元素) -
optionsAPI(旧)→compositionAPI(新),可以更好的逻辑复用 与代码组织 -
虚拟
DOM-新算法更快、更小
2、基于 vite 创建 vue3 的工程化项目
法1 yarn
yarn create vite-app vue3-study(项目名称)
cd vue3-study
yarn
yarn dev
法2 npm
npm init vite-app vue3-study(项目名称)
cd vue3-study
npm install
npm run dev
可以看出,在 vue3 的工程化的项目中,vue 要做的事情很单纯:通过 main.js 把 App.vue 渲染到 index.html 的指定区域中。 其中:
App.vue用来编写待渲染的模板结构index.html中需要预留一个 el 区域main.js把App.vue渲染到了index.html所预留的区域中
插件:
Vue VSCode Snippets、Vue Language Features(Volar)
3、vue3 生命周期钩子函数
vue3生命周期钩子函数setup创建实例前onBeforeMount挂载 DOM 前onMounted挂载 DOM 后onBeforeUpdate更新组件前onUpdated更新组件后onBeforeUnMount卸载销毁前onUnmounted卸载销毁后
4、setup 函数
composition 的使用, 需要配置一个 setup 函数
setup函数是一个新的组件选项, 作为组件中compositionAPI的起点- 从生命周期角度来看,
setup会在beforeCreate钩子函数之前执行 - setup 中不能使用 this, this 指向 undefined
- 在模版中需要使用的数据和函数,需要在
setup返回
<template>
<div>
<p>打个招呼:{{ hello }}</p>
</div>
</template>
<script>
export default {
setup() {
const hello = "你好呀";
return { hello };
},
};
</script>
5、reactive 函数
reactive 函数
setup需要返回值, 返回的值才能在模板中使用- 默认的普通的值不是响应式的, 需要用
reactive函数 reactive函数将复杂数据类型转换成响应式数据(返回该对象的响应式代理)
<template>
<div>
<!-- 一点击,视图层的 name 变成“李四” -->
<p>我是{{ obj.name }}</p>
<button @click="fn">按钮</button>
</div>
</template>
<script>
import { reactive } from "vue";
export default {
setup() {
const obj = reactive({
name: "前端小白兔",
age: 18,
hobby: "敲代码",
});
const fn = () => {
obj.name = "李四";
console.log(obj); //Proxy {name: '李四', age: 18, hobby: '敲代码'}
console.log(obj.name); //李四
};
return { obj, fn };
},
};
</script>
6、ref 函数
reactive 处理的数据, 必须是复杂类型, 如果是简单类型无法处理成响应式, 由此 ref 函数诞生!
作用: 对传入的数据(一般简单数据类型),包裹一层对象, 转换成响应式
ref函数接收一个的值, 返回一个ref响应式对象, 有唯一的属性value- 在
setup函数中, 通过ref对象的value属性, 可以访问到值 - 在模板中,
ref属性会自动解套, 不需要额外的.value ref函数也支持传入复杂类型,传入复杂类型,也会做响应式处理(例如Array)- 明确的对象,明确的属性,用
reactive,其他用ref
<template>
<div>
<p>{{ count }}</p>
<button @click="addFn">按钮</button>
<h1 v-if="flag">{{ flag }}</h1>
</div>
</template>
<script>
import { ref } from "vue";
export default {
setup() {
const count = ref(1);
const flag = ref(true);
const addFn = () => {
count.value++;
flag.value = !flag.value;
};
return { count, flag, addFn };
},
};
</script>
7、toRef 函数
toRef(目标对象,指定变成响应式对象的属性)
<template>
<div>
<!-- 一点击全部变成了新数据 -->
<p>我是{{ obj.name }},我今年{{ obj.age }},我的爱好是{{ obj.hobby }}</p>
<p>我是{{ name }},我今年{{ age }},我的爱好是{{ hobby }}</p>
<button @click="fn">按钮</button>
</div>
</template>
<script>
import { reactive, toRef } from "vue";
export default {
setup() {
const obj = reactive({
name: "前端小白兔",
age: 18,
hobby: "敲代码",
});
const name = toRef(obj, "name");
const age = toRef(obj, "age");
const hobby = toRef(obj, "hobby");
const fn = () => {
name.value = "张三";
age.value = 30;
hobby.value = "玩魔方";
};
return { obj, fn, name, age, hobby };
},
};
</script>
8、toRefs 函数
使用场景: 如果对一个响应数据, 进行解构 或者 展开, 会丢失他的响应式特性!
原因: vue3 底层是对 对象 进行监听劫持
作用: 对一个响应式对象的所有内部属性, 都做响应式处理
reactive的响应式功能是赋值给对象的, 如果给对象解构或者展开, 会让数据丢失响应式的能力- 使用
toRefs可以保证该对象展开的每个属性都是响应式的
<template>
<div>
<p>我是{{ name }},我今年{{ age }},我的爱好是{{ hobby }}</p>
</div>
</template>
<script>
import { reactive, toRefs } from "vue";
export default {
setup() {
const obj = reactive({
name: "前端小白兔",
age: 18,
hobby: "敲代码",
});
return { ...toRefs(obj) };
},
};
</script>
<template>
<div>
<p>我是{{ name }},今年{{ age }}岁了,我的爱好是{{ hobby }}</p>
<button @click="fn">按钮</button>
</div>
</template>
<script>
import { reactive, toRefs } from "vue";
export default {
setup() {
const obj = reactive({
name: "前端小白兔",
age: 18,
hobby: "敲代码",
});
const newobj = toRefs(obj);
const fn = () => {
newobj.name.value = "李四";
newobj.age.value = 24;
newobj.hobby.value = "魔方";
};
return { ...newobj, fn };
},
};
</script>
<template>
<div>
<p>我是{{ name }},今年{{ age }}岁了,我的爱好是{{ hobby }}</p>
<button @click="fn">按钮</button>
</div>
</template>
<script>
import { reactive, toRefs } from "vue";
export default {
setup() {
const obj = reactive({
name: "前端小白兔",
age: 18,
hobby: "敲代码",
});
const fn = () => {
obj.name = "李四";
obj.age = 24;
obj.hobby = "魔方";
};
return { ...toRefs(obj), fn };
},
};
</script>
9、模板中 ref 的使用(获取 DOM)
<template>
<div>
<div class="box1" ref="dom1">我是 box1</div>
<div class="box2" ref="dom2">我是 box2</div>
</div>
</template>
<script>
import { onMounted, ref } from "vue";
export default {
setup() {
const dom1 = ref(null);
const dom2 = ref(null);
onMounted(() => {
console.log(dom1, "111"); //RefImpl {}
console.log(dom2, "222"); //RefImpl {}
console.log(dom1.value, "111"); // <div class="box1">我是 box1</div> '111'
console.log(dom2.value, "222"); // <div class="box2">我是 box2</div> '222'
});
return { dom1, dom2 };
},
};
</script>