Vue.js - Cung cấp các chức năng trợ giúp trên toàn cầu cho các thành phần tệp đơn


100

Tôi có một dự án Vue 2 có nhiều (hơn 50) thành phần tệp đơn . Tôi sử dụng Vue-Router để định tuyến và Vuex cho trạng thái.

Có một tệp, được gọi là helpers.js , chứa một loạt các hàm có mục đích chung, chẳng hạn như viết hoa chữ cái đầu tiên của một chuỗi. Tệp này trông giống như sau:

export default {
    capitalizeFirstLetter(str) {
        return str.charAt(0).toUpperCase() + str.slice(1);
    }
}

Tệp main.js của tôi khởi tạo ứng dụng:

import Vue from 'vue'
import VueResource from "vue-resource"
import store from "./store"
import Router from "./router"
import App from "./components/App.vue"

Vue.use(VueResource)

const app = new Vue({
    router: Router,
    store,
    template: '<app></app>',
    components: { App }
}).$mount('#app')

Tệp App.vue của tôi chứa mẫu:

<template>
    <navbar></navbar>
    <div class="container">
        <router-view></router-view>
    </div>
</template>

<script>
export default {
    data() {
        return {
            //stuff
        }
    }
}
</script>

Sau đó, tôi có một loạt các thành phần tệp đơn, mà Vue-Router xử lý điều hướng đến bên trong <router-view>thẻ trong mẫu App.vue.

Bây giờ, hãy nói rằng tôi cần sử dụng capitalizeFirstLetter()hàm bên trong một thành phần được định nghĩa trong SomeComponent.vue . Để làm điều này, trước tiên tôi cần nhập nó:

<template>Some Component</template>

<script>
import {capitalizeFirstLetter} from '../helpers.js'
export default {
    data() {
        return {
            myString = "test"
        }
    },
    created() {
         var newString = this.capitalizeFirstLetter(this.myString)
    }
}
</script>

Điều này nhanh chóng trở thành một vấn đề vì tôi kết thúc việc nhập hàm vào nhiều thành phần khác nhau, nếu không phải tất cả chúng. Điều này có vẻ lặp đi lặp lại và cũng làm cho dự án khó duy trì hơn. Ví dụ: nếu tôi muốn đổi tên helpers.js hoặc các hàm bên trong nó, thì tôi cần phải đi vào từng thành phần duy nhất nhập nó và sửa đổi câu lệnh nhập.

Tóm lại: làm cách nào để làm cho các hàm bên trong helpers.js khả dụng trên toàn cầu để tôi có thể gọi chúng bên trong bất kỳ thành phần nào mà không cần phải nhập chúng trước rồi thêm vào thistên hàm? Về cơ bản tôi muốn có thể làm điều này:

<script>
export default {
    data() {
        return {
            myString = "test"
        }
    },
    created() {
         var newString = capitalizeFirstLetter(this.myString)
    }
}
</script>

Bạn có thể sử dụng một hỗn hợp toàn cầu, nhưng bạn sẽ phải sử dụng this.
Bert

2
Bạn đã xem xét việc hiển thị các trình trợ giúp của mình dưới dạng bộ lọc để chúng có thể được sử dụng trực tiếp trong các mẫu của bạn mà không cần nhập chúng chưa? Đó là chiến lược tôi đang thực hiện và nó đang hoạt động tốt cho đến nay.
David Weldon

Câu trả lời:


154

bên trong bất kỳ thành phần nào mà không cần phải nhập chúng trước và sau đó thêm nó vào tên hàm

Những gì bạn mô tả là mixin .

Vue.mixin({
  methods: {
    capitalizeFirstLetter: str => str.charAt(0).toUpperCase() + str.slice(1)
  }
})

Đây là một hỗn hợp toàn cầu. với điều này TẤT CẢ các thành phần của bạn sẽ có một capitalizeFirstLetterphương thức, vì vậy bạn có thể gọi this.capitalizeFirstLetter(...)từ các phương thức thành phần hoặc bạn có thể gọi nó trực tiếp như capitalizeFirstLetter(...)trong mẫu thành phần.

Ví dụ làm việc: http://codepen.io/CodinCat/pen/LWRVGQ?editors=1010

Xem tài liệu tại đây: https://vuejs.org/v2/guide/mixins.html


Đẹp quá! Cảm ơn!
Alexey Shabramov

20
Rất vui nếu có thêm chi tiết trong câu trả lời này như cách bạn lưu trữ hàm mixin trong tệp chuyên dụng của riêng nó và làm cách nào để bạn nhập hàm này vào main.js?
Alexis.Rolland

Làm thế nào tôi có thể sử dụng capitalizeFirstLettertừ một const vm = new Vue()phiên bản? Bởi vì vm.capitalizeFirstLetterkhông hoạt động.
Marcelo Rodovalho

Tất cả các thành phần sẽ tham chiếu đến capitalizeFirstLetterhàm trong mixin hay chúng sẽ có bản sao riêng của nó? Tôi đang tìm kiếm một nơi để lưu trữ một chức năng mà nên có thể truy cập đến tất cả các thành phần, nhưng mặt khác không liên quan đến họ (lấy dữ liệu từ một máy chủ để lưu trữ trong một kho vuex)
Daniel F

