欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

浅谈插槽和修饰符

程序员文章站 2022-05-15 17:38:49
...

事件修饰符

  • @click.stop=“事件处理函数”
    • 作用:阻住事件冒泡的修饰符
  • @link.prevent=“事件处理函数”
    • 作用:阻住a链接的跳转(自动跳转),表单的提交按钮(自动刷新)
  • @click.capture=“事件处理函数”
    • 默认的情况下:事件处于冒泡阶段(事件冒泡和捕获只能存在一个)
    • 作用: @click.capture 使得事件处于捕获阶段! 于是先打印 我是爸爸 然后打印 我是儿子
  • @click.once = “事件处理函数”
    • 作用:添加了这个之后,事件只能触发一次
  • @click.self=“事件处理函数”
    • 作用:只当事件在改元素本身(比如不是子元素)触发时触发回调

阻住冒泡事件

  <div id="app">
    <div class="father" @click="fatherClick">
      <div class="son" @click.stop="sonClick">
      </div>
    </div>
  </div>

  <script src="../vue.js"></script>
  <script>
    //分析:对父亲和儿子两个盒子绑定相同的事件,存在冒泡事件,点击子元素的时候,会冒泡到父元素!
    //解决冒泡事件: @click.stop= "事件处理函数" 这是给子元素添加的,防止冒泡上去!
    let data = {
      msg1: "父亲",
      msg2: "儿子"
    }
    let methods = {
      fatherClick() {
        alert("我是父亲")
      },
      sonClick() {
        alert("我是儿子")
      }
    }
    const vm = new Vue({
      el: "#app",
      data,
      methods
    })
  </script>

阻住a链接的跳转,或者表单的提交(存在自动刷新)

  <div id="app">
    <a href="http://www.baidu.com" @click.prevent="links">去百度</a>
    <form action="" @click.prevent="postSubmit">
      <input type="text" name="username">
      <input type="text" name="pwd">
      <input type="submit" value="提交按钮">
    </form>
  </div>

  <script src="../vue.js"></script>
  <script>
    let date = {
    }
    let methods = {
      links() {
        console.log("我要去百度"); //原本要跳转到百度的,只不过使用了事件修饰符,就阻住了!
      },
      postSubmit() {
        console.log("表单提交被阻住"); //原本点击会提交,把表单的name属性值当做参数传递过去  阻住后就打印:表单提交被阻住
      }
    }
    const vm = new Vue({
      el: "#app",
      date,
      methods
    })
  </script>

事件捕获

 <div id="app">
    <div class="father" @click.capture="Fclick">
      <div class="son" @click=Sclick></div>
    </div>
  </div>

  <script src="../vue.js"></script>
  <script>
    //默认的情况下:事件处于冒泡阶段(事件冒泡和捕获只能存在一个)
    //添加了 @click.capture 使得事件处于捕获阶段!  于是先打印 我是爸爸 然后打印 我是儿子
    let data = {
      son: "我是儿子",
      father: "我是爸爸"
    }
    let methods = {
      Fclick() {
        console.log(this.father);
      },
      Sclick() {
        console.log(this.son);
      }
    }
    const vm = new Vue({
      el: "#app",
      data,
      methods
    })
  </script>

Vue插槽

  • 作用:就是占据一个位置,然后使用者可以根据自己需求,去显示相应的内容!
  • 组件插槽:
    • 组件插槽是为了让我们组件封装的时候,更具有扩展性
    • 让使用者可以决定组件内容是以什么内容显示!

简单的插槽使用

  • 需求:
    • 1:定义一个组件,上面和中间固定,下面预留一个位置,根据需求,显示
      • 显示按钮 显示我是右侧 显示我是段落
<body>
  <div id="app">
    <com-a>
      <button>按钮</button>
    </com-a>
    <com-a>
      <p>我是右侧</p>
    </com-a>
    <com-a>
      <p>我是段落</p>
    </com-a>
  </div>

  <script src="../vue.js"></script>
  <script>
    Vue.component("comA", {
      template: `
      <div>
        <h1>我是组件comA</h1>
        <p>我是左侧</p>
        <p>我是中间</p>
        <slot></slot>
      </div>
      `
    })

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

    })
  </script>

