成立背景
在一个项目中,一个请求的结构,里面包含三种权限,权限可以任意组合
一开始我的想法
这个操作有点骚,我提前准备好各种权限组合的 template ?想了下我可能需要准备如下情况
权限 A | 权限 B | 权限 C |
---|---|---|
X | X | X |
X | X️ | ✔️ |
X | ✔️ | ✔️ |
✔️ | ✔ | ✔ |
✔ | ✔ | X |
✔ | X | X |
X | ✔ | X |
✔ | X | ✔ |
有这 8 种,如果到时候再我加一个权限,岂不是要原地去世。然后就考虑了下 gql 函数直接传模板,通过对模板的过滤来生成我们想要的模板,于是就看了下用法,
// 这样的
import gql from 'graphql-tag'
const t = gql`
query Demo {
}
`
// 支持传 fragment 的
const t2 = gql`
query Demo {
...Fragment
}
${Fragment}
`
看了半天没找到我要的结果,于是我就到 graphql-tag
源码里面看了下,如下图
这里我们看到一个 literals
变量,他就是 gql
函数的第一个参数传进来的 template,但是如果我们直接如下使用
gql(`
query Demo {
...Fragment
}
`, Fragment)
literals
这个值就是一个纯字符串,到下面的拼接 args
,我们可以想一下 result
肯定会被加上一些莫名其妙的字符,结局就是 parseDocument
报错,到这里我们要先停一下,这个时候,我们就需要去了解普通的函数调用和字符串模板函数调用的区别
函数调用的区别
在这里我只是简单的打印下两种函数调用的 arguments
给大家看下
我们可以看到区别就是第一个参数 arguments[0]
是不同的,普通函数是字符串,模板字符串函数是一个数组,这个数组包含一个原始模板和一个传入的占位符
结果
所以到此我们就有了动态模板的思路了,我们只需要构造一个和模板字符串第一个参数一样结构的参数传入 gql
就 ok 了
export function stringRaw(template, args = 0) {
const r = new Array(args)
if (r.length !== 0) {
r.fill('')
}
r.unshift(template)
return r
}
const t = gql(stringRaw(`
query Demo{
field1
${permissionA ? 'field2' : ''}
${permissionB ? 'field3' : ''}
${permissionC ? 'field4' : ''}
field5 {
...Fragment
}
}
`, 1), Fragment)
至此我们就完成了传入动态字符串了