Vue基础篇之数据的传递以及对生命周期的监听


数据的传递

每一部分的内容都需要父组件进行传递

  • 1)如标题内容 直接使用传递字符串既可

父组件

<template>
  <div>
    <DialogDemo  title="地址"/>
  </div>
</template>

子组件

<template>
  <div>
    <button>阿迪达斯</button>
    <div class="mask">
      <div class="dialog">
        <!-- 每一部分的内容都需要父组件传递 -->
        <!-- 1.标题内容 直接传递字符串既可 -->
        <div class="dialog-header">{{title}}</div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props:['title']
}
</script>

================================================================================================

  • 2)对话框的内容部分,不确定性太确,它可以展示任何标签, 此时就需要父组件传递插槽给子组件,也就是传递 html 结构个子组件

父组件:
1.父组件内写在子组件的标签中间
2.给子组件进行传递 插槽 内容
3.但需要把标签写成闭合标签

<template>
  <div>
    <!-- 父组件内写在子组件的标签中间 -->
    <!-- 给子组件进行传递 插槽 内容 -->
    <!-- 但需要把标签写成闭合标签 -->
    <DialogDemo  title="地址">
      <form action="">
        <input type="text">
        <input type="text">
      </form>
    </DialogDemo>
  </div>
</template>

子组件:需要在子组件内写 <slot />进行接收

<template>
  <div>
    <button>阿迪达斯</button>
    <div class="mask">
      <div class="dialog">
        <!-- 每一部分的内容都需要父组件传递 -->
        <!-- 1.标题内容 直接传递字符串既可 -->
        <div class="dialog-header">{{title}}</div>
         <!-- 2.对话框的内容部分,不确定性太确,它可以展示任何标签,
        此时就需要父组件传递插槽给子组件,也就是传递 html 结构个子组件 -->
        <div class="dialog-content">
          <slot />
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props:['title']
}
</script>

================================================================================================

  • 3)当需要分类传递内容的时候
    • 我们可以使用 具名插槽来区别(也就是给插槽起名字)

父组件:
1.在父组件中利用 template 以及 v-slot 给插槽命名
2.没有起名字的插槽部分 都称为默认插槽 default

<template>
  <div>
    <!-- 父组件内写在子组件的标签中间 -->
    <!-- 给子组件进行传递 插槽 内容 -->
    <!-- 但需要把标签写成闭合标签 -->
    <DialogDemo  title="地址">
      <!-- 当需要分类传递内容的时候 -->
      <!-- 我们可以使用 具名插槽来区别(也就是给插槽起名字) -->
      <!-- 在父组件中利用 template 以及  v-slot 给插槽命名 -->
      <template v-slot:cpntent>
        <form action="">
        <input type="text">
        <input type="text">
      </form>
      </template>
      <!-- 没有起名字的插槽部分 都称为默认插槽  default -->
      <div>
        <button>取消</button>
        <button>确定</button>
      </div>
    </DialogDemo>
  </div>
</template>

子组件:在子组件中使用父组件 命名 comtent 插槽
slot 也可以不起名字,因为它获取的是 默认插槽

<template>
  <div>
    <button>阿迪达斯</button>
    <div class="mask">
      <div class="dialog">
        <!-- 对话框的三部分内容都不是固定的内容 -->
        <!-- 每一部分的内容都需要父组件传递 -->
        <!-- 1.标题内容 直接传递字符串既可 -->
        <div class="dialog-header">{{title}}</div>
        <!-- 2.对话框的内容部分,不确定性太确,它可以展示任何标签,
        此时就需要父组件传递插槽给子组件,也就是传递 html 结构个子组件 -->
        <div class="dialog-content">
          <!-- 在子组件中使用父组件命名的 comtent 的插槽 -->
          <slot name="cpntent" />
        </div>
        <div class="dialog-foot">
          <!-- slot 可以不起名字,它获取的是 默认插槽  -->
          <slot />
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props:['title']
}
</script>

在这里插入图片描述

================================================================================================

  • 4)

子组件的样式

<style>
.mask {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 999;
  background-color: rgba(0,0,0,0.5);
}

.mask .dialog{
  position: absolute;
  background-color: #fff;
  width: 600px;
  top: 160px;
  left: 50%;
  margin-left: -250px;
  min-height: 200px;
  display: flex;
  flex-direction: column;
}

.mask .dialog .dialog-header , .mask .dialog .dialog-foot {
  padding: 15px;
  border-bottom: 1px solid #ccc;
  flex-shrink: 0;
}

.mask .dialog .dialog-header {
  display: flex;
  justify-content: space-between;
}
.mask .dialog .dialog-header .close{
  cursor: pointer;
}
.mask .dialog .dialog-content {
  padding: 15px;
  border-bottom: 1px solid #ccc;
  flex-grow: 1;
}

.mask .dialog .dialog-foot {
  display: flex;
  justify-content: flex-end;
  border-bottom: 0;
}
</style>

