一些和自定义css属性有关的API
上篇中我们介绍了如何自定义css变量,从而在外部定义一些具体的值,由外部component传入子component后动态的改变,子component的样式。但是这一切都是声明式的也就是说在运行前这些样式就已经决定了,如果你需要在运行时动态的改变一些自定义属性定义的样式,那你就要使用一些polymer提供的API了。

customStyle和updateStyles

下面来看一个例子
还是把my-toolbar改回来,不用@mixin 还是用var(--my-toolbar-title-color)

<link rel="import" href="../bower_components/polymer/polymer.html">
<dom-module id="my-toolbar">
    <template>
        <style>
            :host {
                padding: 4px;
                background-color: gray;
            }
            .title {
                color: var(--my-toolbar-title-color);
            }
        </style>
        <span class="title">{{title}}</span>
    </template>
    <script>
        Polymer({
            is: 'my-toolbar',
            properties: {
                title: String
            }
        });
    </script>
</dom-module>

接下去创建一个父component x-custom

<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="my-toolbar.html">
<dom-module id="x-custom">
  <template>
    <style>
      :host {
        --my-toolbar-title-color: red;
      }
    </style>
    <my-toolbar title="My awesome app"></my-toolbar>
    <button on-tap="changeTheme">Change theme</button>
  </template>
  <script>
    Polymer({
      is: 'x-custom',
      changeTheme: function() {
        this.customStyle['--my-toolbar-title-color'] = 'blue';
        this.updateStyles();
      }
    });
  </script>
</dom-module>

来看几行关键代码

<style>
  :host {
    --my-toolbar-title-color: red;
  }
</style>

这个style上上一篇的外部定义变量无异,给一个初始的文字颜色red。

<script>
    Polymer({
      is: 'x-custom',
      changeTheme: function() {
        this.customStyle['--my-toolbar-title-color'] = 'blue';
        this.updateStyles();
      }
    });
</script>

这里我们给button添加了一个点击事件,当用户点击button时,执行changeTheme的方法,方法里做了2件事情。

  1. 修改customStyle属性中的变量 --my-toolbar-title-color 为 blue

  2. 调用updateStyles()方法来刷新视图

Run一下,看下效果,初始时文字为red
图片描述
点击后,文字变成blue,达到目的
图片描述

为毛要有这2个API呢,为毛polymer不能自动更新视图呢。官方给出的解释是考虑到性能问题。

不过我测试了一下,有一种case是不需要手动updateStyles()的,
比如,下列代码中,我点击按钮动态添加一个class b的dom节点,原本事先在style中定义好的css x-foo.b会立刻生效,并不需要手动刷新。

<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="x-foo.html">
<dom-module id="x-custom2">
    <style>
            /* applies */
        x-foo.a {
          --foo: brown;
        }
        /* does not apply */
        x-foo.b {
          --foo: orange;
        }
    </style>
    <template>
        <div id="container">
            <x-foo class="a"></x-foo>
        </div>
        <button on-tap="addClass">add class b</button>
    </template>
    <script>
        Polymer({
            is: 'x-custom2',
            addClass:function(){
                var xfoo = document.createElement('x-foo');
                xfoo.classList.add('b');
                Polymer.dom(this.$.container).appendChild(xfoo);
            }
        });
    </script>
</dom-module>

为嘛会这样呢,动态添加dom就不需要手动刷新,而动态设置自定义css属性就需要updateStyles(),我猜测可能的原因是
如果用户同时设置多个自定义css属性,比如

this.customStyle['--my-toolbar-title-color'] = 'blue';
this.customStyle['--my-toolbar-title-color2'] = 'red';
this.customStyle['--my-toolbar-title-color3'] = 'green';

这样如果让Polymer自动去刷新视图可能就要执行3次render,用户手动自己在最后一次性刷新的话能提升一定的性能。

本篇未完待续...


熊丸子
5.6k 声望293 粉丝

现在sf的文章质量堪忧~~~