最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 1x5 精读Vue官方文档 - 处理边界情况

    正文概述 掘金(FULL_STOP)   2021-07-11   410

    精读 Vue 官方文档系列 ?

    访问元素 & 组件

    $root

    访问根组件实例

    $parent

    获取父组件实例,支持多次调用,获取连续多层父级的实例。

    ref & $refs

    获取子组件的实例

    <children ref="child" />
    

    获取 DOM 元素的对象引用。

    <input type="text" ref="input" />
    

    最终,我们可以在组件的 $refs 属性中访问这些 ref 的对应的引用。

    mountd(){
        this.$refs.child.input.foucs();
    }
    

    依赖注入

    使用 provide 提供依赖,再使用 inject 注入依赖。

    Provider

    provide: function(){
        return {
            getMapData: this.getData
        }
    }
    

    Consumer

    inject:['getMapData']
    

    这对组件选项必须要一起使用。以允许一个祖先组件向其所有后代组件注入一个依赖,不论组件的层级有多深。

    provide 的值是一个对象或者是返回一个对象的函数。对象的 key 便是向子孙组件中注入的依赖。 inject 的值是一个字符串数组,或者是一个对象选项。这些数组元素或者是对象的 key 都是对应的都是 provide 注入的依赖。

    最基本的形式:

    Vue.extend({
      name: "Parent",
      provide: {
        foo: "bar",
      },
    });
    
    Vue.extend({
      name: "Son",
      inject: ["foo"],
      created() {
        console.log(this.foo);
      },
    });
    

    provide 的值为一个函数,inject 的值是一个对象选项:

    Vue.extend({
      name: "Parent",
      provide() {
        return {
          foo: "bar",
        };
      },
    });
    
    Vue.extend({
      name: "Son",
      inject: {
        bar: {
          from: "foo",
          default: "new bar",
        },
      },
    });
    

    如果 inject 的值是一个对象,那么from 便可以指定来源,default 用来设置依赖的默认值。但是当你的依赖默认值不是一个基本类型时,必须要使用一个工厂方法来返回这个值。

    {
      inject: {
        foo: {
          from: 'bar',
          default: () => [1, 2, 3]
        }
      }
    }
    

    最后,因为 provide/inject 的初始化优先于 props,data ,所以我们便可以用依赖注入来初始化它们的默认值。

    Vue.extend({
      inject: ["foo"],
      props: {
        bar: {
          type: String,
          default: () => this.foo,
        },
      },
      data() {
        return {
          copy_bar: this.foo,
        };
      },
    });
    

    依赖注入解决了什么问题?

    1. 解决了 $parent 无法很好的扩展到更深层级的嵌套组件上。
    2. 给任意的后代提供数据或方法,免去了多层的 Prop 传递。
    3. 任意的后代也不需要关心 property 是从何处注入。

    依赖注入的应用场景:

    1. 编写一个固定组件集,存在一个根组件和多层的子组件,且结构固定。
    2. 一个局部的数据中心化。

    依赖注入的负面影响:

    1. 注入的数据或方法基于设计的考量不具有响应式的特性。
    2. 注入的数据虽然不会被处理为响应式数据,但是并不阻止依赖注入一个本是响应式的数据。
    3. 会将应用程序中相关的组件(使用依赖注入的组件)紧密的耦合在一起,使得重构变得比较困难(这是依赖注入的本质所决定的)。

    程序化的事件监听器

    程序化的事件监听器是建立在 Vue 系统上的,它区别于浏览器的事件系统(EventTarget API)。 通常我们使用 v-on 在组件上监听事件,使用 $emit() 在组件内触发事件,而 “程序化的事件监听器” 提供了一个可以在组件实例上监听事件的功能。

    • $on('eventName', eventHandler) 绑定/侦听一个事件。
    • $off('eventName, eventHandler') 解绑/停止侦听一个事件。
    • $once(eventName, eventHandler) 一次性绑定/监听一个事件。

    善用 $once 可以提高我们解决组件事件清理的麻烦。

    Bad

    // 一次性将这个日期选择器附加到一个输入框上
    // 它会被挂载到 DOM 上。
    mounted: function () {
      // Pikaday 是一个第三方日期选择器的库
      this.picker = new Pikaday({
        field: this.$refs.input,
        format: 'YYYY-MM-DD'
      })
    },
    // 在组件被销毁之前,
    // 也销毁这个日期选择器。
    beforeDestroy: function () {
      this.picker.destroy()
    }
    

    Good

    mounted: function () {
      var picker = new Pikaday({
        field: this.$refs.input,
        format: 'YYYY-MM-DD'
      })
    
      this.$once('hook:beforeDestroy', function () {
        picker.destroy()
      })
    }
    

    递归组件

    所谓“递归”就是自己调自己,同理组件递归就是组件不断的调用自身。

    递归组件的入口:

    <x-menu :menus="menus"></x-menu>
    

    递归组件的定义:

    Vue.component('x-menu', {
        props:{
            menus:{
                requried:true,
                type:Array
            }
        },
        template:`
            <ul>
                <li v-for="menu in menus" :key="menu.key">
                    <div>{{ menu.name }}</div>
                    <!--核心所在-->
                    <x-menus v-if="menu.children"></x-menus>
                </li>
            </ul>
        `
    });
    

    循环引用

    与递归组件不同的是,递归是通过不断调用自己来实现所需的功能。而循环引用只会存在两个组件之间,A 组件使用了 B 组件,B 组件也使用了 A 组件。

    通常这种问题只会出现在使用模块化系统来引入具有相互引用关系的组件。

    解决的办法有两种:

    1. 手动注册其中的一个组件

    beforeCreate: function(){
        this.$options.components.ComponetB = import('./components/componentB').default;
    }
    

    2. 使用异步组件

    {
        components:{
            'component-b': ()=>import('./components/componentB')
        }
    }
    

    模板定义的替代品

    我们更多的推荐使用单文件组件 SFC 的方式定义模板或者在 template 属性中编写字符串模板,并不建议将组件的模板与逻辑相分离。

    内联模板

    inline-template 这个特殊的 attribute 出现在一个子组件上时,这个组件将会使用其里面的内容作为模板,而不是将其作为被分发的内容(不在是理解中 slot 的性质)。这使得模板的撰写工作更加灵活。

    内联模板需要定义在 Vue 所属的 DOM 元素内。

    <my-component inline-template>
      <div>
        <p>These are compiled as the component's own template.</p>
        <p>Not parent's transclusion content.</p>
      </div>
    </my-component>
    

    X-Template

    与内联模板相比就是使用具有特殊 type 值与 id 属性的 <script> 标签来存储模板内容。

    x-template 需要定义在 Vue 所属的 DOM 元素外。

    <script type="text/x-template" id="hello-world-template">
      <p>Hello hello hello</p>
    </script>
    

    id 的作用就是将模板内容与模板逻辑进行连接的凭据。

    Vue.component('hello-world', {
      template: '#hello-world-template'
    })
    

    强制更新

    调用 this.$forceUpdate() 可以强制更新组件。

    通过 v-once 创建低开销的静态组件

    当组件包含了大量静态内容时。我们可以在根元素上添加 v-once attribute 以确保这些内容只计算一次然后缓存起来,提供组件的渲染速度。

    Vue.component('terms-of-service', {
      template: `
        <div v-once>
          <h1>Terms of Service</h1>
          ... a lot of static content ...
        </div>
      `
    })
    

    起源地下载网 » 1x5 精读Vue官方文档 - 处理边界情况

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元