VUE学习三:双向绑定指令(v-mode)、组件化开发(全局组件/局部组卷/组件通信)、组件化高级(slot插槽使用)

简介: 这篇文章是关于Vue.js框架中的v-model指令和组件化开发的详细教程,涵盖了从基础使用到高级功能的多个方面。

导言

  1. let、const和var的区别(涉及块级作用域)
  2. JavaScript 中双引号、单引号和反引号的区别

一、01-v-model使用

1. 01-v-model的基本使用.html

v-mode指令 大多用在表单上进行双向绑定

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <input type="text" v-model="message">
  {
  {message}}
</div>

<script src="../../lib/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    }
  })
</script>

</body>
</html>

在这里插入图片描述

2. 02-v-model的原理.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <h1>v-model: 双向绑定</h1>
  <input type="text" v-model="message"><br>
  <h1>v-bind: 单向绑定,data数据传递到页面。  input事件: 监听用户输入的数据传递到data中</h1>
  <input type="text" :value="message" @input="valueChange"><br>
  <input type="text" :value="message" @input="message = $event.target.value">
  <h2>{
  {message}}</h2>
</div>

<script src="../../lib/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    methods: {
      valueChange(event) {
        // event 不需要传参,会自动传值
        console.log(event)
        // event.target.value 表单中的输入值
        this.message = event.target.value;
      }
    }
  })
</script>

</body>
</html>

在这里插入图片描述

3. 03-v-model结合radio类型.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <label for="male">
    <!--input表单 里面 有一个 name 属性,表单提交时,name 就是一个 key-->
    <input type="radio" id="male" value="男" v-model="sex">男
  </label>
  <label for="female">
    <input type="radio" id="female" value="女" v-model="sex">女
  </label>
  <h2>您选择的性别是: {
  {sex}}</h2>
</div>

<script src="../../lib/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊',
      sex: '女'
    }
  })
</script>

</body>
</html>

在这里插入图片描述

4. 04-v-model结合checkbox类型.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <h1>1.checkbox单选框: 对应 Boolean类型</h1>
  <label for="agree">
    <input type="checkbox" id="agree" v-model="isAgree">同意协议
  </label>
  <h5>您选择的是: {
  {isAgree}}</h5>
  <button :disabled="!isAgree">下一步</button>

  <h1>2.checkbox多选框: 对应 数组类型</h1>
  <input type="checkbox" value="篮球" v-model="hobbies">篮球
  <input type="checkbox" value="足球" v-model="hobbies">足球
  <input type="checkbox" value="乒乓球" v-model="hobbies">乒乓球
  <input type="checkbox" value="羽毛球" v-model="hobbies">羽毛球
  <h5>您的爱好是: {
  {hobbies}}</h5>

  <h5>值绑定: 从data 中获取数据进行 展示</h5>
  <label v-for="item in originHobbies" :for="item">
    <input type="checkbox" :value="item" :id="item" v-model="hobbies">{
  {item}}
  </label>
</div>

<script src="../../lib/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊',
      isAgree: false, // 单选框
      hobbies: [], // 多选框,
      originHobbies: ['篮球', '足球', '乒乓球', '羽毛球', '台球', '高尔夫球']
    }
  })
</script>

</body>
</html>

在这里插入图片描述

5. 05-v-model结合select类型.html(下拉多选有问题)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <h1>1.选择一个:字符串类型</h1>
  <select name="abc" v-model="fruit">
    <option value="苹果">苹果</option>
    <option value="香蕉">香蕉</option>
    <option value="榴莲">榴莲</option>
    <option value="葡萄">葡萄</option>
  </select>
  <h4>您选择的水果是: {
  {fruit}}</h4>

  <h1>2.选择多个:数组类型</h1>
  <select name="abc" v-model="fruits" multiple size="3">
    <option value="苹果">苹果</option>
    <option value="香蕉">香蕉</option>
    <option value="榴莲">榴莲</option>
    <option value="葡萄">葡萄</option>
    <option value="橘子">橘子</option>
  </select>
  <h4>您选择的水果是: {
  {fruits}}</h4>
