0%

vue

1 vue简介

Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面

Vue 是一个框架,也是一个生态。其功能覆盖了大部分前端开发常见的需求。但 Web 世界是十分多样化的,不同的开发者在 Web 上构建的东西可能在形式和规模上会有很大的不同。考虑到这一点,Vue 的设计非常注重灵活性和“可以被逐步集成”这个特点。根据你的需求场景,你可以用不同的方式使用 Vue:

  • 无需构建步骤,渐进式增强静态的 HTML
  • 在任何页面中作为 Web Components 嵌入
  • 单页应用 (SPA)
  • 全栈 / 服务端渲染 (SSR)
  • Jamstack / 静态站点生成 (SSG)
  • 开发桌面端、移动端、WebGL,甚至是命令行终端中的界面

2. 安装和创建一个vue项目

  • 安装vue
    1
    $ npm install vue@^2
  • 全局安装vue CLI。Vue CLI是一个基于Node.js的全局npm包,它提供了标准化的项目结构和开发流程
    1
    npm install -g @vue/cli  
  • 快速搭建vue应用
1
2
3
4
5
6
7
vue create myproject-veutest --default
cd myproject-veutest
npm install
npm run dev
DONE Compiled successfully in 4388ms

> Listening at http://localhost:8080

项目打包:打包 Vue 项目使用以下命令:

1
>npm run build
执行完成后,会在 Vue 项目下生成一个 dist 目录,一般包含 index.html 文件及 static 目录,static 目录包含了静态文件 js、css 以及图片目录 images。

2.1 项目的目录结构

上面我们使用npm创建了项目,打开myproject-vuetest后,其目录有如下:

目录/文件 说明
build 项目构建(webpack)相关代码
config 配置目录,包括端口号等。我们初学可以使用默认的。
node_modules npm 加载的项目依赖模块
src 这里是我们要开发的目录,基本上要做的事情都在这个目录里。里面包含了几个目录及文件:
assets:放置一些图片,如logo等。
components: 目录里面放了一个组件文件,可以不用。
App.vue: 项目入口文件,我们也可以直接将组件写这里,而不使用 components 目录。
main.js: 项目的核心文件。
static 静态资源目录,如图片、字体等。
test 初始测试目录,可删除
.xxxx文件 这些是一些配置文件,包括语法配置,git配置等。
index.html 首页入口文件,你可以添加一些 meta 信息或统计代码啥的。
package.json 项目配置文件。
README.md 项目的说明文档,markdown 格式