================================================================================================

  • 5)让我们上面所写的东西先消失,在点击阿迪达斯后出现

父组件:

<template>
  <div>
    <button @click="show = true">阿迪达斯</button> <!--点击时出现-->
   ...
  </div>
</template>

<script>
export default {
  ...
  data() {
    return {
      show: false
    }
  }
}
</script>

================================================================================================

  • 6)点击灰色的地方以及 × 关闭我们显示的东西

父组件:给父组件定义方法 并且传递给子组件

<template>
  <div>
    <button @click="show = true">阿迪达斯</button>
    ...
    <!--将它传递给子组件-->
    <DialogDemo title="地址"  :show="show"  @close="close">
    <!---->
     <!--<DialogDemo title="地址"  :show.sync="show">  也可简写成这样-->
    ...
</template>

<script>
import DialogDemo from "./components/DialogDemo.vue";
export default {
  components: { DialogDemo },
  // 定义方法
  data() {
    return {
      show: false,
    };
  },
  methods: {
    close() {
      this.show = false;
    },
  },
};
</script>

子组件:接收父组件传递过来的方法

<template>
    <!-- 对话框 -->
     <!--点击空白的地方 关闭-->
    <div v-show="show" class="mask" @click.self="$emit('close')">
   <!-- <div v-show="show" class="mask" @click.self="$emit('update:show',false)">  也可简写成这样-->
    .....
        <div class="dialog-header">
          <span>{{title}}</span>
           <!--点击 × 的地方 关闭-->
          <span class="close" @click.self="$emit('close')">×</span>
          <!-- <span class="close" @click.self="$emit('update:show',false)">×</span> 也可简写成这样-->
        </div>
        .....
</template>

<script>
export default {
  props:['title','show'],
}
</script>
...

================================================================================================

  • 7)点击确定先完成信息的确定再关闭,点击取消直接关闭

父组件:

<template>
  <div>
  ...
      <div>
        <button @click="show = false">取消</button>
        <button @click="ok">确定</button>
      </div>
    </DialogDemo>
  </div>
</template>

<script>
...
  methods: {
  ...
    // 对确认的信息进行 提示
    ok(){
      console.log('确定这样做')
      this.show = false
    }
  },
};
</script>

================================================================================================

  • 8)当出现弹窗的时候,滚动条不能滑动

在子组件内使用 updated 生命周期功能

<script>
export default {
  props:['title','show'],
  updated() {
    if(this.show){
      document.body.style.overflowY = 'hidden'
    }
  }
}
</script>

如果让滚动条消失,滚动条消失时 页面会重新进行渲染布局

<script>
export default {
  props:['title','show'],
  updated() {
    if(this.show){
      // 隐藏滚动条
      document.body.style.overflowY = 'hidden'
      document.body.style.paddingRight = '17px'
    }else{
      document.body.style.overflowY = 'scroll'
      document.body.style.paddingRight = '0'
    }
  }
}
</script>

================================================================================================

  • 9)使用生命周期来实现监听

使用生命周期 updated 来监听 props 的变化
这里我们也可以利用 侦听器来监听,使用 watch 侦听器 props、data、computed
语法 watch:{监听的内容:函数}

<script>
export default {
  props:['title','show'],
 watch: {
    show(newVal) {
      if (newVal) {
        document.body.style.overflowY = "hidden";
        document.body.style.paddingRight = "17px";
      } else {
        document.body.style.overflowY = "scroll";
        document.body.style.paddingRight = "0";
      }
    },
  },
}
</script>

方法二:watch:{监听的内容:{ handler:函数,deep:true,immediate:true}}
deep: true, // 进行深层次侦听值,有些时候值是复杂数据的时候更新某个属性并不会导致侦听器触发,就可以加deep:true
immediate: true //组件初始时就执行一次侦听函数 (例:打开某一个软件时候的 弹窗)

<script>
export default {
  props:['title','show'],
 watch: {
    show: {
      handler(newVal) {
        if (newVal) {
          document.body.style.overflowY = "hidden";
          document.body.style.paddingRight = "17px";
        } else {
          document.body.style.overflowY = "scroll";
          document.body.style.paddingRight = "0";
        }
      },
      // deep: true, // 进行深层次侦听值,有些时候值是复杂数据的时候更新某个属性并不会导致侦听器触发,就可以加deep:true
      immediate: true //组件初始时就执行一次侦听函数
    },
  },
}
</script>

总结

  • 插槽的使用:
    • 我们可以使用 具名插槽来区别(也就是给插槽起名字)

父组件:
1.在父组件中利用 template 以及 v-slot 给插槽命名
2.没有起名字的插槽部分 都称为默认插槽 default

子组件:在子组件中使用父组件 命名 comtent 插槽
slot 也可以不起名字,因为它获取的是 默认插槽

  • 侦听器的使用

使用生命周期 updated 来监听 props 的变化
这里我们也可以利用 侦听器来监听,使用 watch 侦听器 props、data、computed
语法 watch:{监听的内容:函数}

