Vue-插槽与生命周期初见面

834 阅读3分钟

匿名、具名插槽

<body>
  <div id="app">
    <App></App>
  </div>
  <script src="../vue.js"></script>
  <script>
    //匿名插槽
    Vue.component('test',{
    template:`
      <button>
        <slot></slot>
      </button>
    `
    })

    //具名插槽
    //只要匹配到slot标签的name值 template中的内容就会被插入到这个槽中
    Vue.component('MBtn', {
      template: `
        <button>
          <slot name='login'></slot>
          <slot name='submit'></slot>
          <slot name='register'></slot>
        </button>
      `
    })

    const App = {
      data() {
        return {
          title: '父组件的标题'
        }
      },

      template: `
        <div>
          <test>匿名插槽</test>
          <MBtn>
            <template slot='login'>
              <a href="#">登录</a>
            </template>
          </MBtn>
          <m-btn>
            <template slot='submit'>
              提交
            </template>
          </m-btn>
          <m-btn>
            <template slot='register'>
              注册
            </template>
          </m-btn>
        </div>
      `
    }
    new Vue({
      el: '#app',
      data: {},
      components: {
        App
      }
    })
  </script>
</body>

作用域插槽

<body>
  <div id="app">
    <App></App>
  </div>
  <script src="../vue.js"></script>
  <script>
    //已经开发了一个待办事项列表组件,很多模块都在用
    //A APP两个组件都要用到todoList 但APP需要添加✔功能
    //1.之前数据格式和引用接口不变,正常显示
    //2.新功能模块增加对勾
    const todoList ={
      props:{
        todos:Array,
        defaultValue:[]
      },
      template:`
      <ul>
        <li v-for='item in todos' :key='item.id'>
          <slot :itemValue = 'item'>
          </slot>
          {{item.title}}
        </li>
      </ul>
      `
    }

    const App = {
      data() {
        return {
          todoList:[{
            title:'大哥你好吗',
            isComplate:true,
            id:1
          },
          {
            title:'小弟我还行',
            isComplate:false,
            id:2
          },
          {
            title:'你在干什么',
            isComplate:false,
            id:3
          },
          {
            title:'抽烟喝酒烫头',
            isComplate:true,
            id:4
          },
          ]
        }
      },
      components:{
        todoList
      },
      template: `
        <todoList :todos='todoList'>
          <template v-slot='data'>  
            <input type="checkbox" v-model='data.itemValue.isCompalte'/>
          </template>
        </todoList>
      `,

    }
    new Vue({
      el: '#app',
      data: {

      },
      components: {
        App
      }
    })
  </script>
</body>

生命周期

<style>
    .active{
      color:red
    }
</style>
<body>
  <div id="app">
    <App></App>
  </div>
  <script src="../vue.js"></script>
  <script>
    /*
    beforeCreate
    created
    beforeMount
    mounted
    beforeUpdate
    updated
    
    activated 激活
    deactivated 停用
    要配合keep-alive
    
    beforeDestroy
    destroyed
    */
    Vue.component('Test',{
      data() {
        return {
          msg:'test',
          isRed:false
        }
      },
      methods: {
        handleClick(){
          this.msg = 'afterchange'
          this.isRed = !this.isRed;
        }
      },
      template:`
        <div>
          <h3 :class='{active:isRed}'>{{msg}}</h3>
          <button @click = 'handleClick'>改变</button>
        </div>
      `,
      beforeCreate(){
        console.log('组件创建之前',this.$data);//undefined
      },
      created(){
        //非常重要的事情,在此时发送ajax,请求后端数据
        console.log('组件创建完成',this.$data.msg);//test
      },
      beforeMount(){
        //即将挂载 此时没有任何内容
        console.log('DOM挂载之前',document.getElementById('app'));
        //div里的app标签里没有任何内容
      },
      mounted(){
        //这里也可以发送ajax 不过一般在created里
        console.log('DOM挂载之前',document.getElementById('app'));
        //app标签里的所有内容都被渲染完成
      },
      beforeUpdate() {
        //获取更新之前的DOM
        console.log('更新之前的DOM',document.getElementById('app').innerHTML);
        //更新之前的DOM <div><h3>test</h3> <button>改变</button></div>
      },
      updated() {
        //获取最新的DOM
        console.log('更新之前的DOM',document.getElementById('app').innerHTML);
        //更新之前的DOM <div><h3>afterchange</h3> <button>改变</button></div>
      },
      //destory会比较消耗资源
      beforeDestroy(){
        console.log('销毁之前');
      },
      destroyed() {
        console.log('销毁完成');
      },
      //activated会放到缓存
      activated(){
        console.log('组件被激活了');
      },
      deactivated() {
        console.log('组件被停用了');
      },
    })

    const App ={
      data() {
        return {
          isShow:true
        }
      },
      components:{
        
      },
      template:`
        <div>
          <keep-alive>
            <Test v-if='isShow'></Test>
          </keep-alive>
          <button @click='clickHandle'>改变生死</button>
        </div>
      `,
      methods: {
        clickHandle(){
          this.isShow = !this.isShow;
        }
      },
    }

    new Vue({
      el:'#app',
      data:{},
      components:{
        App
      }
    })
  </script>
</body>