Skip to content

Commit 1cde8fb

Browse files
committed
完成无渲染函数的文档
1 parent 0094cf6 commit 1cde8fb

File tree

2 files changed

+102
-4
lines changed

2 files changed

+102
-4
lines changed

docs/.vuepress/config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ module.exports = {
2020
"/posts/tutorial/2",
2121
"/posts/tutorial/3",
2222
"/posts/tutorial/4",
23-
"/posts/tutorial/5",
2423
"/posts/tutorial/6",
24+
"/posts/tutorial/5",
2525
"/posts/tutorial/7",
2626
"/posts/tutorial/8",
2727
"/posts/tutorial/9",

docs/posts/tutorial/5.md

Lines changed: 101 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ slot分为3种类型,第一种是普通插槽,也就是我们上边提到这
9595

9696
上边案例中,close-icon这个关闭按钮的事件函数是绑定在close这个元素上边,而且是在组件内部绑定的。刚才我们实现了close-icon的替换,假如UI这边需要调整close-icon的位置,最快的方法是改样式,改样式首先需要考虑这个组件大概那些地方会用到,是全局改样式还是只是改局部的,如果不是使用第三方组件的情况下,也就是咱们从开发一个组件的方面考虑,适应常用场景下保证组件灵活性,避免使用者使用的时候需要对组件内部进行修改。所以我们这里使用slot-scope来对上边的案例进行一个修改。
9797

98-
<iframe height="265" style="width: 100%;" scrolling="no" title="message-box-2" src="//codepen.io/uncleze2017/embed/ewWZGv/?height=265&theme-id=0&default-tab=result" frameborder="no" allowtransparency="true" allowfullscreen="true">
98+
<iframe height="400" style="width: 100%;" scrolling="no" title="message-box-2" src="//codepen.io/uncleze2017/embed/ewWZGv/?height=265&theme-id=0&default-tab=result" frameborder="no" allowtransparency="true" allowfullscreen="true">
9999
See the Pen <a href='https://codepen.io/uncleze2017/pen/ewWZGv/'>message-box-2</a> by uncleze
100100
(<a href='https://codepen.io/uncleze2017'>@uncleze2017</a>) on <a href='https://codepen.io'>CodePen</a>.
101101
</iframe>
@@ -125,9 +125,107 @@ slot分为3种类型,第一种是普通插槽,也就是我们上边提到这
125125
```
126126
将close这个方法用slot-scope传递到了父组件,让使用这可以自定义元素并绑定事件函数,解决之前只能在内部固定绑定事件的情况。
127127

128-
## 行为与表象分离
128+
## 无渲染组件
129129

130130
我们通过slot和slot-scope给使用这提供部分自定义html和调用自己内部实现的函数的途径。让使用者自定义部分html,然后还能方便的调用函数,并且不用理会内部的状态。
131131

132-
其实我们仔细想想,就上述的组件,其实完全可以让用户自定义全部的html,也就是组件不渲染html,只提供函数,和组件的状态。
132+
所谓的无渲染组件,就是让用户自定义全部的html,组件只提供函数,和组件的状态等剩余内容,即是不渲染html的组件。
133+
134+
接下来我们使用最开始提到的案例。
135+
136+
因为已经不需要渲染了html了, 所以template就不需要了,我们直接使用render函数来进行渲染
137+
138+
```js
139+
Vue.component('renderless-component', {
140+
render (h) {
141+
return this.$scopedSlots.default({
142+
tags: this.tags,
143+
addTag: this.addTag,
144+
deleteTag: this.deleteTag
145+
})
146+
},
147+
props: {
148+
tags: Array
149+
},
150+
mounted () {
151+
console.log(this.tags)
152+
},
153+
methods: {
154+
addTag (e) {
155+
let value = e.target.value.trim()
156+
if (!this.tags.includes(value)) {
157+
this.tags.push(value)
158+
}
159+
e.target.value = ''
160+
this.$emit('on-change',value, this.tags)
161+
},
162+
delTag (index) {
163+
this.tags.splice(index, 1)
164+
}
165+
}
166+
})
167+
168+
let vue = new Vue({
169+
el: '#app',
170+
data () {
171+
return {
172+
tags: [
173+
'日本',
174+
'泰国'
175+
]
176+
}
177+
},
178+
methods: {
179+
handleChangeTags (cur, tags) {
180+
console.log(cur, tags)
181+
}
182+
}
183+
})
184+
```
185+
186+
```html
187+
<div id="app">
188+
<renderless-component :tags="tags">
189+
<div class="input-tag" slot-scope="{tags, addTag, deleteTag}">
190+
<span class="tag" v-for="(tag, i) in tags" :key="i">
191+
{{tag}}
192+
<a href="javascript:;" @click="delTag(i)">&times;</a>
193+
</span>
194+
<input type="text" @keydown.enter="addTag">
195+
</div>
196+
</renderless-component>
197+
</div>
198+
```
199+
<iframe height="400" style="width: 100%;" scrolling="no" title="renderless-component" src="//codepen.io/uncleze2017/embed/Prmaev/?height=265&theme-id=0&default-tab=result" frameborder="no" allowtransparency="true" allowfullscreen="true">
200+
See the Pen <a href='https://codepen.io/uncleze2017/pen/Prmaev/'>renderless-component</a> by uncleze
201+
(<a href='https://codepen.io/uncleze2017'>@uncleze2017</a>) on <a href='https://codepen.io'>CodePen</a>.
202+
</iframe>
203+
204+
然后,我们调整一下html部分,就可以适应第二种场景。
205+
206+
```html
207+
<div id="app">
208+
<renderless-component :tags="tags">
209+
<div class="input-tag__wrapper" slot-scope="{tags, addTag, delTag}">
210+
<div class="input-tag">
211+
<input type="text" @keydown.enter="addTag">
212+
</div>
213+
<div class="tag-list" v-if="tags.length">
214+
<span class="tag" v-for="(tag, i) in tags" :key="i">
215+
{{tag}}
216+
<a href="javascript:;" @click="delTag(i)">&times;</a>
217+
</span>
218+
</div>
219+
<div class="tag-list__empty" v-else>
220+
Please add some tags ...
221+
</div>
222+
</div>
223+
</renderless-component>
224+
</div>
225+
```
226+
227+
<iframe height="300" style="width: 100%;" scrolling="no" title="renderless-component2" src="//codepen.io/uncleze2017/embed/zVwXXr/?height=265&theme-id=0&default-tab=result" frameborder="no" allowtransparency="true" allowfullscreen="true">
228+
See the Pen <a href='https://codepen.io/uncleze2017/pen/zVwXXr/'>renderless-component2</a> by uncleze
229+
(<a href='https://codepen.io/uncleze2017'>@uncleze2017</a>) on <a href='https://codepen.io'>CodePen</a>.
230+
</iframe>
133231

0 commit comments

Comments
 (0)