vue的组件,通信,插槽及周小结

 
1:监听器:
{
  data:{
    msg:"",
    obj:{
      a:10,
      b:20
    }
  },
  watch:{
    msg(newVal,oldVal){
      // 只要 data中 msg 变化了,此函数自动触发
    },
    'obj.a'(newVal,oldVal){
       //  obj a属性值变化 触发
    },
    obj:{
      handler(newVal,oldVal){
        // 只要obj任意一个属性的值变化,都会触发
      },
      deep:true
    }
  }
}

2:计算属性
  使用一个值,需要处理一下才能使用
  {
    data:{
      msg:'hello world'
    },
    computed:{
      msg2(){
        return this.msg.split('').reverse().join('');
        // 简写  相当于只用get
      },
      msg3:{
        get(){
          return this.msg.split('').reverse().join('');
        },
        set(val){
          // 计算属性最好不要去修改
          // 如果要修改,计算属性,需要些 set,在set中去修改依赖
          this.msg = val;
        }
      }
    }
  } 

  3:ref:获取dom
  <div ref="box">

  //实例的 $refs属性是一个对象
  {
    box:div//dom对象
  }
  this.$refs['box']

 

组件:

页面的独立 的区域\
 
1:全局组件
      
let CommonHead = {
        template:`
          <div>


          </div>
        `
        data(){
          return {


          }
        },
        methods,
        watch,
        computed
      }
      Vue.component('组件名 推荐大驼峰或者 -',CommonHead)

 

2:局部组件
      
let CommonHead = {
        template:`
          <div>


          </div>
        `
        data(){
          return {


          }
        },
        methods,
        watch,
        computed,
        components:{
          组件名:{
            template,
            data,
            watch,
            ....
          }
        }
      }

 

## 组件间的关系
由于组件间的嵌套使用,组件互相有了关系 如:父子、兄弟...
 
## 不同组件之间的通信
 
1:父向子通信
 
  子组件中 新增props属性,属性值,时数组,数组中 放 待接收参数列表(定义参数名字)
  注意:
    1,props中定义的参数名会自动 编译成 实例(组件),属性(同data中的属性以及计算属性中的属性)
    2,props名字不能和data中以及methods和计算属性, 不能重名的
  // 子组件
    let CommonTitle = {
      props:['title','arr'],   //properties  props 父向子 传入的数据列表
      template:`
        <div>
            这是标题
          <h2>
            {{ title }}
          </h2>  
          <ul>
              <li v-for="item in arr" :key="item">
                  {{item}}
              </li>
          </ul>
        </div>
      `
    }
    // 父组件
    let Home = {
      template:`
        <div>
          <!--
            <common-title title="我是首页"></common-title>  
          -->
          <common-title :title="title" :arr="0"></common-title>  
          home页内容  
        </div>
      `,
      data(){
        return {
          title:"我是home页111"
        }
      },
      components:{
        CommonTitle
      }
    }
    总结:
      props值是一个数组
 
    问题?
        没有限制 props 传入的数据类型 (存在风险)
 
props验证
对于props类型做了验证
 
  type
  required
  default
 props:{
    propa:String, //只验证type(类型)可以直接写类型预定义的值
    propb:[String,Number] //type是多个类型中的一个  []
    propc:{
      type:String,
      required:true
    },
    propd:{
      type:String,
      default:'xxx'
    }
  }

 

 

注意:
     1,props中定义的参数名会自动 编译成 实例(组件),属性(同data中的属性以及计算属性中的属性)
     2,props名字不能和data中以及methods和计算属性, 不能重名的
     3,如果默认值是 数组或者对象,需要一个函数返回这个默认值
     4,props能否被改变 props保持 单向的  父向子 (子不能改变),易于维护
 
  type的值:
  String
  Number
  Boolean
  Array
  Object
  Date
  Function
  Symbol
 
2:子向父通信
自定义事件 触发 
 
  子组件中
    this.$emit("自定义事件名",携带参数)
  在父组件中
    <子组件 
      @自定义事件="fn"
    ></子组件>
   {
      methods:{
        fn(msg){ //msg 携带数据
          // 当子组件的  $emit触发时 自动调用
        }
      }
    }

 

3:兄弟组件传参

事件总线
Vue实例
  $emit("自定义事件",携带参数)

 

  $on("监听的事件名",fn)
注意:
             谁emit就由谁on监听
利用第三方实例,
emit
on监听
 
## 另外三种不常用通信 (用于面试)
### ref 通信
```
  <child ref="child"/>
  在父组件的
    this.$refs.child 就是这个子组件实例
  注意:
    不建议直接通过ref操作子组件 
```
### $children $parent
```
$children 组件中 获取当前组件所有的子组件 (数组)
$parent 获取当前组件的父组件
```
### provide  inject
//父组件中
{
  provide:{
    msg:'1234',
    num:12
  },
  data,
  template,
  methods
}


//子组件中 
{
  inject:['msg','num']
}