</div>

<script src="../../lib/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊',
      fruit: '香蕉',
      fruits: []
    }
  })
</script>

</body>
</html>

在这里插入图片描述

6. 06-v-model修饰符的使用.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <h1>1.修饰符: lazy: 点击回车的时候 会进行 实时绑定</h1>
  <input type="text" v-model.lazy="message">
  <h2>{
  {message}}</h2>

  <h1>2.修饰符: number: v-model默认绑定为 string类型, number改变类型</h1>
  <input type="number" v-model.number="age">
  <h2>{
  {age}}-{
  {typeof age}}</h2>

  <h1>3.修饰符: trim :去掉表单中输入的两边的空格</h1>
  <input type="text" v-model.trim="name">
  <h2>您输入的名字:{
  {name}}</h2>
</div>

<script src="../../lib/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊',
      age: 0,
      name: ''
    }
  })

  var age = 0
  age = '1111'
  age = '222'
</script>

</body>
</html>

在这里插入图片描述

二、02-组件化开发

1. 01-组件化的基本使用.html

  1. 创建组件构造器对象 Vue.extend({})
  2. 注册(全局)组件:Vue.component('my-cpn', cpnC)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>01-组件化的基本使用</title>
</head>
<body>

<div id="app">
  <!--3.使用组件-->
  <my-cpn></my-cpn>
  <my-cpn></my-cpn>

  <div>
    <div>
      <my-cpn></my-cpn>
    </div>
  </div>
</div>

<my-cpn></my-cpn>

<script src="../../lib/vue.js"></script>
<script>

  // ES6语法:定义字符串的 单引号、双引号  和 `` 的区别
  const a = '12' +
          '34';
  const b = `we
            qw`;

  // 1.创建组件构造器对象
  const cpnC = Vue.extend({
    template: `
      <div>
        <h2>我是标题</h2>
        <p>我是内容, 哈哈哈哈</p>
        <p>我是内容, 呵呵呵呵</p>
      </div>`
  })

  // 2.注册组件
  Vue.component('my-cpn', cpnC)

  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    }
  })
</script>

</body>
</html>

在这里插入图片描述

2. 02-全局组件和局部组件.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>02-全局组件和局部组件</title>
</head>
<body>

<div id="app">
  <cpna></cpna>
  <cpnb></cpnb>
</div>

<hr>
<!--下面的不显示,说明 局部组件 只能使用在挂载的地方-->
<h1>下面的不显示,说明 局部组件 只能使用在挂载的地方</h1>
<div id="app2">
  <cpna></cpna>
</div>

<script src="../../lib/vue.js"></script>
<script>
  // 1.创建局部组件构造器
  const cpna = Vue.extend({
    template: `
      <div>
        <h2>我是标题a: 局部组件</h2>
        <p>我是内容a,哈哈哈哈啊</p>
      </div>
    `
  })

  // 2. 全局组件
  const cpnb = Vue.extend({
    template: `
      <div>
        <h2>我是标题b: 全局组件</h2>
        <p>我是内容,哈哈哈哈啊</p>
      </div>
    `
  })

  // 3.注册组件(全局组件, 意味着可以在多个Vue的实例下面使用)
  Vue.component('cpnb', cpnb)

  // 疑问: 怎么注册的组件才是局部组件了?

  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    // 局部组件定义的位置
    components: {
      // cpnA 使用组件时的标签名
      cpna: cpna
    }
  })

  const app2 = new Vue({
    el: '#app2'
  })
</script>

</body>
</html>

在这里插入图片描述

3. 03-父组件和子组件.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>03-父组件和子组件</title>
</head>
<body>

