$refs获取原生元素和组件对象
$refs获取DOM
利用ref和$refs获取DOM元素
<template>
<div>
<p>获取原生Dom元素</p>
<h1 id="myH" ref="myH">我是一名学员</h1>
</div>
</template>
<script>
export default {
mounted() {
// console.log(document.getElementById('myH'))
/*
1:给标签定义ref属性
2:通过this.$refs.属性名 获取元素
*/
console.log(this.$refs.myH)
},
}
</script>
$refs获取组件对象
-
创建组件MyProduct.vue
<template> <div>MyProduct组件</div> </template> <script> export default { data() { return { msg: 'hello', } }, methods: { fn() { console.log('组件被调用了') }, }, } </script>
-
获取组件对象,调用组件方法
<template> <div> <h2>获取组件对象--可以调用组件内的一切</h2> <my-product ref="myP"></my-product> </div> </template> <script> /* 1:创建组件/引入组件/注册组件/使用组件 2: 给组件起别名 ref 3: 恰当时机,获取组件对象 */ import MyProduct from './components/MyProduct' export default { components: { MyProduct, }, mounted() { let myPobj = this.$refs.myP console.log(myPobj.msg) myPobj.fn() }, } </script>
$nextTick
vue更新DOM–异步的
需求:点击count++,通过原生DOM拿标签内容,无法拿到新值
<template>
<div>
<h2>$nextTick</h2>
<p ref="myP">
{{ count }}
</p>
<button @click="addCount">count++</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 0,
}
},
methods: {
addCount() {
this.count++ //vue监听数据更新,开启一个DOM更新队列(异步任务)
// console.log(this.$refs.myP.innerHTML) //0
/*
vue更新DOM 异步任务
解决:this.$nextTick
过程: DOM更新完会挨个触发$nextTick里的函数体
*/
this.$nextTick(() => {
console.log(this.$refs.myP.innerHTML)
})
},
},
}
</script>
场景
点击搜索按钮,弹出文本框并获取焦点,按钮消失
<template>
<div>
<button @click="btnFn" v-if="isShow">搜索</button>
<input v-else type="text" placeholder="这是一个文本框" ref="myInp" />
</div>
</template>
<script>
export default {
data() {
return {
isShow: true,
}
},
methods: {
async btnFn() {
this.isShow = false
// this.$refs.myInp.focus()
// 原因:DOM更新是异步的 文本框还没有挂载到真实DOM上
// this.$nextTick(() => {
// this.$refs.myInp.focus()
// })
// 等同于
// await取代回调函数
await this.$nextTick()
this.$refs.myInp.focus()
},
},
}
</script>
组件name使用
可以用组件的name属性值,来注册组件名字
我们封装的组件,可以自己定义name属性组件名 让使用者有个统一的前缀风格
components/MyCom.vue
<template>
<div>我是一个Com组件</div>
</template>
<script>
export default {
name: 'ComNameHaHa', //注册时可以定义自己的名字
}
</script>
<style scoped></style>
App.vue中注册和使用
<template>
<div>
<ComNameHaHa></ComNameHaHa>
<MyProducts></MyProducts>
</div>
</template>
<script>
import Com from './components/MyCom.vue'
import Pro from './components/MyProduct.vue'
export default {
components: {
[Pro.name]: Pro,
[Com.name]: Com, //对象里的key是变量的话 [] 属性名表达式
// 相当于
// ComNameHaHa: Com,
},
}
</script>
动态组件
多个组件使用一个挂载点,并动态切换,就是动态组件
vue内置component组件,配合is属性,设置要显示的组件
需求:完成一个注册功能页面,2个按钮切换,一个填写注册信息,一个填写用户简介信息
-
定义两个组件 UserName.vue , UserInfo.vue 2个组件
-
引入到App.vue组件中
-
data中定义变量来存放要显示的组件名
-
要设置挂载点 使用is属性来设置要显示那个组件
-
点击按钮 修改变量里的组件名
同一个挂载点要切换不同组件 显示
1:创建要切换的组件 标签+样式
2:引入到要展示的vue文件内,注册
3:变量 承载要显示的组件名
4:设置挂载点
5:点击按钮 切换comName值为要显示的组件名
<template>
<div>
<button @click="comName = 'UserName'">账号密码</button>
<button @click="comName = 'UserInfo'">个人信息</button>
<p>下面显示动态切换组件</p>
<div style="border: 1px solid red">
<component :is="comName"></component>
</div>
</div>
</template>
<script>
/*
同一个挂载点要切换不同组件 显示
1:创建要切换的组件 标签+样式
2:引入到要展示的vue文件内,注册
3:变量 承载要显示的组件名
4:设置挂载点 <component :is="变量"></component>
5:点击按钮 切换comName值为要显示的组件名
*/
import UserName from './components/UserName.vue'
import UserInfo from './components/UserInfo.vue'
export default {
data() {
return {
comName: 'UserName',
}
},
components: {
UserName,
UserInfo,
},
}
</script>
组件缓存
组件切换会导致组件被频繁的销毁和重新创建,性能不高
使用vue内置的keep-alive组件,可以让包裹的组件保存在内存中不被销毁
演示:给UserName.vue 和 UserInfo.vue 注册created 和destroyed生命周期事件,观察创建和销毁的过程
使用keep-alive内置的vue组件,让动态组件缓存
语法:
Vue内置的keep-alive组件,包裹要频繁切换的组件
App.vue
<div style="border: 1px solid red">
<!-- vue内置的keep-alive组件,把包起来的组件缓存起来 -->
<keep-alive>
<component :is="comName"></component>
</keep-alive>
</div>