### 自定义图标

自定义图标以 sd 开头，用法与常规图标用法相同，可以用按钮的 icon 属性

```vue
<a-icon type="sd-hat" />
<a-icon type="sd-pie-chart" theme="twoTone" />
<a-button icon="sd-module">
  Search
</a-button>
```

### 获取受身份保护的图片

如果图片匿名不能访问，直接写到 src 里面不会带上 token，需要使用 sdResource filter 处理一下

```vue
<img :src="`api/framework/v1/user-manager/userAvatar/hdadmin` | sdResource" />
```

### 下载系统附件

使用 js 下载系统文件

```javascript
import download from '@/common/services/download'
download('api/framework/v1/task-form-process/download-attachments/附件code', '文件名.docx')
```

### 表达式中避免空值报错

在模板表达式中如果访问空值的子属性，页面会报错，这时可以通过 sdGet 这个函数来处理（8.1.0.30 之前需要 sdGet 函数，8.1.0.30 及之后版本原生支持了，无需此函数）

类似 ES 标准中如下功能： [可选链操作符](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/%E5%8F%AF%E9%80%89%E9%93%BE)

```vue
<template>
  <div>
    <div>sdGet('name.test?.xxx'):{{ sdGet('name.test?.xxx') }}</div>
    <div v-for="(item, index) in testEmpty" :key="index">
      在v-for中使用：sdGet(item,'name?.first') {{ sdGet(item, 'name?.first') }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: 'sanmao',
      testEmpty: [{ name: { first: 'sanmao' } }, 'text'],
    }
  },
}
</script>
```

### 获取用户信息

通过 storeMixin 可以把用户信息混入到组件中

```html
<template>
  <div>{{ userInfo }}</div>
</template>

<script>
  import storeMixin from '@/common/store-mixin'
  export default {
    mixins: [storeMixin],
  }
</script>
```

非组件环境使用

```javascript
import { getUserInfo } from '@/common/store-mixin'
console.log(getUserInfo())
```

### 关闭、刷新当前 tab 页

通过 SdTabbedView API 即可。需要注入 SdTabbedView

```html
<template>
  <a-button @click="SdTabbedView.closeCurrent">
    关闭当前Tab页
  </a-button>
  <a-button @click="SdTabbedView.reload">
    刷新当前Tab页
  </a-button>
</template>

<script>
  export default {
    inject: ['SdTabbedView'],
  }
</script>
```

### JS 方式打开各种选值对话框

所有通过 SdValuePicker 实现的选择器，例如 SdIconPicker、SdFlowPicker 等，默认都是点击 input 框弹出选择界面的。

如果需要通过 JS 调用这些对话框，可以通过 pickValues 服务实现。

```vue
<template>
  <div>
    <div>
      <a-button @click="selectIcon">选择图标</a-button>
      {{ icon }}
    </div>
    <div>
      <a-button @click="selectFlow">选择流程</a-button>
      {{ flow }}
    </div>
    <div>
      <a-button @click="selectValue">一般列表选择</a-button>
      {{ value }}
    </div>
  </div>
</template>

<script>
import pickValues from '@/common/services/pick-values'
import sdIconPicker from '@/common/components/sd-icon-picker.vue'
import sdFlowPicker from '@/common/components/sd-flow-picker.vue'
import sdListPickerVue from '@/common/components/sd-list-picker.vue'

export default {
  data() {
    return {
      icon: [{ id: 'sd-oa/outline', name: 'sd-oa', theme: 'outline' }],
      flow: [{ id: 'G_1_JITUANSW', name: '集团收文流程' }],
      value: [{ id: '1', name: 'content2' }],
    }
  },
  methods: {
    selectFlow() {
      pickValues(
        sdFlowPicker, // 第一个参数：使用的选择器组件
        // 第二个参数：传递给选择器的props。默认选中的值、是否单选等，都可以传递
        {
          value: this.flow,
          single: false,
        }
      )
        // 用户选择完成后，promise返回选中的值。用户取消返回undefined
        .then((values) => (this.flow = values))
    },

    selectValue() {
      pickValues(sdListPickerVue, {
        loadListData() {
          return new Promise((resolve) => {
            setTimeout(() => {
              const dataSource = []

              for (let i = 0; i < 20; i++) {
                dataSource.push({
                  id: i.toString(),
                  name: `content${i + 1}`,
                })
              }
              resolve(dataSource)
            }, 400)
          })
        },
        value: this.value,
        single: true,
      }).then((values) => (this.value = values))
    },

    selectIcon() {
      pickValues(sdIconPicker, {
        value: this.icon,
      }).then((values) => (this.icon = values))
    },
  },
}
</script>
```

### ProgressBar 页面底部进度条

更多更高级用法请参考： [NProgress](https://github.com/rstacruz/nprogress)

```vue
<template>
  <div>
    <a-button @click="ProgressBar.start()">
      开始
    </a-button>
    <a-button @click="ProgressBar.set(0.4)">
      设置为50%
    </a-button>
    <a-button @click="ProgressBar.done()">
      完成
    </a-button>
  </div>
</template>

<script>
import ProgressBar from '@/common/services/progress-bar'
export default {
  data() {
    return {
      ProgressBar,
    }
  },
}
</script>
```

### 浏览器页签通信

使用场景:从待办列表打开待办，待办提交后需要通知待办列表更新

```javascript
//第A页面调用api打开b页面
crossWindowWatcher.subscribeChange({
  url: '/sd-webflow/xxx/xxx', //新窗口打开的链接
  callback: () => {
    //回调事件
  },
})
//通知父窗口触发回调事件,可以传参true/false
crossWindowWatcher.notifyChange()
```
