前端框架Vue(三)


插槽

插槽的定义

插槽是什么?插槽是子组件中的提供给父组件的一个占位符,用<slot></slot>表示,父组件可以在这个占位符中填充任何模板代码,如HTML、组件等,填充的内容会替换字组件的<slot></slot>标签。

<slot>元素是一个插槽出口(solt outlet),标示了父元素提供的插槽内容(slot content)将在哪里被渲染。

插槽的应用

新建一对父子组件如下:

App.vue

<template>
  <div>
    app
    <Child>
      <div>我是在app组件中的一段html代码</div>
    </Child>
  </div>
</template>

<script>
import Child from './Child.vue';
export default {
  components:{
    Child
  }
}
</script>

Child.vue

<template>
  <div>
    child
  </div>
</template>

访问项目地址,父组件中的<div>我是在app组件中的一段html代码</div>没有解析显示

在子组件中增加插槽solt

<template>
  <div>
    child
    <slot></slot>
  </div>
</template>

再次访问项目地址,父组件中的<div>我是在app组件中的一段html代码</div>已被解析显示解析显示

若在子组件中写两个插槽

<template>
  <div>
    <slot></slot>
    child
    <slot></slot>
  </div>
</template>

相同的内容会在两个插槽处插入。

在父组件App.vue写入两条内容

<template>
  <div>
    app
    <Child>
      <div>我是在app组件中的一段html代码111</div>
      <div>我是在app组件中的一段html代码222</div>
    </Child>
  </div>
</template>

<script>
import Child from './Child.vue';
export default {
  components:{
    Child
  }
}
</script>

两条内容会在两个插槽处都显示。

若要实现第一条内容显示在插槽1的位置,第二条内容显示在插槽2的位置,这就用到了具名插槽,就是给插槽进行命名

子组件Child.vue

<template>
  <div>
    <slot name="one"></slot>
    child
    <slot name="two"></slot>
  </div>
</template>

父组件App.vue

<template>
  <div>
    app
    <Child>
      <template v-slot:one>
        <div>我是在app组件中的一段html代码111</div>
      </template>
      <template v-slot:two>
        <div>我是在app组件中的一段html代码222</div>
      </template>
    </Child>
  </div>
</template>

<script>
import Child from './Child.vue';
export default {
  components:{
    Child
  }
}
</script>

实现了分别显示的效果

上面的代码中,可以将v-slot:one简写为#one

组件的生命周期

每个Vue组件实例在创建时都需要经历一系列的初始化步骤,例如设置好数据监听,编译模板,挂载实例到DOM等,以及在数据改变时更新DOM。在这个过程中,它也会运行被称作生命周期钩子的函数,让开发者有机会在特定阶段运行自己的代码。

生命周期

beforeCreate()created()beforeMount()mounted()

App.vue

<template>
  <div>
    app-{{title}}

    <div id="root"></div>
  </div>
</template>
<script>
export default{
  data(){
    return{
      title:"AILynn"
    }
  },
  beforeCreate(){
    console.log(this.title)
  },
  created(){
    console.log(this.title)
    this.title = "PLScript"
    // 初始化工作
  },
  // 模板编译完成,但还未挂载到DOM中
  beforeMount(){
    console.log(document.getElementById('root'))
  },
  // 挂载到DOM中
  mounted(){
    console.log(document.getElementById('root'))
    // 这个步骤是要经常使用的
  }
}
</script>

使用ECharts演示

npm i echarts --save

App.vue

<template>
  <div>
    app-{{title}}

    <div id="root"></div>
    <div id="main" style="width: 600px;height:400px;"></div>
  </div>
</template>
<script>
import * as echarts from 'echarts'
export default{
  data(){
    return{
      title:"AILynn",
      option:{}
    }
  },
  beforeCreate(){
    console.log(this.title)
  },
  created(){
    console.log(this.title)
    this.title = "PLScript"
    // 初始化工作
    // 指定图表的配置项和数据
    this.option = {
        title: {
          text: 'ECharts 入门示例'
        },
        tooltip: {},
        legend: {
          data: ['销量']
        },
        xAxis: {
          data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
        },
        yAxis: {},
        series: [
          {
            name: '销量',
            type: 'bar',
            data: [5, 20, 36, 10, 10, 20]
          }
        ]
      };
  },
  // 模板编译完成,但还未挂载到DOM中
  beforeMount(){
    console.log(document.getElementById('root'))
  },
  // 挂载到DOM中
  mounted(){
    console.log(document.getElementById('root'))
    // 这个步骤是要经常使用的
    // 基于准备好的dom,初始化echarts实例
    let myChart = echarts.init(document.getElementById('main'));

    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(this.option);
  }
}
</script>