<div id="app">
  <cpn2></cpn2>
  <!-- <cpn1></cpn1> -->
</div>

<script src="../../lib/vue.js"></script>
<script>
  // 1.创建第一个组件构造器(子组件)
  const cpnC1 = Vue.extend({
    template: `
      <div>
        <h2>我是标题1: 子组件</h2>
        <p>我是内容, 哈哈哈哈</p>
      </div>
    `
  })

  // 2.创建第二个组件构造器(父组件)
  const cpnC2 = Vue.extend({
    template: `
      <div>
        <h2>我是标题2: 父组件</h2>
        <p>我是内容, 呵呵呵呵</p>
        <cpn1></cpn1>
      </div>
    `,
    components: {
      cpn1: cpnC1
    }
  })

  // root组件
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    components: {
      cpn2: cpnC2
    }
  })
</script>

</body>
</html>

在这里插入图片描述

4. 04-组件(全局和局部)的语法糖注册方式.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>04-组件的语法糖注册方式</title>
</head>
<body>

<div id="app">
  <cpn1></cpn1>
  <cpn2></cpn2>
</div>

<script src="../../lib/vue.js"></script>
<script>
  // 1.全局组件注册的语法糖
  // 1.创建组件构造器
  // const cpn1 = Vue.extend({
  //   template: `
  //     <div>
  //       <h2>我是标题1</h2>
  //       <p>我是内容, 哈哈哈哈</p>
  //     </div>
  //   `
  // })

  // 2.注册全局组件
  Vue.component('cpn1', {
    template: `
      <div>
        <h2>我是标题1: 全局组件</h2>
        <p>我是内容, 哈哈哈哈</p>
      </div>
    `
  })

  // 2.注册局部组件的语法糖
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    components: {
      'cpn2': {
        template: `
          <div>
            <h2>我是标题2: 局部组件</h2>
            <p>我是内容, 呵呵呵</p>
          </div>
    `
      }
    }
  })
</script>

</body>
</html>

在这里插入图片描述

5. 05-组件模板的分离写法.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>05-组件模板的分离写法</title>
</head>
<body>

<div id="app">
  <cpn1></cpn1>
  <cpn2></cpn2>
</div>

<!--1.方式1: script标签, 注意:类型必须是text/x-template-->
<script type="text/x-template" id="cpn1">
<div>
  <h2>我是标题: script标签 创建的模版-全局组件</h2>
  <p>我是内容,哈哈哈</p>
</div>
</script>

<!--1.方式2: template标签-->
<template id="cpn2">
  <div>
    <h2>我是标题: template标签 创建的模版-全局组件</h2>
    <p>我是内容,呵呵呵</p>
  </div>
</template>

<script src="../../lib/vue.js"></script>
<script>

  // 2.注册一个全局组件
  Vue.component('cpn1', {
    template: '#cpn1'
  })
  Vue.component('cpn2', {
    template: '#cpn2'
  })

  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    }
  })
</script>

</body>
</html>

在这里插入图片描述

6. 06-组件中的数据存放问题.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>06-组件中的数据存放问题</title>
</head>
<body>

<div id="app">
  <cpn></cpn>
  <cpn></cpn>
</div>

<!--2.template标签-->
<template id="cpn">
  <div>
    <h2>{
  {title}}</h2>
    <p>我是全局组件 模版中的数据,呵呵呵</p>
  </div>
</template>

<script src="../../lib/vue.js"></script>
<script>

  // 1.注册一个全局组件
  Vue.component('cpn', {
    template: '#cpn',
    data() {
      return {
        title: 'abc'
      }
    }
  })

  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊',
      // title: '我是标题'
    }
  })
</script>

</body>
</html>

在这里插入图片描述

7. 07-组件中的data为什么是函数.html

  • 为什么data在组件中必须是一个函数呢?
    1. 首先,如果不是一个函数,Vue直接就会报错。
    2. 其次,原因是在于Vue让每个组件对象都返回一个新的对象,因为如果是同一个对象的,组件在多次使用后会相互影响。
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>07-组件中的data为什么是函数</title>
</head>
<body>

