Vue tip: No rendering components
When using Vue to develop a component, I encountered a problem: the component can be used to customize too many props. As a result, I needed to pass in too many properties, such as data, style control and other attributes.
< some - component title = "I am title" : pos = "[0, 0] :" size = "[500, 400]" : the radius = "[0, 0.5] ": borderWidth =" 2 ": borderColor =" '# FFF' testData ": data =" "/ >
While it may look fine, the list of properties you can customize in practice is far more than that, making it unsightly to use. The idea was to define a theme component similar to the React theme component, and then define some non-data-dependent props to the theme component. The theme component then automatically passes the props to other components. The theme component is used like this:
<theme :pos="[0, 0]" :size="[500, 400]" :radius="[0, 0.5]" :borderWidth="2" :borderColor="'# FFF '" > <some-component title=" I am the title ":data="testData" /> </thmem>
The development oftheme
component
In React, it’s easy to develop such a higher-level theme component. But how do you develop the Theme component in vUE to achieve the desired effect? Looking through the Vue documentation, we found that this was possible with the help of $slots and the Render function.
export default { name: $attrs = props, render(h) {const theme = this.$attrs = props, Const merge => {if (! vNode.tag) { return } if (vNode.componentOptions) { let props = vNode.componentOptions.propsData props = Object.assign({}, theme, props) vNode.componentOptions.propsData = props } else { if (! vNode.data) { return } let attrs = vNode.data.attrs || {} attrs = Object.assign({}, theme, attrs) vNode.data.attrs = attrs } } this.$slots.default.map(vNode => merge(vNode)) Object.keys(this.$attrs).forEach(key => {this.$attrs[key] = null}) return this.$slot.default [0]
The result is this:
<theme :pos="[0, 0]" :size="[500, 400]" :radius="[0, 0.5]" :borderWidth="2" :borderColor="'# FFF '" > <some-component title=" I am the title ":data="testData" /> </thmem>
Obviously the Theme component is not rendered, and all it does is pass through props to other components, called the non-rendered component.
slot-scope
Slot-scopes are mentioned in the Vue documentation to be cleaner using scope slots. So you can write an AXIOS component based on your experience with the Theme component.
Vue.component('s-axios', { props: ['url'], data() { return { loading: true, response: null } }, created() { axios.get(this.url) .then(response => { this.loading = false this.response = response }) }, render() { return this.$scopedSlots.default({ loading: this.loading, response: this.response }) } })
It’s also easy to use:
<div id="app"> <s-axios url="https://api.github.com/orgs/reactjs/repos"> <div slot-scope="{ loading, Response}"> <div v-if="loading"> Loading </div> <div v-else> ${{response.data}}</div> </div> </s-axios> </div>
Click to view the online Demo.
conclusion
With $slots, $scopedSlots and Render, you can create a lot of interesting components, such as the non-render component described in this article. The key is what the user thinks.