默认插槽的使用

  • 就是一个插槽内,若是有着多个默认显示的内容,比如一个按钮,那么就需要默认插槽了!

    • 在slot标签里面,自定义一个按钮,显示按钮内容,这样的话,在使用的时候,你没有添加标签去替换的话,那么就显示默认插槽
    • 注意点:就是在引用组件的时候,若是里面有很多标签,那么都会直接替换掉这个slot插槽 || 默认插槽
  • 需求:

<body>
  <div id="app">
    <com-a>
      <p>我是右侧</p>
    </com-a>
    <com-a>
      <p>我是段落</p>
      <p>我是段落2</p>
      <button>我是按钮</button>
    </com-a>
  </div>

  <script src="../vue.js"></script>
  <script>
    // <slot>
    // 默认插槽:若是引用组件的时候,没有添加替换的内容,那么就显示按钮
    //   <button>按钮</button>
    // </slot>
    // 注意点:就是在引用组件的时候,若是里面有很多标签,那么都会直接替换掉这个slot插槽 || 默认插槽
    // <slot></slot>
    Vue.component("comA", {
      template: `
      <div>
        <h1>我是组件comA</h1>
        <p>我是左侧</p>
        <p>我是中间</p>
        <slot>
          <button>按钮</button>
        </slot>
        <slot></slot>
      </div>
      `
    })

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

    })
  </script>

具名插槽的使用

  • 需求:封装一个具名插槽,可以根据需求,替换左侧 替换中间 替换右侧等!
<body>
  <div id="app">
    <com-a></com-a>
    <com-a>
      <span slot="left">我是替换左侧</span>
    </com-a>
    <com-a>
      <input slot="center" value="我是替换中间"></input>
    </com-a>
    <com-a>
      <button slot="right">我是替换右侧</button>
    </com-a>
    <template v-slot:left="slotProp">
      <span>{{slotProp.title}}</span>
    </template>
  </div>

  <script src="../vue.js"></script>
  <script>
    Vue.component("comA", {
      template: `
      <div>
          <slot name="left">左侧</slot>
          <slot name="center">中间</slot>
          <slot name="right">右侧</slot>
      </div>
      `
    })

    new Vue({
      el: "#app",
      data: {
        slotProp: "我是!!!"
      },

    })
  </script>

作用域插槽

  • 作用:子组件内数据可以被父页面拿到(解决了数据只能从父页面传递给子组件)

编译时的作用域

  • 所谓作用域:就是假设在app这个引用 子组件后,是在app这个组件内执行的,那么变量的作用域就是在app这个组件之中,会在app中的data查询数据,而不是去子组件之中!
  • 这个isShow是根据 父组件中的isShoe变量来决定显示还是隐藏的 vm.isShow=false 在浏览器之中修改后,隐藏了!
  <div id="app">
    <!-- 这个isShow是根据 父组件中的isShoe变量来决定显示还是隐藏的 vm.isShow=false 在浏览器之中修改后,隐藏了! -->
    <!-- 所谓作用域:就是在app这个引用 子组件后,是在app这个组件内执行的,那么变量的作用域就是在app这个组件之中,去app中的data查询数据 -->
    <com-a v-show="isShow"></com-a>
  </div>

  <script src="../vue.js"></script>
  <script>
    const comA = {
      template: `
      <div>
        <p>我是子组件</p>
        <button v-show="isShow"></button>
      </div>`,
      // 在这边 button是不会显示的,因为在子组件作用域之中 isShow为false
      data() {
        return {
          isShow: false
        }
      }
    }

    const vm = new Vue({
      el: "#app",
      data: {
        isShow: true
      },
      components: {
        comA
      }
    })
  </script>