方法二:watch:{监听的内容:{ handler:函数,deep:true,immediate:true}}
deep: true, // 进行深层次侦听值,有些时候值是复杂数据的时候更新某个属性并不会导致侦听器触发,就可以加deep:true
immediate: true //组件初始时就执行一次侦听函数 (例:打开某一个软件时候的 弹窗)

总代码

父组件

<template>
  <div>
    <button @click="show = true">阿迪达斯</button>
    <!-- 父组件内写在子组件的标签中间 -->
    <!-- 给子组件进行传递 插槽 内容 -->
    <!-- 但需要把标签写成闭合标签 -->
    <!-- <DialogDemo title="地址"  :show="show"  @close="close"> -->
      <DialogDemo title="地址"  :show.sync="show">
      <!-- 当需要分类传递内容的时候 -->
      <!-- 我们可以使用 具名插槽来区别(也就是给插槽起名字) -->
      <!-- 在父组件中利用 template 以及  v-slot 给插槽命名 -->
      <template v-slot:cpntent>
        <form action="">
          <input type="text" />
          <input type="text" />
        </form>
      </template>
      <!-- 没有起名字的插槽部分 都称为默认插槽  default -->
      <div>
        <button @click="show = false">取消</button>
        <button @click="ok">确定</button>
      </div>
    </DialogDemo>
  </div>
</template>

<script>
import DialogDemo from "./components/DialogDemo.vue";
export default {
  components: { DialogDemo },
  data() {
    return {
      show: false,
    };
  },
  methods: {
    // close() {
    //   this.show = false;
    // },
    ok(){
      console.log('确定这样做')
      this.show = false
    }
  },
};
</script>

<style>
</style>

子组件

<template>
  <!-- 对话框 -->
  <!--点击空白的地方 关闭-->
  <div v-show="show" class="mask" @click.self="$emit('update:show', false)">
    <div class="dialog">
      <!-- 对话框的三部分内容都不是固定的内容 -->
      <!-- 每一部分的内容都需要父组件传递 -->
      <!-- 1.标题内容 直接传递字符串既可 -->
      <div class="dialog-header">
        <span>{{ title }}</span>
        <!--点击 × 的地方 关闭-->
        <span class="close" @click.self="$emit('update:show', false)">×</span>
      </div>
      <!-- 2.对话框的内容部分,不确定性太确,它可以展示任何标签,
        此时就需要父组件传递插槽给子组件,也就是传递 html 结构个子组件 -->
      <div class="dialog-content">
        <!-- 在子组件中使用父组件命名的 comtent 的插槽 -->
        <slot name="cpntent" />
      </div>
      <div class="dialog-foot">
        <!-- slot 可以不起名字,它获取的是 默认插槽  -->
        <slot />
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: ["title", "show"],
  // updated() {
  //   if(this.show){
  //     // 隐藏滚动条
  //     document.body.style.overflowY = 'hidden'
  //     document.body.style.paddingRight = '17px'
  //   }else{
  //     document.body.style.overflowY = 'scroll'
  //     document.body.style.paddingRight = '0'
  //   }
  // },
  //> 使用生命周期 `updated` 来监听 `props` 的变化
  // > 这里我们也可以利用 侦听器来监听,使用 `watch` 侦听器 一般用零监听 props data computed
  // > 语法  watch:{监听的内容:函数}
  // watch:{监听的内容:{ handler:函数,deep:true,immediate:true}}
  watch: {
    show: {
      handler(newVal) {
        if (newVal) {
          document.body.style.overflowY = "hidden";
          document.body.style.paddingRight = "17px";
        } else {
          document.body.style.overflowY = "scroll";
          document.body.style.paddingRight = "0";
        }
      },
      // deep: true, // 进行深层次侦听值,有些时候值是复杂数据的时候更新某个属性并不会导致侦听器触发,就可以加deep:true
      immediate: true //组件初始时就执行一次侦听函数
    },
  },
};
</script>

<style>
.mask {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 999;
  background-color: rgba(0, 0, 0, 0.5);
}

.mask .dialog {
  position: absolute;
  background-color: #fff;
  width: 600px;
  top: 160px;
  left: 50%;
  margin-left: -250px;
  min-height: 200px;
  display: flex;
  flex-direction: column;
}

.mask .dialog .dialog-header,
.mask .dialog .dialog-foot {
  padding: 15px;
  border-bottom: 1px solid #ccc;
  flex-shrink: 0;
}

.mask .dialog .dialog-header {
  display: flex;
  justify-content: space-between;
}
.mask .dialog .dialog-header .close {
  cursor: pointer;
}
.mask .dialog .dialog-content {
  padding: 15px;
  border-bottom: 1px solid #ccc;
  flex-grow: 1;
}

.mask .dialog .dialog-foot {
  display: flex;
  justify-content: flex-end;
  border-bottom: 0;
}
</style>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fvcvv

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值