那啥 开始就声明解释一下mixin,它不叫米新,它叫迈克散嗯,mix + in 额 就说通不通易不易懂,在本文我将以最为通俗的、让能看懂的话术解释V3Api,当然了一些概念还的是全面点!
mixin—局部
红框和绿框组件,都有相同的方法,和钩子,那么你将他们相同的剪贴走,建一个文件粘贴
进去(mixin.js 也可以是aa.js),最后导入页面,就是混合原理
配合代码更加贴切,易懂
/*
*
* 子组件uname
*
/
<template>
<div>
<h2 @click="choseName">姓名:{{ uname }}</h2>
<hr />
<button @click="fn">测试组件和mixin方法重复,执行谁</button>
</div>
</template>
<script>
import { MyMiXin } from "./mixin";
export default {
data() {
return {
uname: "活在风浪里。。",
};
},
// mixins复数,因为要调用data中数据,必须写在data下面
mixins: [MyMiXin],
methods: {
fn() {
console.log("组件方法");
},
},
created() {
console.log("组件钩子");
},
};
</script>
/*
*
* 子组件school
*
/
<template>
<div>
<h2 @click="choseName">学校:{{ uname }}</h2>
<hr />
<button @click="fn">测试组件和mixin方法重复,执行谁</button>
</div>
</template>
<script>
import { MyMiXin } from "./mixin";
export default {
data() {
return {
uname: "北大",
};
},
// mixins复数,因为要调用data中数据,必须写在data下面
mixins: [MyMiXin],
methods: {
fn() {
console.log("组件方法");
},
},
created() {
console.log("组件钩子");
},
};
</script>
/*
*
* 父组件 引入子组件
*
/
<template>
<div id="about">
<school></school>
<hr />
<uname></uname>
</div>
</template>
<script>
import school from "../components/school.vue";
import uname from "../components/uname.vue";
export default {
data() {
},
components: { school, uname },
};
</script>
/*
*
* 新建mixin JS文件
*
/
export const MyMiXin = {
// data、methods、如果和组件重复,只会执行组件的内容,mixi不会执行
methods: {
choseName() {
alert(this.uname)
},
fn() {
console.log('mixin方法');
}
},
// 钩子函数事特殊的,它会合并组件的钩子,先执行mixin钩子,在执行组件钩子
created() {
console.log("mixin钩子");
},
}
如果组件与mixin冲突怎么办?总结:
- 组件 data、method 优先级高于 Mixin 混入的 data、method
- 组件自定义属性优先级高于 Mixin 混入的 自定义属性
- 先执行 Mixin 的钩子,再执行组件里的钩子,会合并
- 建议配合上面代码和图片,还是看不懂请揍我
mixin造成的问题:
首先Vue是渐进式框架,不需要必须使用它的api,可替代性很强,你可以只用我的一部分,而不是所有部分
- 变量来源不明,不利于代码的阅读;
- 使用多个Mixin可能会造成命名冲突;
- Mixin和组件的关系,复杂度较高
mixin—全局
更新中。。。
什么是全局选项? 就是 全局组件,全局过滤器,全局指令,全局mixin
1、Vue.component 注册的 【全局组件】
2、Vue.filter 注册的 【全局过滤器】
3、Vue.directive 注册的 【全局指令】
4、Vue.mixin 注册的 【全局mixin】
Vue2与Vue3的区别 Options API的弊端
相对于Vue2来说,Vue3最大的突破就是 Composition API 。与现有的Vue2 Option API 截然不同
- 数据劫持、双向绑定之类,不在这里说,太多,太占篇幅,
- 比如**
data定义数据、methods中定义方法、computed中定义计算属性、watch中监听属性改变,也包括生命周期钩子;假如一个大项目,逻辑很多,那么同一个功能的逻辑就会被拆分的很分散,这个组件的代码是难以阅读和理解的(阅读组件的其他人),碎片化的代码使用理解和维护变得很困难,如果我们能将同一个逻辑关注点相关的代码收集在一起**会更好,这个位置就是Vue3setup 函数
setup函数有哪些参数?
// setup函数有哪些参数?
// setup函数有什么样的返回值
// setup(props, context)
setup(props, {attrs, slots, emit}) {//解构context
console.log(props.message);
console.log(attrs.id, attrs.class);
console.log(slots);
console.log(emit);
return {
}
},
- 我们先来研究一个setup函数的参数,它主要有两个参数:
- 第一个参数:
props - 第二个参数:
context
- 第一个参数:
props非常好理解,它其实就是父组件传递过来的属性会被放到props对象中,我们在setup中如果需要使用,那么就可以直接通过props参数获取:
另外一个参数是context
attrs:所有的非prop的attribute;slots:父组件传递过来的插槽emit:当我们组件内部需要发出事件时会用到emit
任何人写的文都不会比官方文档还要全,建议撸一遍V3官方文档
setup函数的返回值
- 必须使用return返回
setup不可以使用this
- 官方关于this有这样一段描述
- 表达的含义是
this并没有指向当前组件实例; - 并且在setup被调用之前,
data、computed、methods等都没有被解析; - 所以
**无法在setup中获取this**;
Vue3中 reactive 和 ref 和 toRefs 和 toRef
reactive 是vue3的一个组合api vue3中新增的最核心的功能就是组合api
reactive vue3建议只用来声明对象 他声明的对象中的每一个属性都是响应式的
他是结合es6的proxy 结合递归给每一个reactive声明的对象数据添加上 setter/getter方法 从而实现数据的响应式
ref是用reactive封装成的一个方法 这个方法我们通常用来声明基本数据类型和数组数据
ref声明的数据是一个对象 值是value ref在使用的时候不需要写value 但是赋值的时候必须写value
toRefs可以解构reactive对象的属性 将属性取出 转换成一个ref对象,假如你要reactive里面的obj.name,在return{}用了 ...toRefs(obj)就可以直接使用name
如果不经过toRefs,直接解构是不具备相应式的
setup() {
const info = reactive({name: "why", age: 18});
// 1.toRefs: 将reactive对象中的所有属性都转成ref,
// 如果不经过toRefs,直接解构是不具备相应式的
let { name, age } = toRefs(info);
return {//具备相应式
name,
age
}
}
总结ref:
- 在模板中引入ref的值时,Vue会自动帮助我们进行解包操作,所以我们并不需要在模板中通过 ref.value 的方式来使用;
- 但是在 setup 函数内部,它依然是一个 ref引用, 所以对其进行操作时,我们依然需要使用 ref.value的方式;
什么是解包:
a解构出来相当于 a={value:xx}
readonly只读属性
使用场景:在父传子时就可以将接受的数据定为只读,子组件不允许直接修改父组件的数据,如果一个子组件有很多父组件(子组件定义结构样式,父组件传递不同的值,以显示不同的页面),子组件修改父组件可能会造成数据混乱,因为多个父组件可能定义了相同的变量,但是可以子传父,不能直接在子组件修改父组件数据
toRef
如果我们只希望转换一个reactive对象中的属性为ref, 那么可以使用toRef的方法:
computed
持续手敲。。