2
votes

I have been trying to get caught up to speed with Vue.js and am working on an asp.net mvc 5 web application that heavily uses jQuery and I would like to start integrating Vue and start replacing jQuery.

I have spent a couple days now trying to integrate Vue into an asp.net mvc 5 web application and with the help of this Best approach when replacing jQuery with VueJS 2 in multi-page existing .NET MVC application, and followed 1_bug's answer.

So in the project that I am hoping to integrate Vue, I am thinking of using components in the partial views first before tackling the the other views.

So in short my question is, how to use Vue components (IE: *.vue files) inside partial views?

2

2 Answers

1
votes

I was able to integrate Vue v.2.6 in my ASP.NET Core project without JavaScript bundler using partial views. It should work the same way in a ASP.NET MVC project.

Please check my answer to How do I set up ASP.NET Core + Vue.js? or the sample project on Github for details: ASP.NET Core + Vue.js

I also wrote a step by step description of Using Vue Components in ASP.NET Core at Medium.

0
votes

This is how I do it. .Vue files are only possible if you use vue-loader (webpack) but as ours is a legacy project, that's not possible

$("vue-category-gallery").each(function () {
    new Vue({
        el: this,
        data: () => ({
            action: "",
            categoryList: []
        }),
        beforeMount: function () {
            const actionAttribute = this.$el.attributes["data-action"];
            if (typeof actionAttribute !== "undefined" && actionAttribute !== null) {
                this.action = actionAttribute.value;
            } else {
                console.error("The data-attribute 'action' is missing for this component.");
            }
        },
        mounted: function () {
            if (this.action !== "") {
                CategoryService.getGalleryCategoryList(this.action).then(response => {
                    this.categoryList = response.data;
                });
            }
        },
        methods: {
            // none
        },
        template: `
            <div class="c-category-gallery" v-if="categoryList.length > 0">
                <div class="row">
                    <div class="col-md-3 col-sm-4" v-for="category in categoryList" :key="category.id">
                        <div class="c-category-gallery__item">
                            <img :src="category.imageUrl" :alt="category.name" class="img-responsive"></img>
                            <div class="c-category-gallery__item-content">
                                <h4>{{ category.name }}</h4>
                                <ul class="list-unstyled">
                                    <li v-for="subCategory in category.subCategoryList" :key="subCategory.id">
                                        <a :href="subCategory.categoryUrl" v-if="subCategory.showCategoryUrl">{{ subCategory.name }}</a>
                                    </li>
                                </ul>
                                <a :href="category.categoryUrl" v-if="category.showCategoryUrl">{{ category.detailName }}</a>
                            </div>
                        </div>
                    </div>
                </div>
            </div>`
    });
})

Calling it from HTML goes as follows...

<vue-category-gallery 
    data-action="/api/categories/getcategorygallerylist?itemCount=4"
    v-cloak></vue-category-gallery>

I am currently looking into Vue.component("", ...) but that's still in testing :)

EDIT:

With Vue.component("", ...)

Vue.component("vue-person", {
    props: ["name"],
    data: function () {
        return {
            type: "none",
            age: 0
        }
    },
    template: `<div>
                   <p>My name is {{name}}.</p>
                   <p>I am {{type}} and age {{age}}.</p>
               </div>`
})

var vm = new Vue({
    el: "vue-components",
    components: [
        "vue-person"
    ]
})

$(".js-change-value").on("click", function () {
    vm.$refs.myPersonComponent.type = "human";
    vm.$refs.myPersonComponent.age = 38;
})

<vue-components>
    <vue-person name="Kevin" ref="myPersonComponent"></vue-person>
    <button type="button" class="js-change-value">Change value</button>
</vue-components>

I would love to be able to omit the wrapper but as I'm already using other instances (new Vue()) on my page, I couldn't use for example '#main' (being the id on the body element) as it clashes with other global instances I already have on my page.