vue学习2

组件-非父子通信

  <div id="box">
    <child1></child1>
    <child2></child2>
  </div>

  <script type="text/javascript">
    //中央事件总线 bus
    var bus = new Vue()
    // bus.$on("zzy")   // 监听事件
    // bus.$emit("zzy") //触发事件



    Vue.component("child1", {
      template: `
            <div>child1</div>
          `,

      //child1 组件 创建完成, 并且渲染到dom节点上
      mounted() {
        console.log("moutend", "8个生命周期中一个,组件上树后触发")

        bus.$on("zzy", (data) => {
          console.log("child1监听的函数", data)
        })
      }
    })

    Vue.component("child2", {
      template: `
            <div>child2
              <button @click="handleClick">click</button>  
            </div>
          `,
      methods: {
        handleClick() {
          bus.$emit("zzy", "1111111111111111111")
        }
      }
    })

    var vm = new Vue({
      el: "#box",
      methods: {

      }
    })
  </script>

bus案例

 <div id="box">
        <button @click="handleAjax">ajax</button>

        <film-item v-for="item in datalist" :key="item.filmId" :mydata="item"></film-item>

        <film-detail></film-detail>
    </div>
    <script>

        var bus = new Vue()
        // bus.$on
        // bus.$emit
        Vue.component("filmItem", {
            props: ["mydata"],
            template: `
                <div class="item">
                    <img :src="mydata.poster"/>
                    {{mydata.name}}
                    <div>
                        <button @click="handleClick">详情</button>
                    </div>
                </div>
            `,
            methods: {
                handleClick() {
                    // console.log(this.mydata.synopsis)

                    bus.$emit("zzy", this.mydata.synopsis)
                }
            }
        })

        Vue.component("filmDetail", {
            //组件刚刚创建好,就开始订阅
            data() {
                return {
                    info: ""
                }
            },
            //生命周期
            mounted() {
                // console.log("当前组件上树后触发")
                bus.$on("zzy", (data) => {
                    console.log("1111111", data)
                    this.info = data
                })
            },

            template: `
                <div class="filminfo">
                    {{info}}
                </div>  
            `
        })



        new Vue({
            el: "#box",
            data: {
                datalist: [],
            },
            methods: {
                handleAjax() {
                    fetch("./json/test.json")
                        .then(res => res.json())
                        .then(res => {
                            console.log(res.data.films)
                            this.datalist = res.data.films
                        })
                }
            }
        })

    </script>

props修改

<div id="box">
    <div v-once>
        {{title}}
    </div>

    <child :mytitle="title"></child>
</div>

<script>
    Vue.component("child", {
        props: ["mytitle"],
        template: `
            <div >
                child-{{mytitle}}
                <button @click="handleClikc">click</button>
            </div>
        `,
        methods: {
            handleClikc() {
                this.mytitle = "22222222222222"
            }
        }
    })
    var vm = new Vue({
        el: "#box",
        data: {
            title: "11111111111111"
        }
    })

    //属性 -- 父组件传给你的属性,只有父组件可以重新传,但不允许子组件随意修改.
    //状态 --组件内部的状态,可以随意修改

</script>

动态组件

 <div id="box">

    <!-- <home v-show=" which=== 'home' "></home>
      <list v-show=" which=== 'list' "></list>
      <shopcar v-show=" which=== 'shopcar' "></shopcar> -->

    <keep-alive>
      <component :is="which"></component>
    </keep-alive>
    <footer>
      <ul>
        <li @click=" which='home' ">
          首页
        </li>
        <li @click=" which='list' ">
          列表
        </li>
        <li @click=" which='shopcar' ">
          购物车
        </li>
      </ul>
    </footer>
  </div>


  <script type="text/javascript">
    Vue.component("home", {
      template: `
          <div>
            home
            <input type="search"/>
          </div>
         `
    })

    Vue.component("list", {
      template: `
          <div>
            list
          </div>
         `
    })

    Vue.component("shopcar", {
      template: `
          <div>
            shopcar
          </div>
         `
    })

    var vm = new Vue({
      el: "#box",
      data: {
        which: 'home'
      }
    })
  </script>

