动态写选项卡
vue内置组件,这个组件可以让视图动态地渲染对应的组件内容
vue内置组件不用自己定义,可以直接拿来使用。
vue内置组件component,这个组件可以让视图动态地渲染对应的组件内容
注意:
内置组件component和注册标签components只是长得像其实没有关系。
如果在component中直接使用了引入的标签,可以不用在components中注册;
如果在component中没有使用了引入的标签,则需要在components中注册。
vue内置组件keep-alive,这个组件可以缓存组件的状态
<keep-alive>
<component :is="comp"></component>
</keep-alive>
通过keepalive包裹的组件没有被销毁,也没有重新挂载,生命周期被保存了
写一个动态绑定的选项卡
<template>
<div class="tabControl">
<span @click="fn1()"> Home </span>
<span @click="fn2()"> Post </span>
<span @click="fn3()"> Archive </span>
</div>
<keep-alive>
<component :is="comp"></component>
</keep-alive>
</template>
<script>
// 导入
import Home from './components/Home.vue'
import Archive from './components/Archive.vue'
import Post from './components/Post.vue'
export default {
name: 'App',
data(){
return {
comp:Home /* 初始值为home,切换选项卡就是修改home */
},
methods:{
fn1(){
this.comp = Home
},
fn2(){
this.comp = Post
},
fn3(){
this.comp = Archive
},
},
}
</script>
新增生命周期
4组8个生命周期(create,mounte,update,destroy)
在生命周期中经常使用的是:mounted(发送http请求,进行Dom操作,连接服务器等),beforeDestroyed(清除副作用,取消连接服务器,清除全局定时器,清除一些订阅消息。)
除此之外,keepalive缓存组件中还新增两个生命周期——激活activated和失活deactivated
选项卡切换:初始挂载+激活,切换时失活——挂载——激活,再次切换失活——激活,不再重新挂载
组件通信
父子组件通信
父到子——props 既是基本属性,也可以是方法
子到父——1.自定义事件;2.接受props方法
祖先到后代——provide/inject 依赖/注入
- 在祖先中provide注入信息(provide与components同级
- 在后代组件中inject:["msg"]注入组件内容,即可在后代组件中调用
Vue获取Dom元素
vue是数据驱动视图的框架,一般情况下,操作的数据,Dom操作由框架来实现,不能用document.querySelector
在Vue中如果希望能获取Dom元素,可以使用ref属性来获取Dom元素,还可以获取组件实例
切换视图后立刻更新
在vue中,数据一变,视图会立即更新吗?不是的。
所有操作结束后,视图统一批量更新,是更合理的操作
视图还未更新时,是无法获取更新后新的值,获取该值得到undefined
调用$nextTick方法通知视图立马更新,这个方法中传入的回调函数的逻辑会在视图更新后执行
this.$nextTick(function(){})
this.$nextTick(function(){
if(this.isEdit){
this.$refs.ref1.focus();
}
});
<template>
<div class="app">
<div class="left">
<div
v-if="!isEdit"
class="t1"
>
{{ msg }}
</div>
<div
v-else
class="t2"
>
<input
ref="ref1"
v-model="msg"
type="text"
>
</div>
</div>
<div class="right">
<button @click="edit">
{{ isEdit ? "确定" : "编辑" }}
</button>
</div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
msg: 'hello',
isEdit: false,
}
},
methods: {
edit() {
this.isEdit = !this.isEdit
if(this.isEdit){
this.$refs.ref1.focus()
}
},
},
};
</script>
<style scoped>
.app {
background-color: #ddd;
padding: 8px;
display: flex;
}
.left {
width: 30%;
margin-right: 20px;
}
.t1 {
border: 1px solid #000;
}
.t2 input {
width: 100%;
}
</style>
name后面为项目名,最好写
el后面的为vue管理的区域,必须写
选择器,可以叫app,也可以叫别的。
插槽
如果希望child传递的一些数据(是js数据的话),通过props传递
我现在希望给child组件传递一些html结构(比如传递过去一个input框——vue插槽)
可以通过一个内置组件来接受父组件传递过来的DOM结构——slot
插槽可以分发一些视图
首先组件需要写成双标签,双标签中的内容为父组件传给子组件的内容
使用slot在子组件中接收并渲染从父组件接收过来的内容
简单父子组件插槽
<!-- 父控件内容 -->
<div id="app">
<p ref="peiqi">这是一个段落</p>
<Child>
<input />
</Child>
</div>
<!-- 子控件内容 -->
<div>
<slot></slot>
</div>
双插槽(具名插槽)
<Child>
<!-- 需要将h1放在name=h1的插槽中,将p放在name=p的插槽中 -->
<template v-slot:h1>
<h1>这是一个父组件的标题</h1>
</template>
<template v-slot:p>
<p>这是一个父组件的段落</p>
</template>
</Child>
<!-- 子控件内容 -->
<slot name="h1"></slot>
this is a child
<slot name="p"></slot>
为默认插槽,只分发一个的时候,可以不写name="default"与