作用域插槽 之旧版本

  • 子组件向父组件传值,但是父组件想要根据需求,展示自己的样式,那么就需要作用域插槽来实现数据的传递和修改!
  <div id="app">
    <com-a></com-a>
    <!-- 根据需要 就子组件展示的内容 需要作出调整的时候,那么需要使用要作用域插槽了! -->
    <com-a>
      <!-- 使用template 来获取子组件的数据 slot-scope来拿去slot插槽 slot.data => slot自定义属性的数据-->
      <template slot-scope="slot">
        <!-- 遍历插槽slot自定义的属性 里面含有数据! -->
        <span v-for="item in slot.data.join('-')">{{item}}</span>
      </template>
    </com-a>

    <com-a>
      <!-- 使用template 来获取子组件的数据 slot-scope来拿去slot插槽 slot.data => slot自定义属性的数据-->
      <template slot-scope="slot">
        <span v-for="item in slot.data.join('*')">{{item}}</span>
      </template>
    </com-a>
  </div>

  <script src="../vue.js"></script>
  <script>
    const comA = {
      // 子组件 自定义属性 向父组件传递数据
      template: `
      <div>
        <slot :data="dataList">
          <ul>
            <li v-for="item in dataList">{{item}}</li>
          </ul>
        </slot>
      </div>`,
      data() {
        return {
          dataList: ["ppp", "www", "ccc", "aaa"]
        }
      }
    }

    const vm = new Vue({
      el: "#app",
      data: {
        isShow: true
      },
      components: {
        comA
      }
    })
  </script>

插槽 之新版本

  • 官网:https://cn.vuejs.org/v2/guide/components-slots.html

默认插槽

  <div id="app">
    <com-a></com-a>
    <com-a>
      <template v-slot:default>
        我要替换!
      </template>
    </com-a>
  <!-- 输出的是  
    我是默认插槽
    我要替换!-->
  </div>

  <script src="../vue.js"></script>
  <script>
    const comA = {
      // 子组件 自定义属性 向父组件传递数据
      template: `
      <div>
        <slot>
          我是默认插槽
        </slot>
      </div>`,
    }

    const vm = new Vue({
      el: "#app",
      data: {
        isShow: true
      },
      components: {
        comA
      }
    })
  </script>

具名插槽

  <div id="app">
    <com-a></com-a>
    <com-a>
      <template v-slot:left>
        我要替换左侧!
      </template>
    </com-a>
    <com-a>
      <template v-slot:right>
        我要替换右侧!
      </template>
    </com-a>
    <!-- 结果:
  左侧 中间 右侧
  我要替换左侧! 中间 右侧
  左侧 中间 我要替换右侧! -->
  </div>

  <script src="../vue.js"></script>
  <script>
    const comA = {
      // 子组件 自定义属性 向父组件传递数据
      template: `
      <div>
        <slot name="left">
          左侧
        </slot>
        <slot name="center">
          中间
        </slot>
        <slot name="right">
          右侧
        </slot>
      </div>`,
    }

    const vm = new Vue({
      el: "#app",
      data: {
      },
      components: {
        comA
      }
    })
  </script>

作用域插槽

  <div id="app">
    <com-a></com-a>
    <com-a>
      <template v-slot:coma="slotProps">
        <span v-for="item in slotProps.dataList.join(' - ')">{{item}}</span>
      </template>
    </com-a>

    <com-a>
      <!-- 定义一个作用域插槽 从coma组件拿数据 后面的slotProps 随意定义 只不过 通过这个slotProps 来拿到子组件的数据! -->
      <template v-slot:coma="slotProps">
        <span v-for="item in slotProps.dataList.join(' * ')">{{item}}</span>
      </template>
    </com-a>
  </div>

  <script src="../vue.js"></script>
  <script>
    const comA = {
      // 子组件 自定义属性 向父组件传递数据 需要定义好这个子组件的name属性 便于从这个组件拿到数据 
      template: `
      <div>
      <slot name="coma" :dataList="dataList">
        <ul>
          <li v-for="item in dataList">{{ item }} </li>
        </ul>
      </slot>
      </div>`,
      data() {
        return {
          dataList: ["ppp", "www", "ccc", "aaa"]
        }
      }
    }

    const vm = new Vue({
      el: "#app",
      data: {
        isShow: true
      },
      components: {
        comA
      }
    })
  </script>
相关标签: vue系列