3. 重要的vue指令

  • v-bind:v-bind 用于动态地绑定一个或多个属性,或一个组件 prop 到表达式。当表达式的值改变时,该属性将会更新。(可简写为:)

    1
    2
    3
    4
    #将src绑定到imageSrc上
    <img v-bind:src="imageSrc" />
    <!-- 简写形式 -->
    <img :src="imageSrc" />

  • v-text:v-text 指令用于更新元素的 textContent。它会覆盖元素中原有的内容。

    1
    2
    3
    4
    5
    #输出message的文本内容
    <span v-text="message"></span>
    <!-- 简写形式(Vue 2.x 不支持简写) -->
    <!-- Vue 3.x 中也没有直接简写,但你可以使用插值表达式 {{ }} -->
    <span>{{ message }}</span>

  • v-if: 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。并且页面源码不会被隐藏
    1
    2
    #showMessage为true时,才显示文本Hello, Vue!
    <div v-if="showMessage">Hello, Vue!</div>
  • v-elsev-else指令表示v-ifv-else-if 条件块之后的“else 块”。v-else 元素必须紧跟在带 v-if 或 v-else-if 元素的兄弟元素之后,否则它将不会被识别。

    1
    2
    3
    <div v-if="condition1">条件1</div>  
    <div v-else-if="condition2">条件2</div>
    <div v-else>其他情况</div>

  • v-show:根据条件来显示或隐藏元素。元素始终保持在 DOM 中,其低层原理是通过改变 display属性的值进行切换因此源码在不显示时会被隐藏

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <template>  
    <div>
    <p v-show="isVisible">这个段落是可见的。</p>
    <button @click="toggleVisibility">切换可见性</button>
    </div>
    </template>
    <script>
    export default {
    data() {
    return {
    isVisible: true // 初始状态为可见
    };
    },
    methods: {
    toggleVisibility() {
    this.isVisible = !this.isVisible; // 切换 isVisible 的值
    }
    }
    }
    </script>
    <style scoped>
    /* 这里的样式是可选的,仅为了说明可以添加样式 */
    p {
    transition: opacity 0.5s ease; /* 添加过渡效果,使显示和隐藏更平滑 */
    }
    </style>

  • v-for:基于数组或对象来渲染一个列表。注意在使用 v-for 时,应该提供一个唯一的 :key 绑定,以帮助 Vue 跟踪每个节点的身份,从而重用和重新排序现有元素。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <ul>  
    <li v-for="(item, index) in items" :key="index">
    {{ item }}
    </li>
    </ul>
    <script>
    new Vue({
    el: '#app',
    data: {
    items: ['Apple', 'Banana', 'Cherry']
    }
    })
    </script>
    >在这个例子中,v-for 指令用于在 items 数组上循环输出元素。:key 是一个特殊的绑定,用于给每个循环的元素提供一个唯一的 key,帮助 Vue 跟踪每个节点的身份。

  • v-on:用于监听 DOM 事件,并在触发时运行一些 JavaScript 代码。如 @click 或 v-on:click。(可简写为@

    1
    2
    3
    <button v-on:click="handleClick">点击我</button>  
    <!-- 简写形式 -->
    <button @click="handleClick">点击我</button>

  • v-model:创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。主要用于表单输入元素,如 <input>、<textarea><select>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <input v-model="message" placeholder="输入信息">  
    #new的方式创建一个vue实例
    <script>
    new Vue({
    el: '#app',
    data: {
    message: ''
    }
    })
    </script>
    >在这个例子中,v-model 指令将 input 元素和 Vue 实例中的 message 属性建立了双向数据绑定。当用户在 input 元素中输入信息时,Vue.js 会自动更新 message 属性的值。

  • v-once:v-once 关联的实例,只会渲染一次。之后的重新渲染,实例及其所有的子节点将被视为静态内容忽略。这可以用于优化更新性能。

4 重要的vue属性1

  • el 属性:用来指示 Vue 编译器从什么地方开始解析 Vue 的语法,通常是一个占位符。

  • data 属性:用来组织从视图中抽象出来的属性,即视图的数据抽象存放在 data 中。data 是一个特殊的选项,它用于存储组件的私有状态。这些状态可以是简单的变量(如字符串、数字、布尔值等),也可以是数组、对象等复杂类型。data 中的属性是响应式的,意味着当它们改变时,视图会自动更新。
    • 函数形式:data 必须是一个函数,而不是一个对象。这是因为每个组件实例都有自己的 data 对象副本,而对象形式的 data 会导致多个组件实例共享同一个数据对象,这是不安全的。通过将 data 定义为函数,我们可以确保每个组件实例都有自己独立的数据副本。
    • 响应式:data 中的属性是响应式的,但 Vue 不能检测对象属性的添加或删除。如果你需要添加或删除属性,并且希望这些变化能够触发视图更新,你应该使用 Vue.set 方法或 Object.assign 方法来添加属性,或者使用 Vue.delete 方法来删除属性。
    • 避免直接修改 props:虽然 data 和 props 都是用于存储组件的状态,但你应该避免直接修改从父组件传入的 props。如果 props 的值需要被修改,你应该在 data 中创建一个新的状态变量,并使用 props 的值来初始化它。这样,你就可以安全地修改 data 中的状态,而不会影响到父组件或其他子组件。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      <template>  
      <div>
      <p>Message: {{ message }}</p>
      <button @click="changeMessage">Change Message</button>
      </div>
      </template>
      <script>
      export default {
      data() {
      return {
      message: 'Hello Vue!'
      };
      },
      methods: {
      changeMessage() {
      this.message = 'Hello, world!';
      }
      }
      };
      </script>
  • methods 属性:放置页面中的业务逻辑,JS 方法一般都放置在 methods 中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <template>  
    <div>
    <p>{{ message }}</p>
    <button @click="reverseMessage">Reverse</button>
    </div>
    </template>
    #export方式
    <script>
    export default {
    data() {
    return {
    message: 'Hello, Vue!'
    };
    },
    methods: {
    reverseMessage() {
    this.message = this.message.split('').reverse().join('');
    }
    }
    }
    </script>
    >在这个例子中,我们定义了一个 Vue 组件,其中包含了数据 message 和一个方法 reverseMessage。当按钮被点击时,reverseMessage 方法会被调用,从而改变 message 的值。

  • computed 属性:用于计算 Vue.js 计算属性,当依赖的数据发生变化时,计算属性会重新求值。允许我们定义基于其他属性的计算属性。这些计算属性是响应式的,并且只有当其依赖的数据属性发生变化时才会重新计算
    • 特点:
      • 基于依赖进行缓存:computed属性的值会被缓存,并且只有在相关依赖属性发生变化时才会重新计算。这可以避免重复计算,提高代码效率。
      • 自动更新:computed属性的值会根据相关依赖的变化而自动更新,无需手动触发。
      • 使用函数返回结果:computed属性的定义类似于普通的属性,但需要使用函数来返回计算结果。
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        new Vue({  
        data: {
        firstName: 'John',
        lastName: 'Doe'
        },
        computed: {
        fullName: {
        get: function () {
        return this.firstName + ' ' + this.lastName;
        },
        set: function (newValue) {
        var names = newValue.split(' ');
        this.firstName = names[0];
        this.lastName = names[names.length - 1];
        }
        }
        }
        });
        >在上面的例子中,我们定义了一个名为fullName的计算属性,它根据firstName和lastName计算得出。同时,我们还为fullName定义了setter方法,以便当fullName被赋值时能够更新firstName和lastName的值。 > >在Vue的模板中,我们可以像使用普通属性一样使用computed属性。Vue会自动处理计算属性的依赖关系,并在相关数据变化时更新计算属性。 > >
        1
        ><div>{{ fullName }}</div>
        >在这个例子中,我们直接在模板中使用了fullName计算属性。当firstName或lastName发生变化时,fullName的值会自动更新,并且模板中的显示也会相应地更新。
  • watch 属性:Vue.js 监听属性,可以通过 watch 来响应数据的变化。当需要在数据变化时执行异步操作或开销较大的操作时,watch 是一个非常有用的工具。下面做一个简单介绍
    • 在 Vue 实例或组件的 watch 属性中,可以定义一个或多个观察器。每个观察器都是一个函数或对象,用于指定要观察的数据属性和当该数据属性变化时执行的回调函数。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      new Vue({  
      el: '#app',
      data: {
      nestedObj: {
      prop: 'Hello'
      }
      },
      watch: {
      nestedObj: { //观察的对象是nestedObj
      handler(newValue, oldValue) {
      console.log('nestedObj changed');
      },
      deep: true // 深度监听
      }
      }
      });
  • 生命周期钩子:Vue 实例从创建到销毁的过程中,会经历一系列的事件,这些事件被称为 Vue 的生命周期钩子。包括 beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy 和 destroyed 等。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <script>  
    export default {
    // ...其他选项...
    created() {
    console.log('Component has been created!');
    },
    mounted() {
    console.log('Component has been mounted to the DOM!');
    }
    // ...其他生命周期钩子...
    }
    </script>
    >在这个例子中,我们使用了createdmounted 这两个生命周期钩子。当组件被创建时,created 钩子会被调用;当组件被挂载到 DOM 时,mounted 钩子会被调用。这些钩子允许我们在组件的不同阶段执行特定的操作。

  • props:props(属性) 是 Vue.js 中组件间通信的一种重要方式,用于父组件向子组件传递数据。在 Vue.js 中,组件是可复用的 Vue 实例,带有可复用的模板和逻辑。props 使我们可以明确地向子组件传递数据,而不需要依赖全局状态管理或其他方法。
    • 使用
      • 子组件需要明确声明props,可以通过字符串数组或对象的形式来定义。
      • 父组件通过组件标签上的属性将数据传递给子组件。
      • 当使用非字符串模板时,prop的名字形式会从camelCase(驼峰命名)转为kebab-case(短横线命名)
    • 特性
      • Prop是单向数据流,只能从父组件流向子组件。子组件不能直接修改props的值,只能通过父组件来修改。
      • 可以通过v-bind(或简写为:)来动态绑定props的值到父组件的数据上。这样当父组件的数据变化时,子组件也会得到更新。
      • Props可以进行类型验证、设置默认值等,以确保接收到的数据符合期望。
        1
        2
        3
        4
        5
        6
        7
        // 子组件定义  
        Vue.component('child-component', {
        props: ['message'],
        template: '<span>{{ message }}</span>'
        })
        // 父组件使用
        <child-component message="Hello, Vue!"></child-component>
        >在这个示例中,父组件通过message属性向子组件传递了一个字符串"Hello, Vue!",子组件在模板中使用了这个prop来显示内容。

注意:

  • new vue:显示创建了一个vue实例,这个实例包含了data、methods、computed、watch、template
  • export default:导出的是一个 Vue 组件对象,而不是一个直接的 Vue 实例,这个组件对象包含了定义该组件所需的所有选项,如 data、methods、computed、watch、template等,当年将这个组件挂载到DOM上时,vue会根据这个组件自动创建一个或多个对于的实例

5 vue重要属性2

  • template:template 是 Vue.js 组件中的一个选项,用于定义组件的 HTML 模板。它可以是内联的 HTML 字符串,也可以是一个选择器,用于在 HTML 文档中查找已存在的模板。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Vue.component('my-component', {  
    data: function() {
    return {
    message: 'Hello, Vue!'
    };
    },
    template: `
    <div>
    <h1>{{ message }}</h1>
    <button @click="changeMessage">Change Message</button>
    </div>
    `,
    methods: {
    changeMessage: function() {
    this.message = 'Hello, World!';
    }
    }
    });
  • render:render 是一个函数,它使用 Vue 的虚拟 DOM 来构建组件的 HTML 结构。在复杂的应用中,render 函数通常用于编写更复杂的逻辑和渲染条件。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    Vue.component('my-component', {  
    data: function() {
    return {
    message: 'Hello, Vue!'
    };
    },
    render: function(createElement) {
    return createElement('div', [
    createElement('h1', this.message),
    createElement('button', {
    on: {
    click: this.changeMessage
    }
    }, 'Change Message')
    ]);
    },
    methods: {
    changeMessage: function() {
    this.message = 'Hello, World!';
    }
    }
    });
  • components:components 选项用于在 Vue 组件中注册子组件。这使得我们可以在父组件的模板中使用子组件。在 Vue.js 中,你可以定义自己的组件,并在其他 Vue 实例或组件的模板中使用它们,后续详解

  • filters:filters 选项用于定义全局或组件级别的文本过滤器。过滤器可以用于在 mustache 插值({{ }})v-bind 表达式中,用于在显示之前对文本进行格式化。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Vue.filter('uppercase', function(value) {  
    if (!value) return ''
    value = value.toString()
    return value.toUpperCase()
    })
    new Vue({
    el: '#app',
    data: {
    message: 'hello'
    }
    })

6 component

Vue.js 中可以自定义组件。在 Vue.js 中,你可以定义自己的组件,并在其他 Vue 实例或组件的模板中使用它们。以下是关于如何使用 的步骤

6.1 定义组件

在Vue中,export default是一种ES6模块语法的特性,用于将一个模块或对象的默认导出。对于Vue组件来说,你可以使用export default来导出你的组件定义,然后在其他文件中通过import语句来引入并使用这个组件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- MyComponent.vue -->  
<template>
<div>这是一个自定义组件</div>
</template>

<script>
export default {
name: 'MyComponent',
// 其他组件选项,如data、methods、props等
}
</script>

<style scoped>
/* 组件的样式 */
</style>

6.2 使用该组件

在使用这个组件时,你需要导入这个组件,并且做全局注册或者局部注册后再使用,或者直接再模板中使用:

  • 局部注册

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 引入组件  
    import MyComponent from './MyComponent.vue'

    // 注册并使用组件
    new Vue({
    el: '#app',
    components: {
    'my-component': MyComponent // 这里你可以使用其他名称来注册组件,但在模板中需要使用这个名称
    }
    })

  • 全局注册

    1
    2
    3
    4
    5
    Vue.component('my-component', {  
    // 组件选项
    template: '<div>这是一个自定义组件</div>',
    // 还可以有 data、methods、props 等其他选项
    });

  • 模板中像HTNL元素一样使用

    1
    2
    3
    <div id="app">  
    <my-component></my-component>
    </div>
    因为你的组件设置了,因此整体模板等价于这样:
    1
    2
    3
    <div id="app">  
    <div>这是一个自定义组件</div>
    </div>

6.3 例子

props 是 Vue 组件中非常重要的一个概念,它允许你向子组件传递数据。你可以将 props 当作子组件的属性来使用,这些属性可以在子组件的模板、计算属性、方法以及生命周期钩子中被访问和使用。

在定义组件时,你可以在组件的 props 选项中声明一个属性列表,并指定它们的类型、默认值、是否必传等。然后,在父组件中使用子组件时,可以通过特性(attribute)的方式向子组件传递这些 props

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- MyComponent.vue -->  
<template>
<div>
<p>接收到的消息是:{{ message }}</p>
</div>
</template>

<script>
export default {
name: 'MyComponent',
props: {
// 声明一个名为 message 的 prop
message: {
type: String, // 指定类型为字符串
required: true, // 指定该 prop 是必传的
default: '默认消息' // 指定默认值(可选)
}
}
}
</script>

在另一个文件使用MyComponent.vue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  
<!-- App.vue 或其他使用 MyComponent 的地方 -->
<template>
<div id="app">
<!-- 使用 MyComponent 并传递 message prop -->
<MyComponent message="这是从父组件传递的消息"></MyComponent>
</div>
</template>

<script>
import MyComponent from './MyComponent.vue';

export default {
name: 'App',
components: {
MyComponent
}
}
</script>
在上面的例子中,MyComponent 组件声明了一个名为 message 的 prop,类型为 String,并且必传。然后,在 App 组件的模板中,我们使用了 MyComponent 并向其传递了一个 message prop,其值为 "这是从父组件传递的消息"。这样,MyComponent 组件就可以在其模板中通过插值 来显示这个消息了。

注意,子组件应该避免修改通过 props 传递进来的数据,因为这可能会导致数据流变得难以理解和维护。如果子组件需要基于 props 的值来改变其状态,它应该使用 data 或 computed 属性来保存这个状态,而不是直接修改 props。