<!--组件实例对象-->
<div id="app">
  <cpn></cpn>
</div>

<template id="cpn">
  <div>
    <h2>全局组件-模版中-当前计数: {
  {counter}}</h2>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
  </div>
</template>
<script src="../../lib/vue.js"></script>
<script>
  // 1.注册组件
  const obj = {
    counter: 0
  }
  /*
  * 为什么data在组件中必须是一个函数呢?
  * 1. 首先,如果不是一个函数,Vue直接就会报错。
  * 2. 其次,原因是在于Vue让每个组件对象都返回一个新的对象,因为如果是同一个对象的,组件在多次使用后会相互影响。
  * */
  Vue.component('cpn', {
    template: '#cpn',
    // data() {
    //   return {
    //     counter: 0
    //   }
    // },
    data() {
      return obj
    },
    methods: {
      increment() {
        this.counter++
      },
      decrement() {
        this.counter--
      }
    }
  })

  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    }
  })
</script>

<script>
  // const obj = {
  //   name: 'why',
  //   age: 18
  // }
  //
  // function abc() {
  //   return obj
  // }
  //
  // let obj1 = abc()
  // let obj2 = abc()
  // let obj3 = abc()
  //
  // obj1.name = 'kobe'
  // console.log(obj2);
  // console.log(obj3);

</script>

</body>
</html>

在这里插入图片描述

8. 08-组件通信-父组件向子组件传递数据.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>08-组件通信-父组件向子组件传递数据</title>
</head>
<body>

<div id="app">
  <h1>正确写法, 使用第一种 props写法: 使用 v-bind 进行传值</h1>
  <cpn v-bind:cmessage="message" :cmovies="movies"></cpn>

  <h1>如果不加 v-bind, 下面这个会将 message、movies 作为 字符串传递给 cmessage、movies 属性</h1>
  <cpn cmessage="message" cmovies="movies" ></cpn>

  <h1>正确写法, 使用第二种 props写法, cmessage 没传值, 使用的是默认值</h1>
  <cpn v-bind:cmovies="movies"></cpn>

</div>

<template id="cpn">
  <div>
    <ul>
      <li v-for="item in cmovies">{
  {item}}</li>
    </ul>
    <h2>{
  {cmessage}}</h2>
  </div>
</template>

<script src="../../lib/vue.js"></script>
<script>
  // 父传子: props: properties
  const cpn = {
    template: '#cpn',
    // 第一种写法
    // props: ['cmovies', 'cmessage'],
    // 第二种写法
    props: {
      // 1.类型限制
      // cmovies: Array,
      // cmessage: String,

      // 2.提供一些默认值, 以及必传值
      cmessage: {
        type: String,
        default: 'aaaaaaaa',
        required: true  // 为true时,必须要传,不传则报错
      },
      // 类型是对象或者数组时, 默认值必须是一个函数
      cmovies: {
        type: Array,
        default() {
          return []
        }
      }
    },
    data() {
      return {}
    },
    methods: {

    }
  }

  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊',
      movies: ['海王', '海贼王', '海尔兄弟']
    },
    components: {
      cpn
    }
  })
</script>

</body>
</html>

在这里插入图片描述

9. 09-组件通信-父传子(props中的驼峰标识).html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>09-组件通信-父传子(props中的驼峰标识)</title>
</head>
<body>

<div id="app">
  <cpn :c-info="info" :child-my-message="message" ></cpn>
</div>

<template id="cpn">
  <div>
    <h2>{
  {cInfo}}</h2>
    <h2>{
  {childMyMessage}}</h2>
  </div>
</template>