slot

  <div id="box">
    <!-- 当前组件或者节点 在哪个模板中,就能访问哪个模板状态 -->
    <child>
      <div slot="a">11111111111111</div>
      <div slot="b">22222222222222</div>
      <div slot="c">33333333333333</div>
      <div>44444444444444</div>
    </child>

    <navbar>
      <button slot="left">aaa</button>
      <i class="iconfont icon-all" slot="right">字体图标</i>
    </navbar>

  </div>

  <script>
    // 插槽的意义 : 扩展组件能力, 提高组件的复用性
    Vue.component("navbar", {
      template: `
      
        <div>
           <slot name="left"></slot>
           <span>navbar</span>  
           <slot name="right"></slot>
        </div>
      `
    })


    // 单个插槽, <slot></slot>
    // 具名插槽  <slot name="a"></slot>
    Vue.component("child", {
      template: `
        <div>
          child
          <slot name="a"></slot>
          <slot name="b"></slot>
          <slot name="c"></slot>
          <slot></slot>
        </div>
      `
    })
    new Vue({
      el: "#box"
    })
  </script>

slot例子

  <div id="box">
    <navbar>
      <button @click="isShow=!isShow">click</button>
    </navbar>
    <sidebar v-show="isShow"></sidebar>
  </div>
  <script>

    Vue.component("navbar", {

      template: `
            <div style="background:yellow">
              nabbar- <slot></slot>
            </div>
          `,

    })

    Vue.component("sidebar", {
      template: `
            <ul style="background-color: yellow;width: 200px;height: 500px;" >
              <li>首页</li>
              <li>钱包</li>
              <li>设置</li>
            </ul>
          `
    })

    new Vue({
      el: "#box",
      data: {
        isShow: false
      }
    })
  </script>

新slot

<div id="box">
    <!-- 当前组件或者节点 在哪个模板中,就能访问哪个模板状态 -->
    <child>
      <template v-slot:a>
        <div>1111111111</div>
      </template>

      <template #b>
        2222222222222222222
      </template>

      <div slot="c">33333333333333</div>
      <div>44444444444444</div>
    </child>

    <navbar>
      <template #left>
        <button>aaa</button>
      </template>
      <template #right>
        <i class="iconfont icon-all">字体图标</i>
      </template>
    </navbar>

  </div>

  <script>
    // 插槽的意义 : 扩展组件能力, 提高组件的复用性
    Vue.component("navbar", {
      template: `
      
        <div>
          <slot name="left"></slot>
          <span>navbar</span>  
          <slot name="right"></slot>
        </div>
      `
    })


    // 单个插槽, <slot></slot>
    // 具名插槽  <slot name="a"></slot>
    Vue.component("child", {
      template: `
        <div>
          child
          <slot name="a"></slot>
          <slot name="b"></slot>
          <slot name="c"></slot>
          <slot></slot>
        </div>
      `
    })
    new Vue({
      el: "#box"
    })
  </script>

过渡效果

过度

 <style>
    /* 进场动画 */
    .zzy-enter-active {
      animation: aaa 1.5s;
    }

    /* 出场动画 */
    .zzy-leave-active {
      animation: aaa 1.5s reverse;
    }

    @keyframes aaa {
      0% {
        opacity: 0;
        transform: translateX(100px);
      }

      100% {
        opacity: 1;
        transform: translateX(0px);
      }
    }
  </style>
  <!-- <link rel="stylesheet" href="lib/animate.css"> -->
</head>

<body>

  <div id="box">
    <button @click="isShow= !isShow">change</button>
    <transition enter-active-class="zzy-enter-active" leave-active-class="zzy-leave-active">
      <div v-show="isShow">1111111111111111</div>
    </transition>


    <transition name="zzy">
      <div v-if="isShow">
        <div>222222222222222222</div>
        <div>333333333333333</div>
        <div>44444444444444444</div>
        <div>55555555555555555</div>
      </div>
    </transition>
  </div>
  <script>
    new Vue({
      el: "#box",
      data: {
        isShow: false
      }
    })
  </script>

初始元素过渡

  <style>
    /* 进场动画 */
    .zzy-enter-active {
      animation: aaa 1.5s;
    }

    /* 出场动画 */
    .zzy-leave-active {
      animation: aaa 1.5s reverse;
    }

    @keyframes aaa {
      0% {
        opacity: 0;
        transform: translateX(100px);
      }

      100% {
        opacity: 1;
        transform: translateX(0px);
      }
    }
  </style>
  <!-- <link rel="stylesheet" href="lib/animate.css"> -->
</head>

<body>

  <div id="box">
      <button @click="isShow= !isShow">change</button>
      <transition enter-active-class="zzy-enter-active" leave-active-class="zzy-leave-active">
        <div v-show="isShow">1111111111111111</div>
      </transition>


      <transition name="zzy" appear>
        <div v-if="isShow">222222222222222222</div>
      </transition>
  </div>
  <script>
    new Vue({
      el:"#box",
      data:{
        isShow:true
      }
    })
  </script>

