Vue3.0拿来吧你!!!
2021-07-25 本文已影响0人
又菜又爱分享的小肖
为什么学习Vue3.0?
关于框架
- 最火的框架,它是国内最火的前端框架之一。
- 性能提升,运行速度是Vue2.x的1.5倍左右。
- 体积更小,按需编译体积比Vue2.x要更小。
- 类型推断,更好的支持TS这个是趋势。
- 高级给予,暴露了更底层的API和提供更先进的内置组件。
- 组合API(composition api),能够更好的组织逻辑,封装逻辑,复用逻辑。
关于自己
- Vue3.0已经是趋势了,我相信会有越来越多的企业在将来会升级Vue3.0。
- 做开发都知道,不学习就会被这个社会所淘汰,提升自己的竞争力。
vite是什么?
- 它是一个更加轻量(热更新速度快,打包构建速度快)的vue项目脚手架工具。
- 相对于vue-cil它默认安装的插件非常少,随着开发过程中依赖增多,需要自己额外配置。
npm init vite-app 项目名
cd 项目名
npm i
npm run dev
选项API和组合API
什么是选项API?
- 我们在Vue2.x项目中使用的就是选项API的写法。data写数据,methods写方法,一个功能逻辑的代码分散。
- 优点:易于学习和使用,写代码的位置已经约定好。
- 缺点: 代码组织性差,相似的逻辑代码不便于复用,逻辑复杂代码多了不好阅读。
- 虽然提供mixins用来封装逻辑,但是出现数据函数覆盖的概率很大,不好维护。
选项api写法
<template>
<div>
<div>{{y}}</div>
<div>{{x}}</div>
<button @click="add">{{count}}</button>
</div>
</template>
<script>
export default {
data() {
return {
x:0,
y:0,
count:0
}
},
mounted(){
document.addEventListener('mousemove',this.move);
},
methosd:{
add(){
this.count++;
},
move(e){
this.x = e.pageX;
this.y = e.pageY;
}
}
}
</script>
组合api写法
<template>
<div>
<div>{{obj.x}}</div>
<div>{{obj.y}}</div>
<button @click="add">{{obj.count}}</button>
</div>
</template>
<script>
import { onMounted, reactive} from 'vue'
export default {
setup(){
const obj = reactive({
x:0,
y:0,
count:0
});
console.log(obj);
const move = (e) =>{
obj.x = e.pageX;
obj.y = e.pageY;
}
const add = () => {
obj.count++
}
onMounted(()=>{
document.addEventListener('mousemove',move)
})
return {obj, add};
}
}
</script>
组合API-setUP函数
- setup是一个新的组件选项,作为组件中使用组合API的起点。
- 从组件生命周期来看,它的执行在组件实例创建之前Vue2.x的beforeCreate执行。
- 这就意味着在setup函数中this还不是组件实例,this是undefined。
- 在模板中需要使用的数据和函数,需要在setup返回。
<template>
<div>
{{msg}}
</div>
</template>
<script>
export default {
setup(){
const msg = '哈哈哈';
console.log(this); //undefined
return {msg}
},
beforeCreate() {
console.log(this); //Proxy {…}
},
}
</script>
组合API-生命周期
- setup 创建实例前。
- onBeforeMount 挂载DOM前。
- onMounted 挂载DOM后。
- onBeforeUpdate 更新组件前。
- onUpdate 更新组件后。
- onBeforeUnmount 卸载销毁前。
- onUnmounted 卸载销毁后。
组合API-reactive函数定义响应式数据。
- reactive是一个函数,它可以定义一个复杂数据类型,成为响应式数据。
<template>
<div>
<div>{{obj.name}}</div>
<div>{{obj.age}}</div>
<button @click="btn"></button>
</div>
</template>
<script>
import { reactive } from 'vue'
export default {
setup(){
const obj = reactive({
name:'xxj',
age:21
})
const btn = () =>{
obj.name = 'xxx';
obj.age = 100
}
return {obj, btn};
}
}
</script>
组合API-toRef函数
- toRef是函数,转换响应式对象中某个属性为单独响应式数据,并且值是关联的。
<template>
<div>
<div>{{age}}</div>
<button @click="btn">按钮</button>
</div>
</template>
<script>
import {reactive, toRef } from 'vue'
export default {
setup(){
const obj = reactive({
name:'xxj',
age:21
});
let age = toRef(obj,'age');
const btn = () =>{
age.value = 100
}
return {age, btn};
}
}
</script>
组合API-toRefs函数
- toRefs是函数,转换响应式对象中所有属性为单独响应式数据,对象成为普通对象。
<template>
<div>
<div>{{name}}</div>
<div>{{age}}</div>
<button @click="btn"></button>
</div>
</template>
<script>
import {reactive, toRefs } from 'vue'
export default {
setup(){
const obj = reactive({
name:'xxj',
age:21
});
const btn = () =>{
obj.name = 'xxx',
obj.age = 100
}
return {...toRefs(obj),btn}
}
}
</script>
组合API-ref函数
- ref函数,常用于简单数据类型定义为响应式数据。
- 再修改值,获取值的时候,需要value。
- 在模板中使用ref声明的响应式数据,可以省略
.value
<template>
<div>
<div>{{num}}</div>
<button @click="btn"></button>
</div>
</template>
<script>
import {ref} from 'vue'
export default {
setup(){
let num = ref(0);
const btn = () =>{
num.value++;
}
return {num, btn}
}
}
</script>
组合API-computed函数
- computed函数,是用来定义计算属性的,计算属性不能修改。
基本用法
<template>
<div>
<div>{{obj.age}}</div>
<button>{{newage}}</button>
</div>
</template>
<script>
import {computed, ref} from 'vue'
export default {
setup(){
const obj = {
name:'xxj',
age:21
}
const newage = computed(()=>{
return obj.age + 2;
})
return {obj, newage};
}
}
</script>
高级用法
<template>
<div>
<div>{{age}}</div>
<input type="text" v-model="newage">
</div>
</template>
<script>
import {computed, ref} from 'vue'
export default {
setup(){
const age = ref(21);
const newage = computed({
//get函数,获取计算属性的值
get(){
return age.value + 2;
},
// set函数,当你给计算属性设置值的时候触发
set(value){
console.log(value);
age.value = value - 2;
}
})
return {age, newage};
}
}
</script>
- 给computed传入函数,返回值计算计算属性的值。。
- 给computed传入对象,get获取计算属性的值,set监听计算属性改变。
组合API-watch侦听器
<template>
<div>
<div>{{count}}</div>
<button @click="add"></button>
</div>
</template>
<script>
import {ref, watch} from 'vue'
export default {
setup(){
const count = ref(0);
const add = () =>{
count.value++;
}
watch(count,(n,o)=>{ // 监听某个变量
console.log(n,o); //返回新值 旧值
},{
//深度监听
deep:true,
//默认执行
immediate:true
})
// 监听多个数据变化
watch([count,obj], ()=>{
console.log('改变了')
})
// 监听对象中某一个属性的变化,例如:obj.name
// 需要写成函数返回该属性的方式才能监听到
watch(()=>obj.name, ()=>{
console.log('改变了');
})
return {count, add}
}
}
</script>
组合API-ref属性
- 获取DOM或者组件实例
- 获取v-for遍历的DOM或者组件
<template>
<div>
<div ref="dom">我是box</div>
<ul>
<li v-for="(item,index) in 5" :key="index" :ref="setDom">{{item}}</li>
</ul>
</div>
</template>
<script>
import {onMounted, ref, watch} from 'vue'
export default {
setup(){
const dom = ref(null);
// 获取单个元素
//定义一个空的响应式数据ref定义的
//setup中返回该数据,你想获取那个dom元素,在该元素上使用ref属性绑定该数据即可。
onMounted(()=>{
console.log(dom.value); // DOM渲染完毕执行 获取
console.log(DOMList);
})
// 获取v-for遍历的元素
// 定义一个空数组,接收所有的li
// 定义一个函数,往空数组push DOM
const DOMList= [];
const setDom = (el) =>{
console.log(el);
DOMList.push(el);
}
return {dom, setDom}
}
}
</script>
组合API-父子通讯
父组件
<template>
<div>
<h1>父组件</h1>
<Son v-model:message="message"></Son>
</div>
</template>
<script>
import Son from "./Son.vue";
import { ref } from "vue";
export default {
components: {
Son,
},
setup() {
let message = ref("啊哈");
const update = (val) => {
console.log(val);
message.value = val;
};
return { message, update };
},
};
</script>
<style>
</style>
子组件
<template>
<div>
<h1>子组件</h1>
{{ message }}
<button @click="btn">子传父</button>
</div>
</template>
<script>
import { onMounted } from "vue";
export default {
props: {
message: {
type: String,
default: 0,
},
},
setup(props, { emit }) {
// 获取父组件数据money
// console.log(props.message);
onMounted(() => {
console.log(props.message);
});
const btn = () => {
//传给父组件
emit("update:message", "哈哈哈");
};
return { btn };
},
};
</script>
- 父传子:在setup中使用props数据
setup(props){ //props就是父组件数据 }
- 子传父:触发自定义事件的时候emit来自
setup(props,{emit}){ //emit 就是触发事件函数 }
- 在Vue2.x中
v-model
和.sync
已经合并v-model指令
依赖注入
使用场景:有一个父组件,里面有一个子组件,有孙组件,有很多后代组件,共享父组件数据。
父组件
<template>
<div>
<h1>父组件</h1>
<Son></Son>
</div>
</template>
<script>
import Son from "./Son.vue";
import { provide, ref } from "vue";
export default {
components: {
Son,
},
setup() {
let money = ref(100);
const changeMoney = (val) => {
//后代组件返回的值对父组件进行修改
money.value = val;
};
// 将数据提供给后代组件
provide("money", money);
//将函数提供给后代组件 provide
provide("changeMoney", changeMoney);
},
};
</script>
子组件
<template>
<div>
<h1>子组件</h1>
{{ money }}
<GrandSon></GrandSon>
</div>
</template>
<script>
import { inject } from "vue";
import GrandSon from "./GrandSon.vue";
export default {
components: {
GrandSon,
},
setup() {
// 接收祖先组件提供的组件
const money = inject("money");
return { money };
},
};
</script>
孙组件
<template>
<div>孙组件</div>
<button @click="fn">修改金额</button>
{{ money }}
</template>
<script>
import { inject } from "vue";
export default {
setup() {
// 接收祖先组件提供的组件
const money = inject("money");
// 不能自己修改数据,谁定义谁修改
const changeMoney = inject("changeMoney"); //获取父组件传来的方法
const fn = () => {
changeMoney(20); // 调用
};
return { money, fn };
},
};
</script>