Vue2知识点详细回顾(以及自己的一些思考和解答)-2

0 阅读3分钟

2.关于组件

2.1 组件传值(通信)的方式

2.1.1 父传后代

  1. 父组件引入子组件,绑定数据:(孙组件无法直接使用,需要子组件再传递给孙组件)
<!-- 父组件引入子组件,绑定数据 -->
<Child :str1="str1"></Child>

<!-- 子组件通过props接收 -->
props:{
    str1:{
        type: String,  //字符串类型
        default: '',   //默认值
    }
}

这种方式 子组件不能直接修改父组件的数据,例如:this.str1 = '321' //错误

  1. 子组件直接使用父组件的数据
this.$parent.str1

这种方式 子组件可以直接修改父组件的数据,例如:this.$parent.str1 = '321' //正确

  1. 依赖注入(父组件可以直接向某个后代组件传值,无需逐级传递)
// 父组件
<script>
export default {
    provide() {
        return {
            val1: '这是父组件的依赖内容'
        }
    }
}
</script>

// 任意的后代组件使用(缺点就是有点难以找到这个值是再哪个父组件中定义的)
<script>
export default {
    inject: ['val1'],
}
</script>

2.1.2 后代传父

  1. 通过触发事件传递数据
// 父组件给子组件设置一个监听事件来触发自己的函数
<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>
  1. 父组件直接拿到子组件的数据(通过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个生命周期activateddeactivated,进入时只会额外执行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…