VUE3的使用
VUE2绑定的原理
vue2的绑定原理使用的是属性访问器和虚拟DOM树的方式,属性访问器将被访问的属性进行保护,然后对被访问的属性的操作都是通过访问器的方式进行操作
但是存在问题是只有在首次new Vue的时候添加的属性才能被属性访问器监视到,在后来添加的属性是无法置于属性访问器的监视之下的。然后无法为索引数组的数字下标添加访问器属性
vue3的绑定原理
ES6的proxy代理对象
形象点解释就是在对象外面建立一层围墙,对对象的操作都会被围墙进行过滤拦截
优点:对象内部所有现有属性自动被监视,而且更可贵的是,后添加的属性,一进入对象就被监视
缺点:有兼容性问题
示例:
//受保护的数组
var arr = ["亮亮", "然然", "东东"];
//在arr数组外围建立拦截的围墙
arr = new Proxy(arr, {
//当有人试图获取数组中任何一个元素值时自动触发
get(当前对象, 属性名) {
console.log(`有人试图读取arr对象的${属性名}成员`)
return 当前对象[属性名];
},
//当有人试图修改数组中任何一个元素值时自动触发
set(当前对象, 属性名, 新值) {
console.log(`有人试图修改arr对象的${属性名}成员`)
当前对象[属性名] = 新值;
return true; //必须: 返回修改成功!
}
});
//城墙外
vue项目的结构的改变
1、vue结构main.js
- 在vue2版本中main.js中还是使用new vue()的方式来启动vue的根组件;
- 在vue3版本中main.js中使用 createApp(App).use(store).use(router).mount(’#app’)方式加载根组件
2、vue结构*.vue文件 - 在vue3版本中的vue文件中 template 和 style 中的内容以及结构没有改变,适用vue2的操作方式
3、vue结构中*.vue文件中 script
- 首先需要使用vue需要导入vue组件,vue3将vue2的script中的method,计算属性等都封装到vue中,然后使用的时候使用解构的方式将其导入,需要什么导入什么
import { defineComponent, ref, toRefs, watch } from 'vue';
其中 defineComponent是必须的,因为这是开始,所有的js代码都放在这里:
export default defineComponent({name:'Home',components:{aaa,ddd}})
这里仍然可以使用子组件引入方式
4、defineComponent({})函数内,必须先调用setup()函数作为整个组件代码的运行起点。
export default defineComponent({
… …
//必须:
//代替了之前的create阶段
//作为整个组件的运行起点
setup(){
//组件所需的所有变量和函数都放在setup()函数内
}
})
- 所有的变量和函数都放在setup()函数作用中
5、ref函数
- vue采用的是将数据存储对象保护起来并不直接访问,在vue2和vue3都是如此;在vue2中只有在new Vue中的数据可以被监听保护,在vue3中采用的是ref函数方法
- 首先使用ref函数必须在导入的时候从vue中解构出来
import { defineComponent, ref, toRefs, watch } from 'vue';
- 对数据进行监听保护:ref(data)
let n=ref(0);//将原始类型值转为对象(n={ value:0 }),并对对象添加监视
6、对数据监视后,想要与页面中进行绑定,需要使用 return 将变量、函数等导出
- 因为有的成员需要抛出到界面,而有的成员不需要抛出到界面仅程序内部使用!这时候就需要使用到return:
return {
//将页面中需要使用到的变量与函数当做对象的属性导出
a,c,b
}
- 需要注意的是,return是在setup()函数中的
7、toRefs
该函数是用来对参数函数进行监视绑定的,当正式做项目的时候,存在众多的数据需要进行监视,但是不可能一个个进行绑定,所用有该函数
使用该函数方式:
- 第一步:使用解构的方法导入该方法
import { defineComponent, ref, toRefs, watch } from 'vue';
- 第二步:将项目中使用的变量和函数(需要与页面进行交互的)封装成一个data数据对象,使用该对象保存数据。
const data=ref({
n:0,
arr:["亮亮","然然","东东"]
})
- 第三步:在函数中或者说是在JavaScript部分中需要使用变量,就需要将数据变量分别进行绑定监视,这里使用到了toRefs函数 使用该函数会将数据分别进行绑定监视,结合结构方式,将数据变量从data数据对象中结构出来;
let {n,arr}=toRefs(data.value);
- 第四步:函数的处理方式,和数据一样,定义方法对象methods,将函数作为方法存储到对象中;使用的时候将方法对象放在return方法中,使用打散的方法结构出来
//3.所有方法都集中保存在methods对象中,不用ref包裹!
const methods={
add(){n.value++; },
minus(){ if(n.value>0){n.value--;}},
change(i:number){arr.value[i]="❀";},
search(){
if(str.value!=="")
console.log(`搜索${str.value}相关的内容`)
}
}
// 使用时
return {
toRefs(data.value), ...methods
}
8、监听方式
在vue2中监听是在JavaScript导出的对象中有专门的属性对象watch对象,使用需要监听的数据变量的变量名作为方法名,设置监听方法
在vue3中,监听就是自行编写监听方法
当然监听方法有专门的监听方法的格式
watch(str,(newVal,oldVal)=>{
console.log(`str的变量值从${oldVal}被改成${newVal}`);
methods.search();
})
需要注意的是在监听方法中,参数的设置;watch中第一个参数是指定需要监视的变量,回调函数中的参数先后顺序时新值,与旧值
在vue3中可以有多个监听函数;当然需要使用监听函数的时候,必须先充vue中结构除wath方法
import { defineComponent, … …, watch } from 'vue';
调用当前监听函数的方法使用上面监听方法制定监听方法
9、自定义指令
自定义指令和模块函数一样,也会分全局指令和局部指令
- 全局指令:
全局指令定义的位置是在main.js中:
var app=createApp(App);
//自定义指令
app.directive("my-focus",{
mounted(el){
el.focus();
}
})
app.use(store).use(router).mount('#app');
- 定义局部指令: 定义局部指令的地址是在该指令所在的vue文件中
export default defineComponent({
directives:{
"my-focus":{
mounted(el){
el.focus();
}
}
},
setup(){
… …
}
})
10、计算属性
还是要在开头的import中解构出computed函数
import { defineComponent, … …, computed } from 'vue';
一定在包含所有方法的自定义methods对象中添加计算属性
方法,才能在return时被解构出来,才能在界面上使用
const methods={
… …,
total:computed(()=>{
var r=0;
for(var p of cart.value){ r+=p.price*p.count }
return r;
}
)
}
注意:计算属性是也是方法,计算属性是定义在方法对象里面的
11、在vue3中已经不在支持过滤器了,转而可以使用计算属性代替
12、注册全局组件
注册全局组件的方法:
// main.ts中:
app.component('my-component-name', {
/* ... */
})