<script src="../../lib/vue.js"></script>
<script>
  const cpn = {
    template: '#cpn',
    props: {
      cInfo: {
        type: Object,
        default() {
          return {}
        }
      },
      childMyMessage: {
        type: String,
        default: ''
      }
    }
  }

  const app = new Vue({
    el: '#app',
    data: {
      info: {
        name: 'why',
        age: 18,
        height: 1.88
      },
      message: 'aaaaaa'
    },
    components: {
      cpn
    }
  })
</script>

</body>
</html>

在这里插入图片描述

10. 10-组件通信-子传父(自定义事件).html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>10-组件通信-子传父(自定义事件)</title>
</head>
<body>

<!--父组件模板-->
<div id="app">
  <!--@item-click="cpnClick" 这里不用写参数-->
  <cpn @item-click="cpnClick"></cpn>
</div>

<!--子组件模板-->
<template id="cpn">
  <div>
    <button v-for="item in categories"
            @click="btnClick(item)">
      {
  {item.name}}
    </button>
  </div>
</template>

<script src="../../lib/vue.js"></script>
<script>

  /*
  * 1.子组件
  * */
  const cpn = {
    template: '#cpn',
    data() {
      return {
        categories: [
          {id: 'aaa', name: '热门推荐'},
          {id: 'bbb', name: '手机数码'},
          {id: 'ccc', name: '家用家电'},
          {id: 'ddd', name: '电脑办公'},
        ]
      }
    },
    methods: {
      btnClick(item) {
        console.log(item);
        // 发射事件: 自定义事件, item:为参数, item-click:事件名称
        this.$emit('item-click', item)
      }
    }
  }

  /*
  * 2.父组件
  * */
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    components: {
      cpn
    },
    methods: {
      cpnClick(item) {
        console.log('cpnClick', item);
      }
    }
  })
</script>

</body>
</html>

在这里插入图片描述

11. 11-组件通信-父子组件通信案例(props实现).html

在这里插入图片描述

12. 12-组件通信-父子组件通信案例(watch实现).html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>12-组件通信-父子组件通信案例(watch实现)</title>
</head>
<body>

<div id="app">
  <cpn :number1="num1"
       :number2="num2"
       @num1change="num1change"
       @num2change="num2change"/>
</div>

<template id="cpn">
  <div>
    <h2>props:{
  {number1}}</h2>
    <h2>data:{
  {dnumber1}}</h2>
    <input type="text" v-model="dnumber1">
    <h2>props:{
  {number2}}</h2>
    <h2>data:{
  {dnumber2}}</h2>
    <input type="text" v-model="dnumber2">
  </div>
</template>

<script src="../../lib/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      num1: 1,
      num2: 0
    },
    methods: {
      num1change(value) {
        this.num1 = parseFloat(value)
      },
      num2change(value) {
        this.num2 = parseFloat(value)
      }
    },
    components: {
      cpn: {
        template: '#cpn',
        props: {
          number1: Number,
          number2: Number,
          name: ''
        },
        data() {
          return {
            dnumber1: this.number1,
            dnumber2: this.number2
          }
        },
        watch: {
          dnumber1(newValue) {
            this.dnumber2 = newValue * 100;
            this.$emit('num1change', newValue);
          },
          dnumber2(newValue) {
            this.number1 = newValue / 100;
            this.$emit('num2change', newValue);
          }
        }
      }
    }
  })
</script>

</body>
</html>

13. 13-组件访问-父访问子-$children-$refs.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>13-组件访问-父访问子-children-refs</title>
</head>

