vue 学习笔记(五)

一、编写可复用的组件

对于需要复用的组件,应当定义一个清晰的公开接口,同时也不需要对其外层数据做出任何假设。
vue组件的api来自三个部分----prop、事件、插槽:
a.prop   允许外部环境传递数据给组件。
b.事件   允许从组件内部触发外部环境的副作用。
c.插槽   允许外部环境将额外的内容组合在组件中。
使用v-bind和v-on的简洁语法,模板的意图会更清晰。
<my-component :foo='baz' :bar='qux' @event-a="doThis" @event-b="doThis">
<img slot="icon" src="..."/>
<p slot="main-text">hello</p> 
</my-component>

二、子组件引用

当需要在javascript中直接访问子组件。为此可以使用ref为子组件制定一个ID:如
<div id="parent">
    <child-compoent ref="child"></child-compoent>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
    Vue.component('child-compoent',{
        template: '<p>子组件</p>'
    });
    var parent = new Vue({
            el: '#parent',
            data: {}
        });
    var child = parent.$refs.child;
</script>

// 当ref和v-for一起使用时,获取到的引用会是一个数组,包含和循环数据源对应的子组件。
// $refs只在组件渲染完成后才填充,并且它是响应式的,它仅仅是一个直接操作子组件的应急方案
// 应当避免在模板或计算属性中使用$refs

三、异步组件

大型应用中,需要将应用拆分成多个小模块,按需从服务器下载。vue允许将组件定义为一个工厂函数,
异步的解析组件的定义。vue只在渲染时触发工厂函数,并把结果缓存起来,用于后面的再次渲染。如:
Vue.component('async-example',function(resolve, reject){
    setTimeout(function(){
        resolve({template: '<div>异步调用</div>'});
    },2000);
});
// 工厂函数接受一个resolve回调,在收到从服务器下载的组件定义时调用。也可以调用reject(reason) 指示加载失败。

四、组件命名约定

当注册组件(或则prop)时,可以使用kebab-case(短横线分割命名),camelCase(驼峰式命名),PascalCase(首字母大写命名)。
在html模块中,camelCase命名要改成kebab-case命名。
当使用字符串模板时,可以不受html大小写不敏感的限制。

五、递归组件

组件在它的模板内可以递归的调用自己,不过,只有当它有name选项时才可以这样做:
<div id="parent">
    <Asyncexample></Asyncexample>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
            Vue.component('Asyncexample',{
                name: 'example',
                template: '<div>递归组件<example></example></div>'
            });
            var parent = new Vue({
                    el: '#parent',
                    data: {}
            });

</script>
// 这样递归会导致死循环,所以递归是要确保递归调用终止条件。如递归调用时使用v-if并最终解析为false
<div id="parent">
    <Asyncexample v-bind:flag="bool"></Asyncexample>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
            Vue.component('Asyncexample',{
                props:['flag'],
                name: 'example',
                template: '<div>递归组件<example v-if="flag"></example></div>'
            });
            var parent = new Vue({
                    el: '#parent',
                    data: {
                        bool:false
                    }
            });

</script>

六、对低开销的静态组件使用v-once

当组件中包含大量静态内容时,可以使用v-once将渲染结果缓存起来。
Vue.component('Asyncexample',{
        template: '<div v-once>大量静态内容</div>'
});

七、边界处理情况

1、访问跟实例
   在每个new vue 实例的子组件中,其根实例可以通过$root属性进行访问。如:
<div id="parent">
    <my-component v-bind:msg="message">
    </my-component>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
            Vue.component('my-component',{
                props: ['msg'],
                template: '<button type="button" @click="getRootData">{{msg}}</button>',
                methods: {
                    getRootData: function () {
                        alert(this.$root.root);
                    }
                }
            });
            var parent = new Vue({
                    el: '#parent',
                    data: {
                        message: '父组件内容',
                        root: 'hello'
                    },
                    methods: {
                      baz: function () {
                          、、、
                      }
                  }
            });
</script>

// 所有的子组件都可以讲这个实例作为一个全局store来访问或使用

//获取根实例的数据
this.$root.root;
//写入根实例的数据
this.$root.root = 'hello world';
//调用根实例的方法
this.$root.baz();
2.访问父组件实例
  $parent属性可以用来从一个子组件访问父组件的实例,他提供了一种机会,在后期可以随时触达父级组件,
  以代替将数据以prop的方法传入子组件的方式。可以使用this.$refs.usernameInput 来访问base-input实例

3.依赖注入
<google-map>
  <google-map-region v-bind:shape="cityBoundaries">
    <google-map-markers v-bind:places="iceCreamShops"></google-map-markers>
  </google-map-region>
</google-map>

// 在这个例子中,假如google-map的后代都需要访问一个getMap。那使用$parent属性无法很好的扩展到更深层级的嵌套组件上。
// 这需要依赖注入,它用到了两个新的 实例选项 provide和inject
// provide:允许指定想要提供给后代组件的数据/方法,如:

provide: function () {
  return {
    getMap: this.getMap
  }
}
// 然后在任何后代组件里,都可以使用inject选项来接收指定的我们想要添加在这个实例上的属性,inject:['getMap']
4.程序化的事件侦听器
  通过$on(eventName,eventHandler) 侦听一个事件
  通过$once(eventName,eventHandler) 一次性侦听一个事件
  通过$off(eventName,eventHandler) 停止侦听一个事件

猜你喜欢

转载自blog.csdn.net/cxz792116/article/details/80774599