beforeUpdate()updated()

App.vue

<template>
  <div>
    app-{{title}}

    <div id="root"></div>
    <button @click="plClick">改变echart表格宽度</button>
    <div id="main" :style="{width:mywidth,height:'400px'}"></div>
  </div>
</template>
<script>
import * as echarts from 'echarts'
export default{
  data(){
    return{
      title:"AILynn",
      option:{},
      mywidth:"600px",
    }
  },
  beforeCreate(){
    console.log(this.title)
  },
  created(){
    console.log(this.title)
    this.title = "PLScript"
    // 初始化工作
    // 指定图表的配置项和数据
    this.option = {
        title: {
          text: 'ECharts 入门示例'
        },
        tooltip: {},
        legend: {
          data: ['销量']
        },
        xAxis: {
          data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
        },
        yAxis: {},
        series: [
          {
            name: '销量',
            type: 'bar',
            data: [5, 20, 36, 10, 10, 20]
          }
        ]
      };
  },
  // 模板编译完成,但还未挂载到DOM中
  beforeMount(){
    console.log(document.getElementById('root'))
  },
  // 挂载到DOM中
  mounted(){
    console.log(document.getElementById('root'))
    // 这个步骤是要经常使用的
    // 基于准备好的dom,初始化echarts实例
    this.myChart = echarts.init(document.getElementById('main'));

    // 使用刚指定的配置项和数据显示图表。
    this.myChart.setOption(this.option);
  },
  methods:{
    plClick(){
      this.mywidth = "800px"
      
      // 需要在生命周期的update方法中实现调用,这里不起作用
      // this.myChart.resize()
      // updated()生命周期方法更新的是全部的变更内容,若要仅更新当前的内容,可以使用$nextTick()方法实现
      this.$nextTick(()=>{
        console.log("nexttick")
        this.myChart.resize()
      })
    }
  },
  beforeUpdate(){
    console.log("beforeUpdate")
  },
  updated(){
    console.log(document.getElementById("main").style.width)

    // this.myChart.resize()
  }
}
</script>

beforeUnmount()unmounted()

App.vue

<template>
  <div>
    App - <button @click="isCreated=!isCreated">click</button>
    <Child v-if="isCreated"/>
  </div>
</template>
<script>
import Child from './Child.vue';
export default{
  data(){
    return{
      isCreated:true
    }
  },
  mounted(){
    console.log("app-mounted")
  },
  components:{
    Child
  }
}
</script>

Child.vue

<template>
  <div>
    child
  </div>
</template>

<script>
export default{
  mounted(){
    console.log("child-mounted")
  },
  beforeUnmount(){
    console.log("beforeUnmount")
  },
  unmounted(){
    console.log("unmounted")
  }
}
</script>

小节:

  1. beforeCreate() 会在实力初始化完成、props解析之后、data()computed等选项处理之前立即调用。
  2. created() 当这个钩子被调用时,以下内容已经设置完成:响应式数据、计算属性、方法和监听器。然而,此时挂载阶段还未开始。
  3. beforeMount() 当这个钩子被调用时,组件已经完成了其响应式状态的设置,但还没有创建DOM节点。它即将首次执行DOM渲染过程。
  4. mounted() 所有同步子组件都已经被挂载。这个钩子通常用于执行需要访问组件所渲染的DOM树相关的。
  5. beforeUpdate() 这个钩子可以用来在Vue更新DOM之前访问DOM状态。这个钩子中更改状态也是安全的。
  6. update() 这个钩子在组件的任意DOM更新后被调用,这些更新可能是由不同的状态变更导致的。如果你需要在某个特定的状态更改后访问更新后的DOM,请使用nextTick()作为替代。
  7. beforeUnmount() 当这个钩子被调用时,组件实例依然还保有全部的功能
  8. unmounted() 在一个组件实例被卸载之后调用

文章作者: 老百
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 老百 !
 上一篇
前端框架Vue(四) 前端框架Vue(四)
Vue 是一款用于构建用户界面的 JavaScript 框架。本小节介绍组合式API(Vue-Composition-API)。
2023-08-14
下一篇 
前端框架Vue(二) 前端框架Vue(二)
Vue 是一款用于构建用户界面的 JavaScript 框架。本小节介绍了Vue的组件的定义及组件间的相互通信。附Vue开发环境搭建。
2023-07-18
  目录