注意:挂载到了 子组件的 实例的 属性上  注意不要和data或者props或者计算属性或methods重名

 
## 插槽
占位符
  实现 组件,在不同父组件中使用,内部可以有不一样 代码块(布局(html))
 
 
 //子组件
  {
    template:`
        <div>
          <h2>我是子组件</h2>
         
          下面结构在不同的组件中使用 不一样
          <slot></slot> 
          
      </div>
  }
  //在父组件中
    template:`
        <div>
          home页内容 
          <child> 
          <!-- 子组件 自定义标签的内容 会自动 灌入 子组件内部的slot中 -->
              <h5>
                我是插槽对应的内容  
              </h5>
              <p>aaa</p>
          </child>
        </div>
      `,

 

1:具名插槽  命名插槽
  实现 可以在子组件中 定义多个插槽,且每个插槽,有自己名字(在传入代码时,指定传入哪个插槽
//子组件
{
     template:`
        <div>
          <h2>我是子组件</h2>
          <slot name="xm"></slot>
          <p>下面结构在不同的组件中使用 不一样</p>
          <slot name="xq"></slot>
        </div>
      `
  }


  //父组件
  {
    template:`
        <div>
          home页内容 
          <common-title>
             <div slot="xq">  slot属性 的值,对应插槽 name
                <button>我是小明</button>
              </div>
              <div slot="xm"> 
                <h3>我是小明</h3>
              </div>
             
          </common-title>
        </div>
      `
  }

 

mvvm 渐进式 前端 用于 构建用户界面的 js框架
mvvm    (原理具体参考脑图)
  m v vm(数据改变视图自动刷新)
数据驱动
new Vue({
  el:"#app", // 挂载vue 到html上
  data:{
    msg:123
  },
  methods:{
    change(){
      this.msg=""
    }
  }
})

 

{{}}
模板 在视图 渲染数据
1,js环境
2,里面的变量 或者 方法 自动去 寻找当前 视图 所在的组件这个实例的属性或者方法
3,js全局 变量或者方法 不通用 (白名单)
4,能写表达式  语句不行

 

指令:
  v-model  表单值 与 实例中 某个数据进行双向绑定
    .lazy 将 原来 input触发 改为change触发
    .trim 去除首尾空格
    .number 过滤成数字 (parseFloat)
  v-html 解析富文本数据
  v-bind:属性 属性的值 就会与 实例中的数据绑定
    简写: :属性
  v-on:事件  将原生事件,变成vue事件(事件函数 找实例上的方法)
    @事件
    事件对象
      $event
    修饰符
      .stop 取消冒泡
      .prevent 阻止 默认 行为
      .capture 事件在捕获阶段就提前触发
      .self 只能自己才能触发,后代元素无法触发
      .once 只触发一次
  总结:
    指定 写法 是标签属性,注意:指令 引号中   引号中是一个js环境 可以写表达式

 

  条件渲染
    v-if
    v-else (作为 if指令所在标签或者组件的下一个兄弟)

 

    v-show
    v-if v-show区别:
      1,都是控制元素 显示隐藏
      2,if移除元素 show display:none
      3,初始值为false v-if是不加载
    使用场景:
      v-show适用于频繁切换
      v-if适用于 初始不加载 (切换频率也不高)
  列表渲染
    v-for
    <li v-for="item in arr" 
      :key="xx"
    >
    <li v-for="(item,index) in arr" 
      :key="xx"
    >
  mvvm原理
    Object.defineProperty(target,属性,{
      get(){},
      set(){}
    })
    初始化一个实例(组件),vue会自动去遍历data中的所有的属性,用get/set劫持
    加入 监听器,只要数据变化,set就会立即通知。监听者,自动调用render函数,生成新的虚拟dom,和上一次(每一次render调用都会缓存虚拟dom)虚拟dom进行比较,diff算法,最小程度操作dom
    key:给每一层 虚拟dom节点,加了一个 标记(两个虚拟dom,就会按照,同一层同key进行比较)

 

  侦听器
  
watch
  {
    data(){
      return {
        msg:12,
        obj:{
          a:10,
          b:20
        }
      }
    },
    watch:{
      msg(newVal,oldVal){
         // 逻辑代码
      },
      "obj.a"(newVal,oldVal){
        // 逻辑代码
      },
      obj:{
        handler(newVal,oldVal){
          // 逻辑代码
        },
        deep:true
      }
    }
  }

 

  计算属性
    解决 在 模板中写过多业务逻辑
    一个数据 使用时候需要处理一下,在使用
   {
    data(){
      return {
        msg:'hello world'
      }
    },
    computed:{
      msg2(){  //不修改 计算属性的值 
          return this.msg.split('').reverse().join("")
      },
      msg3:{
        get(){
          return this.msg.split('').reverse().join("")
        },
        set(val){
          // val 设置计算属性的值,在这里去修改它的依赖
        }
      }
    }
   }

 

   注意:
   1,不要和data以及methods,props重名
   2,根据 属性所 依赖的值 缓存,如果多次使用,依赖没有变化,计算属性不会重新调用

 

posted @ 2020-08-28 20:47  软泥的新时代博客zu  阅读(183)  评论(0)    收藏  举报