Vue 夫向子传递 子向父 平辈传递 ref属性 is属性 vue使用swiper轮播图 插槽
1-父组件向子组件通信
1.1-步骤
自定属性的方式实现数据传递
- 
父组件中:
在子组件的调用标签上, 通过v-bind动态设置一个自定义属性,将父组件中需要传递的数据赋值给自定义属性
<!-- 父向子: 第一步 --> <List v-bind:dataList="list"/> - 
子组件中:
在子组件的配置对象中通过props属性节点来接收父组件通过自定义属性传递过来的数据
export default { // 父向子: 第二步(数组元素需要和自定义属性的名称保持一致) props:['dataList'], data(){ return { // 控制添加模态框的显示状态 isAdd:false } }, methods:{ } }; 
1.2-对props数据的类型进行校验
- 数据类型可选值: 
String/Number/Boolean/Undefined/Null/Array/Object 
- 
写法1
export default { // 实现对props数据进行类型校验 props: { isAdd:Boolean } } - 
写法2
export default { props: { // 数据类型:[默认值] msg: [String, Number] } } - 
写法3
export default { props: { dataList: { // 数据类型 type: Array, // 如果是对象或者数组, 建议使用函数的方式返回默认值 default() { return [ { id: 4, title: "新添加", content: "新添加内容" } ]; } }, msg:{ // 数据类型 type:String, // 默认值 default:'你好' } } } 
1.3-props数据和data数据的区别
- props数据
- props来自外部的数据
 - 如果props数据类型是基本数据类型(String,Number,Boolean), 那么不能重写
 - 如果props数据类型是引用数据类型(Array,Object), 那么可以重写
 
 - data数据
- data数据是组件内部的数据
 - data数据可读可写
 
 
1.4-注意事项
 1. props数据的名字不要和data同名
2-子组件向父组件通信
- 通过自定义事件的方式实现子组件向父组件传递数据
 
2.1-步骤
- 
父组件中:
在子组件的调用标签上通过v-on绑定一个自定义事件, 然后在父组件中的methods中定义一个方法, 充当自定义事件的处理函数
<!-- 注册自定义事件 --> <List v-bind:dataList="list" :msg="'hello'" @del="del"/>del(id){ // console.log(id,'index.vue'); // 1-通过id查找索引 const index=this.list.findIndex(item=>item.id===id); // 通过splice方法删除数据元素 this.list.splice(index,1); } - 
在子组件中:
通过this.$emit('自定义事件的名称','需要传递数据')触发自定义事件
// 删除按钮的点击事件处理函数 del(id){ // 2-触发自定义事件, 并且传递数据 this.$emit('del',id); } 
3-非父子组件之间通信
- 通过自定义事件实现非父子组件的数据通信
 
实现步骤
- 
创建一个空的vue实例对象
vm, 充当事件中心的角色/utils/vm.js
// 1-导入vue import Vue from 'vue'; // 创建一个空的vue实例, 充当事件中心的角色 export default new Vue(); - 
在A组件中通过事件中心
vm.$emit()触发自定义事件/pages/list.vue
// 编辑按钮的事件处理函数 edit(row){ // 显示alert组件 this.$emit('updateIsAdd',true); // 1-通过自定义事件传递待编辑的数据 vm.$emit('contentUpdate',row); } - 
在B组件中通过事件中心
vm.$on()监听自定义事件的执行/pages/alert.vue
created(){ // 2-监听自定义事件 // vm.$on('自定义事件名称',事件处理函数); vm.$on('contentUpdate',(obj)=>{ // 更新表单数据模型 this.formData=obj; }) } 
4-ref属性
- 
虚拟DOM: 特殊的对象
const h1={ name:'h1', attributes:{ title:'属性值', style:{ color:'red' }, className:'.container' }, children:[ 'h1的内容' ] } const div={ name:'div', attributes:{ title:'属性值', style:{ color:'red', fontSize:'20px' }, className:'.container' }, children:[ '文本内容', h1 ] } - 
作用: 帮我们间接操作标签对象或者组件对象
 
4.1-ref属性操作标签
- 
在目标元素(标签/组件)添加一个ref属性, ref属性的值必须保证唯一不重复
<h1 ref="h1">{{msg}}</h1> - 
在逻辑层通过
this.$refs.ref属性名获取标签的虚拟dom对象或者组件对象this.$refs.h1.style.color='red'; this.$refs.h1.style.border='1px solid red'; this.$refs.h1.style.backgroundColor='yellow'; 
4.2-ref属性操作组件
- 
在组件调用标签上添加一个
ref属性, 保证ref属性值的唯一性<Box1 ref="box1"/> - 
在逻辑层通过
this.$refs.ref属性名获取组件对象// 组件对象 console.log(this.$refs.box1); // 获取组件内部的数据 console.log(this.$refs.box1.msg); // 调用组件内部的方法 this.$refs.box1.setMsg('更新过的msg'); // 修改组件的视图(操作组件视图的虚拟dom必须通过$el属性) this.$refs.box1.$el.style.backgroundColor='green'; 
5-is属性
- 作用: 接收组件名称
 - 使用范围
- component动态组件
 - 普通html标签
 
 
6-vue项目中引入jquery
6.1-下载安装
npm i jquery -S
6.2-使用
import $ from 'jquery'
7-vue中使用swiper轮播图插件
7.1-下载安装
npm i swiper@3.4.2 -S
7.2-使用
- 
导入swiper核心js
import Swiper from 'swiper' - 
导入样式文件
import 'dist/css/swiper.min.css' - 
初始化
<div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide">Slide 1</div> <div class="swiper-slide">Slide 2</div> <div class="swiper-slide">Slide 3</div> </div> <!-- 如果需要分页器 --> <div class="swiper-pagination"></div> <!-- 如果需要导航按钮 --> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> </div>// 初始化 var swiper = new Swiper('.swiper-container', { pagination: '.swiper-pagination', paginationClickable: true, lopp:true, autoplay:1000 });.swiper-container { width: 100%; height: 100%; } 
8-插槽
- 插槽也是外部向组件内部传递数据的一种方式
 - 传递的是标签结构
 - 通过组件调用标签之间
 
8.1-匿名插槽
8.1.1-定义
<template>
  <div class="cmt-container">
      <h3>评论</h3>
      <hr>
      <!-- 占位 -->
      <slot></slot>  
  </div>
</template>
<script>
export default {}
</script>
<style scoped>
.cmt-container{
    width: 600px;
    height: 200px;
    margin:40px auto;
    line-height: 50px;
    padding:10px;
    background: lightyellow;
}
</style>
8.1.2-调用
 <Comment>
     <input type="text" placeholder="请输入评论内容" />
     <hr />
     <button>立即提交</button>
</Comment>
<hr />
<Comment>
    <div>
        <textarea placeholder="请输入评论内容" cols="30" rows="3"></textarea>
        <hr />
        <button>立即提交</button>
        <button>清空</button>
    </div>
</Comment>
8.2-具名插槽
8.2.1-定义
- slot: 充当占位符
 
<template>
  <div class="panel-container">
      <!-- 具名插槽 -->
      <slot name="header"></slot> 
      <div>
          <input type="text" placeholder="用户名"/>
      </div>
      <div>
          <input type="text" placeholder="密码"/>
      </div>
      <slot name="footer"></slot>  
  </div>
</template>
<script>
export default {}
</script>
<style>
.panel-container{
    width: 600px;
    height: 140px;
    margin:60px auto;
    background: lightyellow;
    padding:10px;
    line-height: 30px;
}
</style>
8.2.2-调用
- slot: 充当占位符
 
<Panel>
    <div slot="header">
        <h3>登录页面</h3>
    </div>
    <div slot="footer">
        <button>立即登录</button>
        <button>重置表单</button>
    </div>
</Panel>
8.3-作用域插槽
8.3.1-定义
- slot插槽组件的2个作用:
- 1-占位符
 - 2-分发数据
 
 
<template>
  <div class="list-container">
      <ul>
          <li v-for="item in list" :key="item.id">
              <!-- 
					slot插槽组件的2个作用: 1-占位 2-分发数据 
               -->
              <slot :row="item"></slot>
          </li>
      </ul>
  </div>
</template>
<script>
export default {
    data(){
        return {
            list:[
                {
                    id:3,
                    name:'vue'
                },
                {
                    id:2,
                    name:'react'
                },
                {
                    id:1,
                    name:'angular'
                }
            ]
        }
    }
}
</script>
<style>
.list-container{
    width: 400px;
    height: 200px;
    margin:20px auto;
    background: #EEE;
    
}
.list-container li{
    list-style: none;
    padding:10px;
    line-height: 30px;
    border-bottom:1px dashed #999;
}
.list-container li label{
    cursor: pointer
}
</style>
8.3.2-调用
- 
老写法:
slot-scope<List> <!--props为模板变量, 名字自己定义, 保存的是slot插槽组件上的自定义属性--> <!-- slot组件上的属性集合 --> <!-- slot-scope:老的写法 --> <template slot-scope="props"> <label> <input type="checkbox" />  {{props.row.id}}---{{props.row.name}} </label> </template> </List> - 
新写法:
v-slot<List> <!-- v-slot: 最新写法 --> <template v-slot="obj"> <label> <input type="radio" name="lang"/>  {{obj.row.id}}---{{obj.row.name}} </label> </template> </List> 
9-组件样式添加作用域
- 在组件内的
style标签之上添加一个scoped属性, 即可实现让组件内的选择器只对当前组件的视图生效, 而不会影响到其他组件 
<style scoped>
</style>
组件内样式添加作用域的原理
vue会生成一个随机的字符串, 如data-v-02e4c64b- 将
style标签内的选择器改写为交集选择器,如.container[data-v-02e4c64b] - 在调用选择器的标签上添加随机属性
<div class="container" data-v-02e4c64b></div> 

                
            
        
浙公网安备 33010602011771号