之前一直是用vue2来写项目的,现在实习工作也不是很忙,闲下来记录一些vue2和vue3对比有哪些升级的部分。
1. ref
在vue2中的用法
在vue2中,如果我们想要一个dom节点,需要以下两步:
- 使用ref给元素注册引用信息;
- 在方法中利用this.$refs.xxx便可获取该dom元素;
//示例代码
<template>
<div>
<ul>
<li v-for="(item,index) in list" :key="index" :ref="name">{{item.nam}}</li>
</ul>
</div>
</template>
<script>
export default {
data(){
return{
list:[{nam:'111'},{nam:'111'},{nam:'111'},{nam:'111'},{nam:'111'},],
}
},
mounted(){
console.log(this.$refs.name) //这里会输出dom元素
},
}
</script>
在vue3中的用法
在vue3中,如果我们想要获取dom元素,需要以下三步:
-
和vue2中的一样,使用ref给元素注册引用信息;
-
是在methods中创建和上面ref所绑定的名字相同的函数,这个函数的参数就是获取的dom元素;
-
将传递过来的参数推入到一个新的自定义数组中;
//示例代码
<template>
<div>
<ul>
<li v-for="(item,index) in list" :key="index" :ref="nameList">{{item.name}}</li>
</ul>
<button @click="getRef">获取</button>
</div>
</template>
<script>
export default {
data(){
return{
list:[{name:'111'},{name:'111'},{name:'111'},{name:'111'},{name:'111'},],
refnameList:[],
}
},
methods:{
nameList(el){ //创建的方法
if(el){
this.refNameList.push(el) //循环出的所有节点都推入自定义的refTodo
}
},
getRef(){
console.log(this.refNameList) //打印出proxy对象,但是用起来和数组没什么区别
}
},
}
</script>
优点
在 Vue 2 中,在 v-for
中使用的 ref
attribute 会用 ref 数组填充相应的 $refs
property。当存在嵌套的 v-for
时,这种行为会变得不明确且效率低下。
2. $chilren
在vue2中的用法
$children一般是用来找到我们这个页面的子组件的
<template>
<div>
<hello /> //使用子组件
</div>
</template>
<script>
import hello from '../../components/HelloWorld.vue' //引入子组件
export default {
components:{
hello //注册子组件
},
mounted:{
console.log(this.$children); //这里输出子组件的内容,而在vue3中会输出undefined
}
}
</script>
vue3的用法
上述特性被删除,这也就是为什么在vue3中使用this. c h i l d r e n 打 印 子 组 件 会 输 出 u n d e f i n e d , 官 方 文 档 建 议 我 们 使 用 children打印子组件会输出undefined,官方文档建议我们使用 children打印子组件会输出undefined,官方文档建议我们使用refs,那么使用方法就如下:
<template>
<div>
<hello ref='hello'/>
</div>
</template>
<script>
import hello from '../../components/HelloWorld.vue'
export default {
components:{
hello
},
mounted(){
console.log(this.$refs) //这里就可以输出子组件,是vue2的属性
}
}
</script>
3. 插槽
其实在我学习vue2的时候,使用插槽是直接学习的v-slot指令,但其实这在vue2.6以后才出现的写法。
在vue2.6以前是使用slot="xx" slot-scope="xx"
这种属性写法,在vue2.6以后这种属性写法和v-slot指令是可以共同使用的,但在vue3中把属性写法去掉了,也就是vue3中只有v-slot这种指令写法了。
在elementui文档中也有这种属性写法,详情见组件table https://element.eleme.cn/#/zh-CN/component/table
vue2.6以前的写法
<template>
<S :btnStyle="waring">
<template slot="name" slot-scope="scope"> //插槽属性写法内容
<div>
{{scope.data}}
</div>
</template>
</S>
</template>
<script>
import S from '../../components/S.vue'
export default {
components:{
S
}
}
</script>
vue3的写法
<template>
<S :btnStyle="waring">
<template v-slot:name> //在向具名插槽提供内容的时候,可以在一个 <template> 元素上使用 v-slot 指令,
<text>插槽内容</text>
</template>
</S>
</template>
<script>
import S from '../../components/S.vue'
export default {
components:{
S
}
}
</script>
参考:https://v3.cn.vuejs.org/guide/migration/array-refs.html#%E8%BF%81%E7%A7%BB%E7%AD%96%E7%95%A5