组件注册

全局注册

这些组件是全局注册的。也就是说它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中。

  1. Vue.component('my-component-name', {
  2. // ... 选项 ...
  3. })

在很多 Vue 项目中,我们使用 Vue.component 来定义全局组件,紧接着用 new Vue({ el: ‘#container ‘}) 在每个页面内指定一个容器元素。这种方式在很多中小规模的项目中运作的很好,在这些项目里 JavaScript 只被用来加强特定的视图。但当在更复杂的项目中,或者你的前端完全由 JavaScript 驱动的时候,下面这些缺点将变得非常明显:

  • 全局定义 (Global definitions) 强制要求每个 component 中的命名不得重复
  • 字符串模板 (String templates) 缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的 \
  • 不支持 CSS (No CSS support) 意味着当 HTML 和 JavaScript 组件化时,CSS 明显被遗漏
  • 没有构建步骤 (No build step) 限制只能使用 HTML 和 ES5 JavaScript,而不能使用预处理器,如 Pug (formerly Jade) 和 Babel

    局部注册

    ```javascript var ComponentA = { // } var ComponentB = { // } var ComponentC = { // }

new Vue({ el: ‘#app’, components: { ‘component-a’: ComponentA, ‘component-b’: ComponentB } })

  1. 可能你的许多组件只是包裹了一个输入框或按钮之类的元素,是相对通用的。我们有时候会把它们称为[基础组件](https://cn.vuejs.org/v2/style-guide/#%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6%E5%90%8D-%E5%BC%BA%E7%83%88%E6%8E%A8%E8%8D%90),它们会在各个组件中被频繁的用到。
  2. ```javascript
  3. import BaseButton from './BaseButton.vue'
  4. import BaseIcon from './BaseIcon.vue'
  5. import BaseInput from './BaseInput.vue'
  6. export default {
  7. components: {
  8. BaseButton,
  9. BaseIcon,
  10. BaseInput
  11. }
  12. }

单文件组件

文件扩展名为 .vue 的 single-file components (单文件组件) 为以上所有问题提供了解决方法,并且还可以使用 webpack 或 Browserify 等构建工具。

  • 完整语法高亮
  • CommonJS 模块
  • 组件作用域的 CSS

    分拆代码

    多文件

    在一个组件里,其模板、逻辑和样式是内部耦合的,并且把他们搭配在一起实际上使得组件更加内聚且更可维护。在写代码时,仍然可以把 JavaScript、CSS 分离成独立的文件然后做到热重载和预编译。
    1. <!-- my-component.vue -->
    2. <template>
    3. <div>This will be pre-compiled</div>
    4. </template>
    5. <script src="./my-component.js"></script>
    6. <style src="./my-component.css"></style>

    模板

    使用vue的编辑模板的功能。使用别的模板编译器,需要进行配置。
    1. <template>
    2. <div>{{ msg }} home2</div>
    3. </template>

    样式

    1. /*使用scss编写**

    逻辑

    ```javascript /**
  • home.js文件 */ import home3 from “./home3.vue”;

export default { name: “home”, data() { return { msg: “你好”, }; }, //此处不能使用箭头函数,this需要指向调用者 render: function () { return home3.render.apply(this); }, };

  1. <a name="VaWOv"></a>
  2. ### 小结
  3. 在开发医链项目时,将.vue当成一个组件,抽离部分重复共用的方法时较为困难。<br />多文件是将组件分为三个部分:样式、模板、逻辑。可以组合这些部分。
  4. <a name="SZdO7"></a>
  5. ## mixin复用功能
  6. 混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
  7. <a name="KCkg9"></a>
  8. ### data
  9. For example, data objects undergo a recursive merge, with the component’s data taking priority in cases of conflicts.
  10. ```javascript
  11. var mixin = {
  12. data: function () {
  13. return {
  14. message: 'hello',
  15. foo: 'abc'
  16. }
  17. }
  18. }
  19. new Vue({
  20. mixins: [mixin],
  21. data: function () {
  22. return {
  23. message: 'goodbye',
  24. bar: 'def'
  25. }
  26. },
  27. created: function () {
  28. console.log(this.$data)
  29. // => { message: "goodbye", foo: "abc", bar: "def" }
  30. }
  31. })

Hook functions

Hook functions with the same name are merged into an array so that all of them will be called. Mixin hooks will be called before the component’s own hooks.
同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。

Options

Options that expect object values, for example methods, components and directives, will be merged into the same object. The component’s options will take priority when there are conflicting keys in these objects:

  1. var mixin = {
  2. methods: {
  3. foo: function () {
  4. console.log('foo')
  5. },
  6. conflicting: function () {
  7. console.log('from mixin')
  8. }
  9. }
  10. }
  11. var vm = new Vue({
  12. mixins: [mixin],
  13. methods: {
  14. bar: function () {
  15. console.log('bar')
  16. },
  17. conflicting: function () {
  18. console.log('from self')
  19. }
  20. }
  21. })
  22. vm.foo() // => "foo"
  23. vm.bar() // => "bar"
  24. vm.conflicting() // => "from self"

Note that the same merge strategies are used in Vue.extend().

Global Mixin

You can also apply a mixin globally. Use with caution! Once you apply a mixin globally, it will affect every Vue instance created afterwards. When used properly, this can be used to inject processing logic for custom options:

  1. // inject a handler for `myOption` custom option
  2. Vue.mixin({
  3. created: function () {
  4. var myOption = this.$options.myOption
  5. if (myOption) {
  6. console.log(myOption)
  7. }
  8. }
  9. })
  10. new Vue({
  11. myOption: 'hello!'
  12. })
  13. // => "hello!"

Custom Option Merge Strategies

When custom options are merged, they use the default strategy which overwrites the existing value. If you want a custom option to be merged using custom logic, you need to attach a function to Vue.config.optionMergeStrategies.

Vue.extend( options )

  • Arguments:
    • {Object} options
  • Usage:Create a “subclass” of the base Vue constructor. The argument should be an object containing component options.


The special case to note here is the data option - it must be a function when used with Vue.extend().

  1. // create constructor
  2. var Profile = Vue.extend({
  3. template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
  4. data: function () {
  5. return {
  6. firstName: 'Walter',
  7. lastName: 'White',
  8. alias: 'Heisenberg'
  9. }
  10. }
  11. })
  12. // create an instance of Profile and mount it on an element
  13. new Profile().$mount('#mount-point')
  1. var MyComponent = Vue.extend({
  2. template: '<div>Hello!</div>'
  3. })
  4. // create and mount to #app (will replace #app)
  5. new MyComponent().$mount('#app')
  6. // the above is the same as:
  7. new MyComponent({ el: '#app' })
  8. // or, render off-document and append afterwards:
  9. var component = new MyComponent().$mount()
  10. document.getElementById('app').appendChild(component.$el)

extends

  • Type: Object | Function
  • Details:Allows declaratively extending another component (could be either a plain options object or a constructor) without having to use Vue.extend. This is primarily intended to make it easier to extend between single file components.This is similar to mixins. ```javascript var CompA = { … }

// extend CompA without having to call Vue.extend on either var CompB = { extends: CompA, … }

  1. <a name="vetrR"></a>
  2. ### 示例
  3. 一个vue组件about.vue。
  4. ```vue
  5. <template>
  6. <div class="about">
  7. <h1>This is an about page</h1>
  8. </div>
  9. </template>
  10. <script>
  11. export default {
  12. mounted(){
  13. console.log("about")
  14. }
  15. }
  16. </script>

一个home.js对 about.vue进行扩展。

  1. import About from "./About.vue";
  2. const Home = {
  3. extends: About,
  4. name: "Home",
  5. methods: {
  6. clickFn() {
  7. console.log("clickFn");
  8. },
  9. },
  10. mounted() {
  11. console.log("home");
  12. },
  13. };
  14. export default Home;