2.关于组件
2.1 组件传值(通信)的方式
2.1.1 父传后代
- 父组件引入子组件,绑定数据:(孙组件无法直接使用,需要子组件再传递给孙组件)
<!-- 父组件引入子组件,绑定数据 -->
<Child :str1="str1"></Child>
<!-- 子组件通过props接收 -->
props:{
str1:{
type: String, //字符串类型
default: '', //默认值
}
}
这种方式 子组件不能直接修改父组件的数据,例如:this.str1 = '321' //错误
- 子组件直接使用父组件的数据
this.$parent.str1
这种方式 子组件可以直接修改父组件的数据,例如:this.$parent.str1 = '321' //正确
- 依赖注入(父组件可以直接向某个后代组件传值,无需逐级传递)
// 父组件
<script>
export default {
provide() {
return {
val1: '这是父组件的依赖内容'
}
}
}
</script>
// 任意的后代组件使用(缺点就是有点难以找到这个值是再哪个父组件中定义的)
<script>
export default {
inject: ['val1'],
}
</script>
2.1.2 后代传父
- 通过触发事件传递数据
// 父组件给子组件设置一个监听事件来触发自己的函数
<h1>{{ str2 }}</h1>
<Child @change='getChildVal'></Child>
<script>
export default {
// 省略...
data(){
return {
str2: '',
}
},
methods: {
getChildVal(val){
this.str2 = val
}
}
}
</script>
// 子组件通过点击按钮触发父组件的函数
<button @click="sendChildVal">按钮</button>
<script>
export default {
data(){
return {
childVal: '这里是子组件的数据',
}
},
methods: {
sendChildVal(){
this.$emit('change',this.childVal) //触发'change'事件,参数是this.childVal
}
}
}
</script>
- 父组件直接拿到子组件的数据(通过DOM)
<Child ref='child'></Child>
// 使用时:this.$refs.child.xxx
2.1.3 兄弟组件之间传值
同样是可以通过自定义事件(的监听和触发)来进行传值
2.2 父组件如何直接修改子组件的值
父组件中可以先为子组件设置ref,拿到它的DOM来操作:
<Child ref='child'></Child>
使用 this.$refs.child.xxx 去修改
2.3 子组件如何直接修改父组件的值
子组件中可以使用 this.$parent.xxx 去修改
2.4 如何找到父组件
this.$parent
2.5 如何找到根组件(一般为App.vue中的id为'app'的div)
this.$root
2.6 keep-alive
keep-alive是用来缓存当前组件的!它的核心价值在于提升用户体验和性能。常用于Tab页的切换,下面写一个例子:
// App.vue
<template>
<div id="app">
<nav>
<!-- 点击跳转到不同用户的主页 -->
<router-link to="/user_home?user_id=1">用户1</router-link>
<router-link to="/user_home?user_id=2">用户2</router-link>
</nav>
<keep-alive>
<!-- 被缓存的部分 -->
<router-view/>
</keep-alive>
</div>
</template>
那么当我们第一次点击“用户1”的时候,跳转到“/user_home?user_id=1”路径时会正常执行生命周期来发送请求、渲染页面等。(会额外增加2个生命周期activated
和deactivated
,进入时只会额外执行activated
);
当我们处于“用户1”中的时候,点击“用户2”跳转到“/user_home?user_id=2”时,原本的组件会执行deactivated
,仅仅只是“失活”而不是被“销毁”。
因此,后续我们再点击“用户1”的时候就会发现“/user_home?user_id=1”路径的内容已经被缓存了,不会再执行前四个生命周期 而只会执行activated
再次被激活。
2.7 slot/插槽
2.7.1 匿名插槽:插槽没有名字
当我们的组件只有一个地方需要做区分时,直接使用匿名插槽会比较方便,比如:
// 带插槽的组件 List.vue
<div class="list-box">
<div>内容内容</div>
<slot></slot>
</div>
// 在A页面中引用组件,并插入一行提示在 List的内容下方插槽中
<div>
<List>
<p>提示提示</p>
</List>
</div>
2.7.2 具名插槽:插槽有名字
还是用List组件打比方,假设我这次既要在内容上方加标题又要在内容下方加提示,这时候就需要给每个插槽起名字:
// 带插槽(在不同位置)的组件 List.vue
<div class="list-box">
<slot name="title"></slot>
<div>内容内容</div>
<slot name="tips"></slot>
</div>
// 在A页面中引用组件,并分别插入 标题 和 提示
<div>
<List>
<template #title>
<h1>标题</h1>
</template>
<template #tips>
<p>提示提示</p>
</template>
</List>
</div>
2.7.3 作用域插槽:传值
假设在组件List.vue中的data还定义了一些数据 value1,value2 需要在A页面中接收数据来对插槽的具体内容进行编辑,就需要用到作用域插槽:
// 带插槽的组件 List.vue,并且我会往“提示”的插槽传两个参数
<div class="list-box">
<slot name="title"></slot>
<div>内容内容</div>
<slot name="tips" :value1="value1" :value2="value2"></slot>
</div>
// 在A页面中引用组件,并分别插入 标题 和 提示,在 提示 插槽中拿到参数
<div>
<List>
<template #title>
<h1>标题</h1>
</template>
<!-- 传过来的参数是一个对象,用{value1,value2}进行解构 -->
<template #tips="{value1,value2}">
<p>提示提示</p>
<p>{{ value1 }}</p>
<p>{{ value2 }}</p>
</template>
</List>
</div>
2.8 provide/inject
provide/inject ===> 依赖注入
我是跟着这位老师复习的,我这里会根据我自己的相关情况补充知识点和总结知识点。 www.bilibili.com/video/BV1ef…