<body>

  <div id="app">
    <cpn></cpn>
    <cpn ref="aaa"></cpn>
    <button @click="btnClink">按钮</button>
  </div>

  <template id="cpn">
    <div>
      <span>我是一个演员</span>
    </div>
  </template>

  <script src="../../lib/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {},
      methods: {
        btnClink() {
          // 父组件  访问 子组件

          /*
          * 1. $children
          * */
          console.log('this:', this)
          console.log('this.$children:', this.$children)
          console.log('-------------------')
          this.$children[0].showMessage();
          for (let c of this.$children) {
            console.log('c.name: ', c.name)
            c.showMessage()
          }
          this.$children[1].name; // 这样可以指定某个组件对象,但是不固定,所以这样不好

          /*
          * 2. $ref => 对象类型,默认是一个空的对象 ref='bbb
          * */
          console.log(this.$refs.aaa.name)
        }
      },
      components: {
        cpn: {
          template: '#cpn',
          props: {},
          data() {
            return {
              name: '我是子组件的 name'
            }
          },
          methods: {
            showMessage() {
              console.log('子组件方法-showMessage');
            }
          }
        }
      }
    })
  </script>

</body>

</html>

在这里插入图片描述

14. 14-组件访问-子访问父-$parent-$root.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>14-组件访问-子访问父-parent-root</title>
</head>
<body>

<div id="app">
  <cpn></cpn>
</div>

<template id="cpn">
  <div>
    <h2>我是cpn组件</h2>
    <ccpn></ccpn>
  </div>
</template>

<template id="ccpn">
  <div>
    <h2>我是ccpn组件</h2>
    <button @click="btnClick">按钮</button>
  </div>
</template>

<script src="../../lib/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    components: {
      cpn: {
        template: '#cpn',
        data(){
          return {
            name: '我是ccpn组件的 name'
          }
        },
        methods: {
          btnClink(){
            console.log('btnClink');
          }
        },
        components: {
          ccpn: {
            template: '#ccpn',
            methods: {
              btnClick(){
                // 1. 访问父组件 $parent
                console.log('this.$parent: ', this.$parent);
                console.log('this.$parent.name: ', this.$parent.name);
                console.log('------------------------');


                // 2. 访问根组件$root
                console.log('this: ', this);
                console.log('this.$root: ', this.$root);
                console.log('this.$root.message: ', this.$root.message);
              }
            }
          }
        }
      }
    }
  })
</script>

</body>
</html>

在这里插入图片描述

三、03-组件化高级

1. 01-slot-插槽的基本使用.html

  1. 插槽的基本使用
  2. 插槽的默认值 button
    3.如果有多个值, 同时放入到组件进行替换时, 一起作为替换元素
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>01-slot-插槽的基本使用</title>
</head>
<body>

<!--
1.插槽的基本使用 <slot></slot>
2.插槽的默认值 <slot>button</slot>
3.如果有多个值, 同时放入到组件进行替换时, 一起作为替换元素
-->

<div id="app">
  <cpn></cpn>
  <hr>

  <cpn><span>我是传过来的:哈哈哈</span></cpn>
  <hr>

  <cpn><i>我是传过来的:呵呵呵</i></cpn>
  <hr>

  <cpn>
    <i>我是传过来的:呵呵呵</i>
    <div>div元素</div>
    <p>p元素</p>
  </cpn>
  <hr>
</div>

<template id="cpn">
  <div>
    <h2>我是组件</h2>
    <p>我是组件, 哈哈哈</p>
    <slot><button>按钮</button></slot>
    <!--<button>按钮</button>-->
  </div>
</template>

<script src="../../lib/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    components: {
      cpn: {
        template: '#cpn'
      }
    }
  })
</script>

</body>
</html>

在这里插入图片描述

2. 02-slot-具名插槽的使用.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>02-slot-具名插槽的使用</title>
</head>
<body>

<div id="app">
  <cpn><span slot="center">center</span></cpn>
  <hr>
  <cpn><button slot="left">left</button></cpn>
</div>

<template id="cpn">
  <div>
    <slot name="left"><span>左边</span></slot>
    <slot name="center"><span>中间</span></slot>
    <slot name="right"><span>右边</span></slot>
  </div>
</template>

<script src="../../lib/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    components: {
      cpn: {
        template: '#cpn'
      }
    }
  })
