VUE(二) -- 进阶

68 阅读2分钟

一、插槽

匿名插槽:组件外部维护参数以及结构、内部自定义放置位置插入。
具名插槽: <slot name="header"></slot>以name为标识,对多个插槽进行区别和标识。
作用域插槽:可以接受scope-slot传上来的参数。

 定义:
     <slot ></slot>
     <slot name="header"></slot>
     <slot :slotProps="slotProps"></slot>
     <slot :slotProps="slotProps" name="header"></slot>
 使用:
 // vue2.6以前版本
     <template ></template>
     <template slot="header"></template>
     <template slot-scope="{ slotProps }" >
     <template slot-scope="{ slotProps }" slot="header">
      {{slotProps}}
     </template>
 
 // >2.6
    <template ></template>
    <template v-slot:header></template>
    <template v-slot:slotProps='slotProps'> 
    <template v-slot:header='slotProps'>  
      {{slotProps}}
     </template>

二、过滤器

{{ timer | format }}format是一个方法,timer就是参数 ,处理之后,返回值会渲染到timer

 使用:
 {{ msg | msgFilter}}
 
 定义:
 filters:{
     msgFilter(v){
       let _arr = ['foo','bar','baz']
       return _arr[v] || "nothing"
     }
 
 }

filter过滤器是的this不指向实例,指向全局,所以filter应该是一个纯函数。

三、jsx

template -> js

<script>
    export default {
        name: "hellowWorld",
        data(){
          return{
            value:100,
            options:[{
              value:1,
              label:"1"
            },
              {
                value:2,
                label:"3"
              },
              {
                value:3,
                label:"3"
              }]
          }
        },
       methods:{
         handleClick(){
           ////
         }
       },
        render(h) {
          //手写节点 node用(),逻辑用{}
          const textNode = (
            <p>{this.value > 99 ? 99 : this.value}</p>
          )
          return (
            <ul>
            {
               //遍历实现 v-for
              this.options.map(item => {
                return (
                  <li>{item.label}<li>
                  //组件引入 属性 - 事件
                  <contentLi
                     item={item}
                     value={item.value}
                     key={item.value}
                     onclick={this.handleClick}
                  >
                       //节点嵌套
                       { textNode }
                   </contentLi>
                )
              })
            }
            </ul>
          )
        }

    }
</script>

四、组件化

1.传统组件

//注册组件
Vue.component('helloWorld',{
   template:'<span>hello world</span>'
})
//创建实例
new Vue({
   el:"#app"
})

2.混入 mixin

使用场景,抽离公共逻辑(逻辑相同,但是模板不一样)

  • data数据冲突时, 数据以主题为准
  • 生命周期的顺序 mixin 在先,先加载mixin,再加载主体组件
export default {
 data(){
   return{
     msg:"this is mixin.js"
   }
 },
 created(){
   console.log("mixin created")
 }
}

3.继承拓展 extends

使用场景, 拓展独立逻辑

  • 与主体相比,与mixin的优先级相同,
  • 但是mixin相比,mixin的优先级大于extends,回调的优先级比mixin高。

4.整体拓展extend

全局拓展一个全局配置,进行合并

//创建一个vue实例
new Vue({
  el:"app",
  components: { App },
  template:'<App />'
})

//新增一个构造器

const BASEOPTIONS = {
  data(){
    return{
      msg:"this is  extend options"
    }
  },
  created(){
    console.log("extend created")
  }
}
//挂载
const basicComponent = Vue.extend(BASEOPTIONS)

//可以基于一个拓展  再此进行拓展

new basicComponent({
  created(){
    console.log('extend Next Created')
  }
})

5.插件 - Vue.use()

//myPlugin.js
*************************
//使用vue.use()的方法,会默认指向插件的install方法,并且把vue 和 option 作为两个参数传参给install方法
// 使用vue.globalMethods 进行对method的拓展等等
export default {
  install:(vue,options) => {
    vue.globalMethods = function () {

    };
    vue.directive('directiveName',{
      bind(el,binding,vNode){

      },
      inserted(el,binding,vNode){

      }
    });
    vue.prototype.myFunction = function () {

    }
    //相应的逻辑
    //....
  }

}
*******************************
//使用
import myPlugin from './myPlugin'
Vue.use(myPlugin,{
  //配置项
  ...options
})

五、vue边界问题

  • 组件递归调用,A引用B,B引用了A
  • updated生命周期修改 data 的属性值 ,陷入无限循环
  • 访问 根实例/父组件/子组件 $root/$parents/$ref