成立背景
在一個專案中,一個請求的結構,裡面包含三種許可權,許可權可以任意組合
一開始我的想法
這個操作有點騷,我提前準備好各種許可權組合的 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)
複製程式碼
至此我們就完成了傳入動態字串了