目录
Vue3
优点
- 更小的打包体积和内存
- 更好的支持 TypeScript
- 页面第一次的渲染速度和更新速度更快
- 新增了 Composition API 和内置组件
Vue脚手架 Vue CLI 创建一个Vue3的项目
1:安装脚手架
npm install -g @vue/cli
Node 版本要求
Vue CLI 4.x 需要 Node.js v8.9 或更高版本 (推荐 v10 以上)。你可以使用 n,nvm 或 nvm-windows 在同一台电脑中管理多个 Node 版本。
2:创建一个项目
vue create hello-vue3
报错:vue : 无法加载文件xxx 因为在此系统上禁止运行脚本
解决:以管理员身份运行VS Code,在终端输入 set-ExecutionPolicy RemoteSigned 即可。
使用 vue -V 查看 Vue CLI版本
vue -V
然后
cd hello-vue3
npm run serve
打开网页 http://localhost:8080。这样一个 Vue3 脚手架项目就创建完成了
3:Vue初始项目文件
-
main.js
整个项目的入口文件
-
App.vue
所有⼦组件的⽗组件
Vue3的Composition API
-
setup 函数
- setup 函数是Vue3新的配置项
- 是使用组合API的前提,数据、方法都要放到 setup 函数里声明
- 在生命周期函数 beforeCreate 之前执行一次,而且 setup 函数没有 this
<template>
<div>姓名:{{name}}</div>
<div>年龄:{{age}}</div>
<button @click="hello">打招呼</button>
</template>
<script>
export default {
setup() { // setup函数,里面使用 js 原生语法
let name = '张三';
let age = 18;
function hello () {
alert(`你好,我是${name},今年${age}岁了`);
}
return { // vue 中要使用 setup 里定义的变量、函数的话,需要把变量、函数 return 出去
name,
age,
hello
}
}
}
</script>
-
setup 的参数
参数:props
用于接收父组件的值
<script>
export default {
props: ["msg"], // 接收父组件的值
setup(props) {
console.log(props.msg); // setup 中获取父组件的值
}
}
</script>
参数:context
上下文对象,触发自定义事件
父组件代码
<template>
<!-- 定义自定义事件 -->
<HelloWorld @dj="handleDianji"/>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
components: {
HelloWorld
},
setup() {
// 自定义事件回调
function handleDianji(value) {
console.log("打印子组件传过来的值=", value);
}
return {
handleDianji
}
}
}
</script>
子组件代码
<template>
<button @click="dianji">点击</button>
</template>
<script>
export default {
emits: ["dj"], // 声明自定义事件
setup(props, context) {
function dianji() {
context.emit("dj", "我是子组件的值"); // 触发自定义事件
}
return {
dianji
}
}
}
</script>
-
ref 函数
实现数据的响应式 // setup定义的变量数据,如果想通过setup中定义的函数改变数据是没有作用的。这里就要用到 ref 函数改变数据
- 可以处理基本类型数据、数组或者对象类型的数据
- 基本类型数据的响应式是通过 Object.defineProperty() 实现
- 对象类型数据的响应式是通过 ES6 中的 Proxy 实现
<template>
<div>姓名:{{name}}</div>
<div>年龄:{{age}}</div>
<div>性别:{{obj.sex}}</div>
<button @click="hello">打招呼</button>
<button @click="changePreson">切换人员</button>
</template>
<script>
import { ref } from "vue"; // 引入 ref 函数
export default {
setup() {
let name = ref("张三"); // ref 操作基本数据类型
let age = ref(18);
let obj = ref({ // ref 操作对象
sex: "man"
});
function hello() {
alert(`你好,我是${name.value},今年${age.value}岁了, 性别${obj.value.sex}`);
}
function changePreson() {
name.value = "李四";
age.value = "20";
obj.value.sex = "female"
}
return {
name,
age,
obj,
hello,
changePreson
}
}
}
</script>
-
reactive 函数
定义一个对象类型的响应式数据(不能处理基本类型数据)
<template>
<div>姓名:{{name}}</div>
<div>年龄:{{age}}</div>
<div>性别:{{obj.sex}}</div>
<button @click="hello">打招呼</button>
<button @click="changePreson">切换人员</button>
</template>
<script>
import { ref, reactive } from "vue"; // 引入 ref 函数
export default {
setup() {
let name = ref("张三"); // ref 操作基本数据类型
let age = ref(18);
let obj = reactive({ // reactive 操作对象
sex: "man"
});
function hello() {
alert(`你好,我是${name.value},今年${age.value}岁了, 性别${obj.sex}`);
}
function changePreson() {
name.value = "李四";
age.value = "20";
obj.sex = "female"
}
return {
name,
age,
obj,
hello,
changePreson
}
}
}
</script>
-
ref 和 reactive 的区别
- 处理数据类型不同:ref 可以处理基本类型和对象(数组)类型数据, reactive 只能处理对象(数组)类型数据
- 实现原理不同:ref 处理基本类型数据通过 Object.defineProperty() 实现, reactive 通过Proxy 实现
- 操作不同: ref 操作数据需要加 .value
-
setup 的 computed 函数
<template>
<div>{{fullName}}</div>
</template>
<script>
import { ref, computed } from "vue";
export default {
setup() {
let firstName = ref("张");
let lastName = ref("三");
let fullName = computed({
get() {
return firstName.value + "-" + lastName.value;
},
set(value) {
const arr = value.split("-");
firstName.value = arr[0];
lastName.value = arr[1];
}
})
return {
firstName,
lastName,
fullName
}
}
}
</script>
-
setup 的 watch函数
<template>
<h1>
当前的计数a:<span>{{ numa }}</span> <br />
当前的计数b:<span>{{ numb }}</span> <br />
</h1>
<button @click="numa++">增加a</button>
<button @click="numb++">增加b</button>
<hr />
</template>
<script>
import { ref, watch } from "vue";
export default {
setup() {
let numa = ref(1);
let numb = ref(1);
watch([numa, numb], (newValue, oldValue) => {
console.log("numa或者numb变化了", newValue, oldValue);
}, { immediate: true, deep: true });
return {
numa,
numb
};
},
};
</script>
监听对象
watch(numObj, (newValue, oldValue) => {
console.log("numObj变化了", newValue, oldValue);
})
监听对象中的一个基本类型属性
watch(
() => numObj.a,
(newValue, oldValue) => {
console.log("numObj变化了", newValue, oldValue);
}
);
监听对象中的一些基本类型属性
watch([() => numObj.a, () => numObj.b], (newValue, oldValue) => {
console.log("numObj变化了", newValue, oldValue);
});
监听对象中的对象属性类型
watch(
numObj.c,
(newValue, oldValue) => {
console.log("numObj.c变化了", newValue, oldValue);
}
);
- ref 定义的数据
- 基本类型数据作为监听值
- 对象作为监听值,需要加 .value (⽤的少)
- reactive 定义的数据
- 对象作为监听值
- 属性作为监听值,需要放在回调函数中
- 如果监听 reactive 定义的对象,则无法正确输出 oldValue ,且深度监听是强制开启的,无法关闭 (vue3配置)
-
setup 的 watchEffect 函数
在监听的回调函数中使⽤了属性,则监听该属性,不⽤在参数上指明监听哪个属性
<script>
import { ref, watchEffect } from "vue";
export default {
setup() {
let numa = ref(1);
watchEffect(() => {
console.log(numa.value); // 在监听中使用了 numa 属性,就默认监听此属性
console.log("watchEffect函数执行了");
});
return {
numa
};
}
};
</script>
-
setup 的 toRef 函数
创建一个 ref 对象,其 value 值指向另一个对象中指定的属性 // 相当于起了个别名
<template>
<h1>
<!-- {{data.name}} // 未使用toRef的方式 -->
{{aliasName}} <!-- 使用 toRef 的方式-->
</h1>
</template>
<script>
import { reactive, toRef} from "vue";
export default {
setup() {
let data = reactive({
name: "张三"
});
let aliasName = toRef(data, "name"); // 相当于 把data的name属性定义了一个别名
return {
data,
aliasName,
}
}
};
</script>
-
setup 的 toRefs 函数
批量创建 ref 对象,其 value 值指向另一个对象 // 相当于批量起别名
<template>
<h1>
{{name}}
{{age}}
</h1>
</template>
<script>
import { reactive, toRefs} from "vue";
export default {
setup() {
let data = reactive({
name: "张三",
age: 18
});
return {
...toRefs(data)
}
}
};
</script>
Vue3中的生命周期函数
<script>
import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted} from "vue";
export default {
setup() {
console.log("===setup===");
onBeforeMount(()=>{
console.log("===挂载前===");
})
onMounted(()=>{
console.log("===挂载后===");
})
onBeforeUpdate(()=>{
console.log("===更新前===");
})
onUpdated(()=>{
console.log("===更新后===");
})
onBeforeUnmount(()=>{
console.log("===卸载前===");
})
onUnmounted(()=>{
console.log("===卸载后===");
})
}
};
</script>
多层嵌套组件之间的通讯
- provide:祖组件使用此函数传递数据
- inject:后代组件使用此函数接收数据
// 上级组件代码
<script>
import { ref, reactive, provide } from 'vue';
export default {
components: {
HelloWorld
},
setup() {
let name = ref("张三");
provide("name", name) // 父组件使用 provide 向下级(多级都可以)组件传值
let obj = reactive({
name: "李四",
age: 18
});
provide("obj", obj);
}
}
</script>
// 下级(多层下级都可以)组件代码
<script>
import { inject } from "vue";
export default {
setup() {
let name = inject("name");
console.log("下级组件接收到值=",name.value);
let obj = inject("obj");
console.log("下级组件接收到值=",obj);
}
};
</script>
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/72515.html