多个元素过渡

 <style>
    /* 进场动画 */
    .zzy-enter-active {
      animation: aaa 1.5s;
    }

    /* 出场动画 */
    .zzy-leave-active {
      animation: aaa 1.5s reverse;
    }

    @keyframes aaa {
      0% {
        opacity: 0;
        transform: translateX(100px);
      }

      100% {
        opacity: 1;
        transform: translateX(0px);
      }
    }
  </style>
  <!-- <link rel="stylesheet" href="lib/animate.css"> -->
</head>

<body>

  <!-- <div class="zzy-enter-active">333333333333333</div> -->

  <div id="box">
    <button @click="isShow = !isShow">change</button>
    <transition name="zzy" mode="out-in">
      <div v-if="isShow" key="1">111111111111111</div>
      <div v-else key="2">2222222222222222222222222</div>
    </transition>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: "#box",
      data: {
        isShow: true
      }
    })

    /*
      diff算法,
       1. 同层级对比
       2. 同标签, 组件 对比
       3. 同key对比
    */
  </script>

多个组件过渡

  <style type="text/css">
    * {
      margin: 0px;
      padding: 0px;
    }

    html,
    body {
      width: 100%;
      height: 100%;
      overflow-x: hidden;
    }

    footer ul {
      display: flex;
      position: fixed;
      left: 0px;
      bottom: 0px;
      width: 100%;
      height: 40px;
    }

    footer ul li {
      flex: 1;
      text-align: center;
      list-style: none;
      height: 40px;
      line-height: 40px;
      background: gray;
      color: white;
    }
  </style>
  <style>
    /* 进场动画 */
    .zzy-enter-active {
      animation: aaa 1.5s;
    }

    /* 出场动画 */
    .zzy-leave-active {
      animation: aaa 1.5s reverse;
    }

    @keyframes aaa {
      0% {
        opacity: 0;
        transform: translateX(100px);
      }

      100% {
        opacity: 1;
        transform: translateX(0px);
      }
    }
  </style>
</head>

<body>
  <div id="box">

    <!-- <home v-show=" which=== 'home' "></home>
      <list v-show=" which=== 'list' "></list>
      <shopcar v-show=" which=== 'shopcar' "></shopcar> -->

    <keep-alive>
      <transition name="zzy" mode="out-in">
        <component :is="which"></component>
      </transition>
    </keep-alive>
    <footer>
      <ul>
        <li @click=" which='home' ">
          首页
        </li>
        <li @click=" which='list' ">
          列表
        </li>
        <li @click=" which='shopcar' ">
          购物车
        </li>
      </ul>
    </footer>
  </div>


  <script type="text/javascript">
    Vue.component("home", {
      template: `
          <div>
            home
            <input type="search"/>
          </div>
         `
    })

    Vue.component("list", {
      template: `
          <div>
            list
          </div>
         `
    })

    Vue.component("shopcar", {
      template: `
          <div>
            shopcar
          </div>
         `
    })

    var vm = new Vue({
      el: "#box",
      data: {
        which: 'home'
      }
    })
  </script>

多个列表过渡

  <style>
    /* 进场动画 */
    .zzy-enter-active {
      animation: aaa 1.5s;
    }

    /* 出场动画 */
    .zzy-leave-active {
      animation: aaa 1.5s reverse;
    }

    @keyframes aaa {
      0% {
        opacity: 0;
        transform: translateX(100px);
      }

      100% {
        opacity: 1;
        transform: translateX(0px);
      }
    }
  </style>
</head>

<body>
  <div id="box">
    <!-- 双向绑定的指令 -->
    <!-- {{mytext}} -->
    <input type="text" v-model="mytext" />
    <button @click="handleAdd()">add</button>

    <div v-show="!datalist.length">待办事项空空如也</div>

    <transition-group name="zzy" tag="ul" v-show="datalist.length">
      <li v-for="(item,index) in datalist" :key="item">
        {{item}}--{{index}}
        <button @click="handleDel(index)">del</button>
      </li>
    </transition-group>

  </div>
  <script>
    var vm = new Vue({
      el: "#box",
      data: {
        mytext: "11111",
        datalist: ["111", "222", "333"]
      },
      methods: {
        handleAdd() {
          console.log("add", this.mytext)
          this.datalist.push(this.mytext)

          this.mytext = "" //清空value
        },
        handleDel(index) {
          console.log("del", index)
          this.datalist.splice(index, 1)
        }
      }
    })
  </script>