</script>

</body>
</html>

在这里插入图片描述

3. 03-什么是编译的作用域.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>03-什么是编译的作用域</title>
</head>
<body>

<!--
这里是 vue 实例的数据
-->
<div id="app">
  <cpn v-show="isShow"></cpn>
  <hr>
  <cpn v-for="item in names"></cpn>
</div>

<!--
这里是 子组件 对象的数据
-->
<template id="cpn">
  <div>
    <h2>我是子组件</h2>
    <p>我是内容, 哈哈哈</p>
    <button v-show="isShow">按钮</button>
  </div>
</template>

<script src="../../lib/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊',
      isShow: true
    },
    components: {
      cpn: {
        template: '#cpn',
        data() {
          return {
            isShow: false,
            names: [1, 2, 3, 4]
          }
        }
      },
    }
  })
</script>

</body>
</html>

4. 04-作用域插槽的案例.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>04-作用域插槽的案例</title>
</head>
<body>
<!--
插槽的作用:当子组件的渲染方式,父组件不满意时,通过作用域 拿到子组件插槽中的数据,进行修改
-->
<div id="app">
  <cpn></cpn>

  <cpn>
    <!--目的是获取子组件中的pLanguages
    vue 2.5以下版本 必须使用 template标签,以上的版本也可以使用div标签-->
     <template slot-scope="slot">
      <!--<span v-for="item in slot.data"> - {
  {item}}</span>-->
       <!--join():数组方法,数组之间以什么进行衔接-->
      <span>{
  {slot.data.join(' - ')}}</span>
    </template>
  </cpn>

  <cpn>
    <!--目的是获取子组件中的pLanguages-->
    <template slot-scope="slot">
      <!--<span v-for="item in slot.data">{
  {item}} * </span>-->
      <span>{
  {slot.data.join(' * ')}}</span>
    </template>
  </cpn>
  <!--<cpn></cpn>-->
</div>

<template id="cpn">
  <div>
    <slot :data="pLanguages">
      <ul>
        <li v-for="item in pLanguages">{
  {item}}</li>
      </ul>
    </slot>
  </div>
</template>

<script src="../../lib/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    components: {
      cpn: {
        template: '#cpn',
        data() {
          return {
            pLanguages: ['JavaScript', 'C++', 'Java', 'C#', 'Python', 'Go', 'Swift']
          }
        }
      }
    }
  })
</script>

</body>
</html>

在这里插入图片描述

相关文章
|
2月前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
167 64
|
6天前
|
存储 设计模式 JavaScript
Vue 组件化开发:构建高质量应用的核心
本文深入探讨了 Vue.js 组件化开发的核心概念与最佳实践。
38 1
|
2月前
|
JavaScript API 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
2月前
|
JavaScript 前端开发 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
2月前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
64 8
|
2月前
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。
|
2月前
|
存储 JavaScript 开发者
Vue 组件间通信的最佳实践
本文总结了 Vue.js 中组件间通信的多种方法,包括 props、事件、Vuex 状态管理等,帮助开发者选择最适合项目需求的通信方式,提高开发效率和代码可维护性。
|
JavaScript
初识 Vue(19)---(Vue 中使用插槽(slot))
Vue 中使用插槽(slot) 案例:子组件中的一部分内容是根据父组件传递来的 DOM 来进行显示 Vue 中使用插槽(slot) Vue.
1267 0
|
26天前
|
JavaScript
vue使用iconfont图标
vue使用iconfont图标
127 1
|
5天前
|
JavaScript 安全 API
iframe嵌入页面实现免登录思路(以vue为例)
通过上述步骤,可以在Vue.js项目中通过 `iframe`实现不同应用间的免登录功能。利用Token传递和消息传递机制,可以确保安全、高效地在主应用和子应用间共享登录状态。这种方法在实际项目中具有广泛的应用前景,能够显著提升用户体验。
31 8