Vue 2 component styles without Vue loader
Asked Answered
L

3

6

Considering that there is single file component (as shown in the guide),

<style>
.example {
  color: red;
}
</style>

<template>
  <div class="example">hi</div>
</template>

How can the same thing be done without Vue loader in non-modular ES5/ES6 environment?

Considering that the style is scoped,

<style scoped>
.example {
  color: red;
}
</style>

Is there a way to implement scoped CSS in non-modular environment, too? If there's none, is there a way to implement it in modular environment (Webpack), but without Vue loader and custom .vue format?

Lorettelorgnette answered 13/3, 2017 at 13:48 Comment(0)
A
6

Instead of using the template instance in the Vue component, you can harness a 'closer-to-the-compiler alternative' with the render function without the need for the Vue Loader or compiler. You can add any additional attributes with the second parameter in the createElement function and this will give you a lot of flexibility on top of just styles.

See the Render Functions section in the guide for more info and the full options allowed in the data obj:

https://v2.vuejs.org/v2/guide/render-function

https://v2.vuejs.org/v2/guide/render-function#The-Data-Object-In-Depth

Note: The caveat here is that the style will only apply to the component it is declared in, so it might not be able to used across multiple components of the same class like CSS would be. Not sure if thats also what you want to achieve.

An example from the docs catered to this use case:

Vue.component('example', {
    // render function as alternative to 'template'
    render: function (createElement) {
        return createElement(
            // {String | Object | Function}
            // An HTML tag name, component options, or function
            // returning one of these. Required.
            'h2',
            // {Object}
            // A data object corresponding to the attributes
            // you would use in a template. Optional.
            {
                style: {
                    color: 'red',
                    fontSize: '28px',
                },
                domProps: {
                    innerHTML: 'My Example Header'
                }
            },
            // {String | Array}
            // Children VNodes. Optional.
            []
    )}
});

var example = new Vue({
    el: '#yourExampleId'
});
Aliment answered 7/4, 2017 at 2:26 Comment(1)
Yes, thanks, it looks to me that render function is the only available way to do this for now.Lorettelorgnette
V
0

It can be achieved putting the scope manually, as vue-loader does automatically.

This is the example of the documentation. Adding some kind of ID, "_v-f3f3eg9" in this case, to scope the class only for that element.

<style>
.example[_v-f3f3eg9] {
  color: red;
}
</style>

Vue.component('my-component', {
    template: '<div class="example" _v-f3f3eg9>hi</div>'
});
Villar answered 13/3, 2017 at 20:19 Comment(1)
But .vue file with <style>...</style><template>...</template> requires Vue loader. How can this be achieved without Vue loader?Lorettelorgnette
S
-1

I use Rollup (+ Bublé) + Vue.js all the time. It's pretty simple and fast.

The Rollup config is like:

import vue from 'rollup-plugin-vue';
import resolve from 'rollup-plugin-node-resolve';
import buble from 'rollup-plugin-buble';

const pkg = require('./package.json');
const external = Object.keys(pkg.dependencies);

export default {
  external,
  globals: { vue: 'Vue' },
  entry: 'src/entry.js',
  plugins: [
    resolve(),
    vue({ compileTemplate: true, css: true }),
    buble({ target: { ie: 9 }})
  ],
  targets: [
    { dest: 'dist/vue-rollup-example.cjs.js', format: 'cjs' },
    { dest: 'dist/vue-rollup-example.umd.js', format: 'umd' }
  ]
};

I've made a boilerplate repo:

git clone https://github.com/jonataswalker/vue-rollup-example.git
cd vue-rollup-example
npm install
npm run build
Sienna answered 16/3, 2017 at 17:46 Comment(3)
Thanks for the example, it's illustrative. Didn't know about Buble. However, the thing I'm interested in how to use Vue in plain JS, without transpilation and building. Component styles in particular.Lorettelorgnette
Oh no, the browser will never understand Component styles. Necessarily you will need a build step.Sienna
I'm quite sure it is doable in Vue, but not sure how. Just because Vue loader should compile .vue to something. And just because rival frameworks fully support vanilla ES5, and not supporting it would be a nonsense for Vue.Lorettelorgnette

© 2022 - 2024 — McMap. All rights reserved.