可复用过渡

  <style>
    .left {}

    .right {
      position: fixed;
      right: 0px;
      top: 0px;
    }

    /* 进场动画 */
    .left-enter-active {
      animation: aaa 1.5s;
    }

    /* 出场动画 */
    .left-leave-active {
      animation: aaa 1.5s reverse;
    }

    @keyframes aaa {
      0% {
        opacity: 0;
        transform: translateX(-100%);
      }

      100% {
        opacity: 1;
        transform: translateX(0px);
      }
    }


    .right-enter-active {
      animation: bbb 1.5s;
    }

    /* 出场动画 */
    .right-leave-active {
      animation: bbb 1.5s reverse;
    }

    @keyframes bbb {
      0% {
        opacity: 0;
        transform: translateX(100px);
      }

      100% {
        opacity: 1;
        transform: translateX(0px);
      }
    }
  </style>
</head>

<body>
  <div id="box">
    <navbar @myevent="handleEvent"></navbar>
    <sidebar v-show="isShow" mode="right"></sidebar>
  </div>
  <script>
    Vue.component("navbar", {

      template: `
            <div>
              nabbar-<button @click="handleClick">click</button>  
            </div>
          `,
      methods: {
        handleClick() {
          // 通知父组件 取反 isShow - 子传父 依靠 事件
          this.$emit("myevent")
        }
      }
    })

    Vue.component("sidebar", {
      props: ["mode"],
      template: `
          <transition :name="mode">
            <ul style="background-color: yellow;width: 200px;height: 500px;" :class="mode">
              <li>首页</li>
              <li>钱包</li>
              <li>设置</li>
            </ul>
          </transition>
          `
    })

    new Vue({
      el: "#box",
      data: {
        isShow: false
      },
      methods: {
        handleEvent() {
          console.log("父组件", "1111111")
          this.isShow = !this.isShow
        }
      }
    })
  </script>

组件生命周期

   <div id="box">
        {{myname}}

        <button @click=" myname='xiaoming' ">change</button>

        <ul>
          <li v-for="data in datalist" :key="data">
            {{data}}
          </li>
        </ul>
      </div>

    <script type="text/javascript">

    // Vue.component("navbar",{
    //   template:``
    // })
      //根组件
      var vm= new Vue({
        el:"#box",
        data:{  
          myname:"zzy",
          datalist:[]
        },
        // template:`<div>root component--{{myname}}</div>`,
        beforeCreate(){
          console.log("beforeCreate",this.myname)
        },
        created(){
          console.log("created","初始化状态或者挂载到当前实例的一些属性")
          this.myname = this.myname+"11111111" //被拦截的状态

          this.user =localStorage.getItem("user")  // this下面的属性
          // 发ajax
        },

        beforeMount(){
          console.log("beforeMount",this.$el)  // 模板解析之前最后一次修改模板节点。
        },

        mounted(){
          console.log("mounted","拿到真实的dom节点",document.getElementById("box").innerHTML)
          // 依赖于dom创建之后, 才进行初始化工作的插件  (轮播插件)
          // 订阅 bus.$on
          // 发ajax

          setTimeout(()=>{
            this.datalist = ["1111","222","333"]
            // 虚拟dom创建, diff对比 -- 状态立即更新,dom异步更新
            // console.log(document.getElementsByTagName("li").length)
          },2000)

          
        },

        beforeUpdate(){
          console.log("beforeUpdate","更新之前,记录老的dom某些状态,比如滚动条位置记录。")
        },
        updated(){
          console.log("updated","更新完成,获取更新的后dom,才进行swiper工作的插件 ")
          // console.log(document.getElementsByTagName("li").length)
        }
      })
    </script>

销毁

  <div id="box">
    <child v-if="isCreated"></child>
  </div>
  <script>
    Vue.component("child", {
      data() {
        return {
          time: 1000
        }
      },
      created() {
        this.id = null
      },
      mounted() {
        this.id = setInterval(() => {
          console.log("倒计时")
          this.time--
        }, 1000)

        window.onresize = () => {
          console.log("resize")
        }
      },
      template: `
        <div>
            抢购倒计时组件
            <div>{{time}}</div>  
        </div>
      `,

      beforeDestroy() {
        console.log("beforeDestroy", "清除定时器, 事件解绑,,,,")

        clearInterval(this.id)

        window.onresize = null
      },

      destroyed() {
        console.log("destroyed", "清除定时器, 事件解绑,,,,")
      }
    })
    var vm = new Vue({
      el: "#box",
      data: {
        isCreated: true
      }
    })
  </script>

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值