Cảm ơn ! Nó hoạt động tốt trong các thành phần nhưng không hoạt động trong "store.js". Tôi có một người kết hợp tùy chỉnh "console.log": "log: str => console.log ('% c' + str + '', 'background: #aaa; color: #fff; padding: 5px; border- bán kính: 5px ') ". Làm thế nào tôi có thể sử dụng nó trong store.js?
bArraxas

66

Nếu không, bạn có thể cố gắng làm cho trình trợ giúp của mình hoạt động như một plugin:

import Vue from 'vue'
import helpers from './helpers'

const plugin = {
  install () {
    Vue.helpers = helpers
    Vue.prototype.$helpers = helpers
  }
}

Vue.use(plugin)

Khi helper.jsxuất các chức năng của bạn, theo cách này:

const capFirstLetter = (val) => val.charAt(0).toUpperCase() + val.slice(1);
const img2xUrl = (val) => `${val.replace(/(\.[\w\d_-]+)$/i, '@2x$1')} 2x`;

export default { capFirstLetter, img2xUrl };

hoặc là

export default { 
  capFirstLetter(val) {
    return val.charAt(0).toUpperCase() + val.slice(1);
  },
  img2xUrl(val) {
    return `${val.replace(/(\.[\w\d_-]+)$/i, '@2x$1')} 2x`;
  },
};

Sau đó, bạn sẽ có thể sử dụng chúng ở bất kỳ đâu trong các thành phần của mình bằng cách sử dụng:

this.$helpers.capitalizeFirstLetter()

hoặc bất kỳ nơi nào trong ứng dụng của bạn bằng cách sử dụng:

Vue.helpers.capitalizeFirstLetter()

Bạn có thể tìm hiểu thêm về điều này trong tài liệu: https://vuejs.org/v2/guide/plugins.html


Vui lòng liệt kê nội dung của helpers.vue
Marius

Bạn có thể bao gồm một ví dụ về cách truy cập cửa hàng Vue? this. $ store hoạt động trong các thành phần, nhưng không hoạt động trong một mixin.
Marius

1
Nội dung của helpers.js là trong câu hỏi
Hammerbot

9

Tạo một bản mixin mới:

"src / mixins / generalMixin.js"

Vue.mixin({
  methods: {
    capitalizeFirstLetter(str) {
        return str.charAt(0).toUpperCase() + str.slice(1);
    }    
  }
})

Sau đó nhập nó vào main.js của bạn như:

import '@/mixins/generalMixin'

Từ bây giờ bạn sẽ có thể sử dụng chức năng như this.capitalizeFirstLetter(str)trong tập lệnh thành phần của bạn hoặc không thistrong một mẫu.

Bạn phải sử dụng thisvì bạn đã trộn một phương thức vào thể hiện Vue chính. Nếu có những cách để loại bỏ thisnó có thể sẽ liên quan đến điều gì đó không bình thường, thì đây ít nhất là một cách chia sẻ các chức năng được lập thành văn bản sẽ dễ hiểu cho bất kỳ nhà phát triển Vue nào trong tương lai cho dự án của bạn.


1

Sử dụng Webpack v4

Tạo một tệp riêng biệt để có thể đọc được (vừa được thả vào thư mục plugin). Sao chép từ phản hồi @CodinCat và @digout

//resources/js/plugins/mixin.js
import Vue from 'vue'

Vue.mixin({
    methods: {
      capitalizeFirstLetter: str => str.charAt(0).toUpperCase() + str.slice(1),
      sampleFunction(){
        alert('Global Functions')
      }
    }
  })

Sau đó nhập vào tệp main.js hoặc app.js của bạn

//app.js
import mixin from './plugins/mixin' 

SỬ DỤNG:

Gọi this.sampleFunction()hoặcthis.capitalizeFirstLetter()


1

Sử dụng bộ lọc chung nếu nó chỉ liên quan đến cách dữ liệu được định dạng khi hiển thị. Đây là ví dụ đầu tiên trong tài liệu :

{{ message | capitalize }}
Vue.filter('capitalize', function (value) {
  if (!value) return ''
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})

0

Câu hỏi tuyệt vời. Trong nghiên cứu của mình, tôi nhận thấy vue-injection có thể xử lý điều này theo cách tốt nhất. Tôi có nhiều thư viện hàm (dịch vụ) được giữ riêng biệt với các phương pháp xử lý logic thành phần vue tiêu chuẩn. Lựa chọn của tôi là để các phương thức thành phần chỉ là người ủy quyền gọi các chức năng dịch vụ.

https://github.com/jackmellis/vue-inject


-5

Nhập nó vào tệp main.js giống như 'store' và bạn có thể truy cập nó trong tất cả các thành phần.

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  store,
  router,
  render: h => h(App)
})

11
bạn có thể hoàn thành câu trả lời chỉ ra cách sử dụng nó trong một thành phần không?
JeanValjean
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.