-
Notifications
You must be signed in to change notification settings - Fork 546
Remove inline-template #98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I build a lot of Laravel sites. A common situation where I rely on |
There's a bunch of articles out nowadays suggesting that Google would handle the "hidden in a JS file" scenario pretty well. A key takeaway from this article is that Google will wait 5-20 seconds before taking a snapshot of the page. So I'd say you're fine in that regard. |
You're right, but I think most other search engines lag behind Google a bit, that's mostly the cause for my hesitation. Check out: |
Would it be possible to refactor it to use a default slot? |
Yep! I think that’s a great solution. Thanks! |
@leopiccionia good point. I've added default slot as a replacement option: https://github.com/vuejs/rfcs/blob/remove-inline-templates/active-rfcs/0000-remove-inline-templates.md#replacement-2-default-slot |
This RFC is now in final comments stage. An RFC in final comments stage means that: The core team has reviewed the feedback and reached consensus about the general direction of the RFC and believe that this RFC is a worthwhile addition to the framework. |
Hi everyone.
Replacement 1 (templates in script tags) gives us 1) and replacement 2 (default slots) gives us 2). <body>
<div id="app">
<h1>Test inline template</h1>
<test-inline-template :init-counter="3" inline-template>
<div>
<div>counter (start from {{initCounter}}): {{counter}}</div>
<button v-on:click="methodClick">Click</button>
</div>
</test-inline-template>
<h1>Test default slot</h1>
<test-default-slot :init-counter="4" v-slot="vm">
<div>
<div>counter (start from {{vm.initCounter}}): {{vm.counter}}</div>
<button v-on:click="vm.methodClick">Click</button>
</div>
</test-default-slot>
</div>
<script>
Vue.component("test-inline-template", {
props: {
initCounter: {
type: Number,
required: true
}
},
data: function () {
return {
counter: this.initCounter
}
},
methods: {
methodClick: function () {
this.counter++;
}
}
});
Vue.component("test-default-slot", {
template: `
<div>
<slot
:initCounter="initCounter",
:counter="counter",
:methodClick="methodClick"
></slot>
</div>
`,
props: {
initCounter: {
type: Number,
required: true
}
},
data: function () {
return {
counter: this.initCounter
}
},
methods: {
methodClick: function () {
this.counter++;
}
}
})
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
</body> And the only thing I hate about this is passing all data, props and methods to @yyx990803 Is it possible to write some I'm asking for solution for Vue 2 but showing how it could be done in Vue 3 (with current rfc) would be also helpful when we'll do migration when Vue 3 is released. There's not much info on web about |
Maybe we use the term "build step" for different things, but this solution does not require any build tooling like webpack or whatever. Can you clarify? |
@LinusBorg I really want to avoid passing explicitly every prop, data and method that can be used in default slot. I want this "default slot" approach (which is proposed replacement for |
You don't really have to provide them one by one manually. You could do this:
<slot v-bind="self" /> |
@LinusBorg thanks! Nice workaround, but it doesn't pass other computed fields. Do you have some idea how to also pass them (without doing it one by one manually)?
Only |
Don't see an obvious reason why that should not work, no. |
@LinusBorg hmmm... so should I create a bug on https://github.com/vuejs/vue for it? |
It probably won't work because computed properties dependencies are lazily collected -- it doesn't matter if you track it via getters, like Vue 2, or proxies, like Vue 3. (I don't know why props don't work.) If you want that computed properties to be available, you should mention them explicitly: computed: {
counterPlusTen () {
return this.counter + 10
},
self () {
return {
...this,
counterPlusTen: this.counterPlusTen,
}
}
}, One could create a helper (I haven't tested it): computed: {
// ...
self () {
const self = { ...this, ...this.$props }
for (const key of Object.keys(this.$options.computed)) {
if (key !== 'self') {
self[key] = this[key
}
}
return self
},
} An important point to be made is that you may not need all properties to be available to the slot; the slot just need to contain the part of the template that's really dynamic. |
I'm left wondering at this point what the best practice is for integrating vue with lightweight, potentially nested components where the template(s) are php rendered (say) by blade or twig and client side code is contained in .vue files. Using slots isn't a drop in replacement, requiring and using Since the Apologies if this should be discussed elsewhere please point me in the right direction! |
@qgates a lot of the time you can convert to slots with just a few changes to your component, but you're right, it's not a drop-in replacement. If you want to use |
@imacrayon thanks for those thoughts. It just appears as though there's no strategy for using vue in a lightweight way in larger, tradition server side applications, where is served up from SS templates and we just want to add vue reactivity. The inline-template approach has its drawbacks, but has been widely used for this purpose. I'm all for change, but there should be some advice and best practice notes for using view in this way. Wasn't a fan of it listed under 'edge cases' in the original user guide either! 😉 |
For simply enhancing server-rendered markup, take a look at AlpineJS. It has Vue-inspired syntax but is specifically targeting the "enhancing server-rendered markup" use case. If Alpine doesn't fit the scale of your application, then you really should use a build setup. It's not that hard. |
Thanks @yyx990803, and sorry if my comments came over as complaint. It's not that it's hard per se, it's just that it's harder, especially for those invested in Vue 2 in large scale projects using the Straying off-topic, another example is the removal of
Care to elaborate? We're already using webpack on the client side. |
@qgates It may please you that Vue 3.0 doesn't have the same shortcomings related to props and computed properties. |
Thanks @leopiccionia, lots to like about Vue 3 and I'm learning all the time :-) |
Rendered