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>

在这里插入图片描述

相关文章
|
1天前
|
编解码 Java 程序员
写代码还有专业的编程显示器?
写代码已经十个年头了, 一直都是习惯直接用一台Mac电脑写代码 偶尔接一个显示器, 但是可能因为公司配的显示器不怎么样, 还要接转接头 搞得桌面杂乱无章,分辨率也低,感觉屏幕还是Mac自带的看着舒服
|
3天前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1540 5
|
1月前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
7天前
|
人工智能 Rust Java
10月更文挑战赛火热启动,坚持热爱坚持创作!
开发者社区10月更文挑战,寻找热爱技术内容创作的你,欢迎来创作!
577 22
|
3天前
|
存储 SQL 关系型数据库
彻底搞懂InnoDB的MVCC多版本并发控制
本文详细介绍了InnoDB存储引擎中的两种并发控制方法:MVCC(多版本并发控制)和LBCC(基于锁的并发控制)。MVCC通过记录版本信息和使用快照读取机制,实现了高并发下的读写操作,而LBCC则通过加锁机制控制并发访问。文章深入探讨了MVCC的工作原理,包括插入、删除、修改流程及查询过程中的快照读取机制。通过多个案例演示了不同隔离级别下MVCC的具体表现,并解释了事务ID的分配和管理方式。最后,对比了四种隔离级别的性能特点,帮助读者理解如何根据具体需求选择合适的隔离级别以优化数据库性能。
201 3
|
10天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
10天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
571 5
|
23天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
6天前
|
XML 安全 Java
【Maven】依赖管理,Maven仓库,Maven核心功能
【Maven】依赖管理,Maven仓库,Maven核心功能
233 3
|
9天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
327 2