插槽:
作用:让组件内的标签能动态传入
用法:
<slot></slot>
 当使用组件,并未给传入具体标签内容时,插槽默认内容会显示
 使用组件时传入自定义标签
<Pannel></Pannel>
自定义标签会替换slot的位置
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
¶具名插槽
作用:给不同的slot分发不同的内容
slot name= “” 这个 attribute 可以用来定义额外的插槽
给具名插槽提供内容时候,在一个 <template> 元素上使用 v-slot 指令,用template包裹自定义标签,并以 v-slot 的参数的形式提供其名称
v-solot:name 简写等同 #name
<template v-slot:header>
v-slot 
只能添加在 <template> 上 (只有一种例外情况),这一点和已经废弃的 slot attribute 不同。
具名插槽和插槽的默认语法不能混用,会导致作用域不明确
作用域插槽
让插槽内容能够访问子组件中才有的数据.
在子组件slot 身上添加属性和子组件的值
使用组件出template 配和v-slot = ‘变量名’
子组件内在的slot上绑定的变量
<slot :row="obj">
</slot>
export default{
    data(){
        obj:{
            firstname: "Lionel",
            lastname: "messis"
        }
    }
}
父组件指定接受
<Pannel>
    //scope是个对象,存储了 slot 绑定了所有属性  scope:{row:obj}
	<template v-slot="scope">
    		<h1>
			{{scope.row.lastname}}    	
    		</h1>
    </template>
</Pannel>
export default{
    components:{
        Pannel,
    }
}
在使用组件时开闭标签内写 template,设置v-slot=“变量”
当被提供的内容只有默认插槽时,组件的标签才可以被当作插槽的模板来使用。这样我们就可以把 v-slot 直接用在组件上:
v-slot:default="变量名"
v-slot="变量名"  等同以上
自定义指令
作用:当Vue内置指令无法满足需求时可以自定义
用法: 全局注册或者局部注册(核心API)
全局:
// 全局注册指令
//参数1:指令名称 参数2: 配置对象
Vue.directive("foc", {
  //inserted 函数会自动使用 当该指令绑定的标签插入DOM树上时候执行 执行时候会把绑定的标签元素传过来
  inserted(el) {
      //对el进行操纵
  console.log(el)
  el.focus()
  }
})
局部注册:
directive:{
   foc:{
     inserted(el){
       el.focus();
     }
   }
 }
上面的focus指令能自动获取焦点
下面这个案例的节选部分,实现了对btn点击转为搜索框,自动获取焦点,并注册了失去焦点,输入判定,本地存取,运用了序列化反序列化,以及使用ES7 的asnyc await 发送AJAX请求,
<td>
                  <!--绑定按下事件 通过监听inputVisible属性变化 以及inputValue属性注册										相应的事件  -->
                  <input type="text"
                      v-if="scope.row.inputVisible"
                      v-foc
                      ref="inp"
                      v-model="scope.row.inputValue"
                      @keydown.esc="scope.row.inputValue==''"
                      @keydown.enter="enterFn(scope.row)"
                      @blur="scope.row.inputVisible=!scope.row.inputVisible"
                      style="width:80px">
                  <button @click="!search(scope.row)" class="btn btn-primary"
                  v-else >+TAGS
                  </button><br>
                  <span style="margin-left:5px"
                      v-for="(item,index) in scope.row.tags"
                      :key="index"
                      class="badge bg-warning ">
                  {{item}}
                  </span>
              </td>
export default {
    name: 'GoodslistMygoodslist',
    components:{
        MyTable,
        MyHeader
    },
    data() {
        return {
    //把本地数据取出来
        list: JSON.parse(localStorage.getItem('data')),
        isShow: true,
        };
    },
    //自定义指令的局部注册焦点事件
    directives:{
    foc:{
        inserted(el){
        el.focus()
                }
    }
},
        //发送ajax
    // async created(){
    //     let res= await this.$ajax({
    //         url:'/api/goods',
    //     })
    //     this.list=(res.data.data)
    // },
    methods: {
        search(row){
              // this.$nextTick().then(()=>{this.$refs.inp})
            row.inputVisible=true
        },
        enterFn(obj){
            if(obj.inputValue.trim().length===0){
                alert("非法")
                return 0
            }
            obj.tags.push(obj.inputValue)
            obj.inputValue=""
        },
        del(id){
            let index =  this.list.findIndex(item => item.id===id)
            this.list.splice(index,1)
        }
    },
    //深度监听将数据缓存到本地
    watch:{
        list:{
            deep: true,
            handler(){
                localStorage.setItem('data', JSON.stringify(this.list))
            }
        }
    }
};
$nextTick方法
参数:
{Function} [callback]
用法:
将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法
Vue.nextTick一样,不同的是回调的this自动绑定到调用它的实例上。
- $nextTick 原地返回值 是个Promise对象,因此能链式编写
 
示例:
<button @click="search" v-if="isShow">点我搜索</button>
<input  v-else ref= "inp"   type="text">
data(){
    return:{
        isShow:true,
    }
},
methods:{ 
		search(){
      			this.isShow =false;	
        		this.$nextTick().then(()=>{ this.$refs.inp.focus()})
 				}
    		}
当用户点击这个search时,会立即跳转将btn 转为search框
参考:
上文用到了$refs 方法
他是获取元素DOM元素的方法
¶ref
- 
预期:
stringref被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的$refs对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例:<!-- `vm.$refs.p` will be the DOM node --> <p ref="p">hello</p> <!-- `vm.$refs.child` will be the child component instance --> <child-component ref="child"></child-component>当
v-for用于元素或组件的时候,引用信息将是包含 DOM 节点或组件实例的数组。关于 ref 注册时间的重要说明:因为 ref 本身是作为渲染结果被创建的,在初始渲染的时候你不能访问它们 - 它们还不存在!
$refs也不是响应式的,因此你不应该试图用它在模板中做数据绑定。 - 
参考:子组件 ref
 
¶vm.$refs
- 
类型:
Object - 
只读
 - 
详细:
一个对象,持有注册过
refattribute 的所有 DOM 元素和组件实例。 - 
参考:
 
获取原生DOM需要在Mounted生命周期获取
在Mounted生命周期中获取2中方式
- 在目标标签添加 id /ref
 - 在恰当实际,通过 id / ref 属性获取目标标签
 
示例:
<h1 id ='baba' ref="bigH1"></h1>
<h1>ref和ID获取原生DOM</h1>
mounted(){
    let h1 = document.querySelector("#baba");
    let h1Ref = this.$refs.bigH1;
    console.log(h1);
    console.log(h1Ref);
}
¶$refs 可以通过ref属性获取组件对象
¶(当需要调组件对象里方法等) 子传父方法
示例:
父组件:
<h1>ref 获取子组件对象</h1>
<Demo ref="Yetu"></Demo>
import Demo from './components/refdemo.vue'
export default {
components:{
        Demo,
  },
    mounted(){
        console.log(this.$refs.Yetu.msg)
        this.$refs.yetu.fn()
    }
}
子组件:
<h4>这是子组件
     {{msg}}
</h4>
export default {
data() {
        return {
            msg:'这是子组件里的数据'
        };
    },
 methods: {
        fn(){
            console.log("这是子组件里的方法")
        }
    },
}
                
            
                    
                    
                        
                        