继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Vue3学习:新手入门与实战指南

慕虎7371278
关注TA
已关注
手记 1307
粉丝 202
获赞 877
概述 Vue3学习涵盖了从基础概念到高级特性的全面介绍,包括Vue3相对Vue2的主要改进、开发环境搭建、组件开发、响应式原理与实践以及路由和状态管理等内容。此外,文章还通过一个简单的实战项目案例,展示了如何使用Vue3、Vue Router和Vuex构建完整的应用。通过本文,读者可以深入理解并掌握Vue3的各项核心功能。
Vue3基础概念介绍

什么是Vue3

Vue.js 是一个渐进式前端框架,它允许你以渐进的方式将 Vue 添加到现有的项目中。Vue3 是 Vue.js 的最新版本,它引入了大量的改进,包括更好的性能、更小的打包体积、更易于调试的错误信息等。Vue3 采用了一种称为 Proxy 的 JavaScript 特性,用以替代 Vue2 中使用的基于 Object.defineProperty 的代理机制,从而实现了更高效的状态管理。

Vue3相对Vue2的主要改进

Vue3 相比 Vue2 的主要改进在以下几个方面:

  1. 更好的性能:Vue3 通过优化内部结构,可以更快地更新视图。特别是对于复杂组件,Vue3 可以减少不必要的 DOM 操作。

  2. 更小的打包体积:Vue3 的核心库体积更小,这意味着它在浏览器中的加载速度更快。这主要是因为 Vue3 对模板编译器进行了重构,减少了编译器的大小。

  3. 更好的工具支持:Vue3 提供了更详细的错误信息和警告,使得调试更为简单。同时,它也支持 TypeScript,这使得 Vue3 对于那些希望在开发过程中使用静态类型的人来说更加实用。

  4. 更好的兼容性:Vue3 兼容了更多的浏览器版本和 JavaScript 运行时环境,包括一些更现代的特性,如 Proxy

  5. Composition API:Vue3 引入了一个新的 API,称为 Composition API,它允许开发者更灵活地组织组件逻辑。Composition API 通过 refreactive 提供一种声明性的方式来管理状态。

安装Vue3的开发环境

安装 Vue3 的开发环境,首先需要安装 Node.js。请确保你已经安装了 Node.js 的最新版本。接下来,你可以使用 Vue CLI 来搭建一个新的 Vue 项目。

步骤1:全局安装 Node.js

# 安装 Node.js
sudo apt update
sudo apt install nodejs
sudo apt install npm

步骤2:全局安装 Vue CLI

npm install -g @vue/cli

步骤3:创建一个新的 Vue 项目

vue create my-vue3-project

在创建项目的过程中,Vue CLI 会询问你一些关于项目配置的问题。选择一个预设或手动配置你的项目设置。选择 Vue 3 作为版本。

步骤4:启动开发服务器

创建完项目后,你可以在项目的根目录下运行以下命令来启动开发服务器:

npm run serve

这会启动一个本地开发服务器,你可以在浏览器中通过 http://localhost:8080 访问你的 Vue 应用。

Vue3项目搭建入门

使用Vue CLI快速搭建项目

Vue CLI 是一个命令行工具,可以用来快速搭建 Vue 项目。通过它,你可以轻松地创建一个新的 Vue 项目,并且可以很方便地进行配置和扩展。

步骤1:使用 Vue CLI 创建新项目

vue create my-vue3-project

在创建项目时,Vue CLI 会问你一些配置选项。如果你是新手,选择默认的设置即可。如果你对项目有特殊的要求,可以选择手动配置项目设置。

步骤2:选择 Vue 3 作为版本

在创建新项目时,Vue CLI 会询问你选择一个预设或手动选择特性。选择 Vue 3 作为版本,这样你就可以开始使用 Vue 3 的新特性了。

项目的基本结构与文件管理

一个 Vue 项目的基本结构如下:

my-vue3-project/
├── node_modules/
├── public/
│   └── index.html
├── src/
│   ├── assets/
│   ├── components/
│   ├── App.vue
│   └── main.js
├── .gitignore
├── babel.config.js
├── package.json
└── vue.config.js
  • node_modules/:存放项目依赖的模块。
  • public/:存放静态文件,如 index.html
  • src/:存放项目源代码。
    • assets/:存放静态资源,如图片、字体等。
    • components/:存放可复用的组件。
    • App.vue:应用的主组件。
    • main.js:应用的入口文件。
  • .gitignore:定义 Git 托管代码时需要忽略的文件。
  • babel.config.js:Babel 配置文件,用于将 ES6+ 代码转译为兼容性更好的 JavaScript。
  • package.json:项目信息文件,包含版本号、依赖和脚本命令等。
  • vue.config.js:Vue CLI 的配置文件,可以自定义一些项目配置。

配置开发环境

在开始开发之前,你需要确保你的开发环境已经正确配置好。一般情况下,使用 Vue CLI 创建的项目已经为你配置好了基础的开发环境。例如,package.json 中包含了一些有用的脚本命令,例如:

{
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  }
}

这些命令分别用于启动开发服务器、构建生产环境代码和进行代码格式检查。

Vue3组件开发

组件的基本使用方法

在 Vue 中,组件是构建应用的基本单元。每个组件通常包括一个模板、一个逻辑部分和一个样式部分。

创建组件

创建一个新的组件文件,例如 HelloWorld.vue

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>
      For a guide and recipes on how to configure / customize this project,
      check out the
      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>
    </p>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  }
}
</script>

<style scoped>
.hello {
  background-color: #eee;
}
</style>

在这段代码中:

  • <template> 标签内的内容是组件的模板。
  • <script> 标签内的内容是组件的逻辑代码,使用 export default 导出一个对象,这个对象包含组件的配置信息。
  • <style> 标签内的内容是组件的样式,使用 scoped 属性来使样式仅作用于当前组件。

使用组件

在父组件中使用子组件:

<template>
  <div id="app">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

这里,我们通过 import 语句导入 HelloWorld 组件,并在 components 选项中注册它。在模板中,我们使用 <HelloWorld> 标签来引用这个组件,并传递 msg 属性。

传递属性和插槽的使用

传递属性

在前面的例子中,我们已经看到了如何通过 props 来传递属性给子组件。这里再详细解释一下。

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: {
      type: String,
      required: true
    }
  }
}
</script>

这里,我们通过 props 选项来定义 msg 属性。type 属性指定了属性的类型,required 属性表示这个属性是必需的。

在父组件中使用:

<template>
  <div id="app">
    <HelloWorld msg="Hello from Parent"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

使用插槽

插槽允许你将父组件的内容传递给子组件,以实现细粒度且灵活的布局。默认插槽用于向组件模板中的指定位置插入内容,具名插槽则允许你向组件模板中的多个位置插入内容。

<template>
  <div class="hello">
    <slot name="header"></slot>
    <h1>Hello from {{ name }}</h1>
    <slot name="footer"></slot>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    name: String
  }
}
</script>

在父组件中使用:

<template>
  <div id="app">
    <HelloWorld name="Vue3">
      <template v-slot:header>
        <h2>Header</h2>
      </template>
      <template v-slot:footer>
        <p>Footer</p>
      </template>
    </HelloWorld>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

组件之间的通信

组件之间的通信主要包括父组件向子组件传递数据(通过 props)和子组件向父组件传递数据(通过 事件)。

父组件向子组件传递数据

通过 props,父组件可以向子组件传递数据。上文已经展示了如何通过 props 传递字符串类型的属性,下面展示如何传递对象或数组类型的属性。

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>{{ user.name }} is {{ user.age }} years old.</p>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String,
    user: Object
  }
}
</script>

在父组件中使用:

<template>
  <div id="app">
    <HelloWorld
      msg="Hello from Parent"
      :user="{ name: 'John Doe', age: 30 }"
    />
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

子组件向父组件传递数据

子组件可以通过 $emit 方法向父组件发送事件,父组件可以通过 v-on 指令监听这些事件。

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <button @click="sendDataToParent">Send Data</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  methods: {
    sendDataToParent() {
      this.$emit('data-sent', 'Hello from Child')
    }
  }
}
</script>

在父组件中使用:

<template>
  <div id="app">
    <HelloWorld
      msg="Hello from Parent"
      @data-sent="handleDataFromChild"
    />
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  },
  methods: {
    handleDataFromChild(data) {
      console.log(data)
    }
  }
}
</script>
Vue3响应式原理与实践

响应式系统的原理

Vue3 使用了 Proxy 对象来实现响应式系统,Proxy 是 ES6 引入的一种新的语言特性,它允许你创建一个对象的代理,并在访问或修改对象属性时拦截并处理这些操作。通过 Proxy,Vue3 能够在属性被访问或修改时自动触发视图更新。

数据劫持

在 Vue3 中,响应式数据通常通过 refreactive 函数来创建。ref 用于创建一个带有 .value 属性的可变引用,而 reactive 则用于直接创建一个响应式对象。

import { ref, reactive } from 'vue'

const count = ref(0)
const state = reactive({
  count: 0
})

console.log(count.value) // 输出 0
console.log(state.count) // 输出 0

count.value++
state.count++

console.log(count.value) // 输出 1
console.log(state.count) // 输出 1

计算属性

计算属性是基于组件内的数据进行计算,并随时响应变化的数据。计算属性和普通方法的主要区别在于计算属性会基于其依赖缓存,只有依赖发生改变时才会重新计算。

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { ref, computed } from 'vue'

export default {
  setup() {
    const count = ref(0)

    const doubleCount = computed(() => {
      return count.value * 2
    })

    const increment = () => {
      count.value++
    }

    return {
      count,
      doubleCount,
      increment
    }
  }
}
</script>

常见的响应式编程技巧

使用 watch 监听数据变化

watch 可以用来监听一个响应式数据的变化。每当被监听的数据发生变化时,watch 会触发回调函数。

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { ref, watch } from 'vue'

export default {
  setup() {
    const count = ref(0)

    watch(count, (newValue, oldValue) => {
      console.log(`Count changed from ${oldValue} to ${newValue}`)
    })

    const increment = () => {
      count.value++
    }

    return {
      count,
      increment
    }
  }
}
</script>

使用 computed 缓存计算结果

计算属性会缓存计算结果,只有在依赖的数据发生变化时才会重新计算。这可以避免不必要的重复计算,提高性能。

<template>
  <div>
    <p>Original Value: {{ originalValue }}</p>
    <p>Computed Value: {{ computedValue }}</p>
  </div>
</template>

<script>
import { ref, computed } from 'vue'

export default {
  setup() {
    const originalValue = ref('Hello')

    const computedValue = computed(() => {
      return originalValue.value.toUpperCase()
    })

    return {
      originalValue,
      computedValue
    }
  }
}
</script>

监听器的使用

在某些情况下,你可能需要监听更复杂的状态变化,例如数组或对象的嵌套属性。Vue3 提供了 watchwatchEffect 两种方式来实现这一点。

使用 watch

如果你需要监听一个具体的属性变化,可以使用 watch

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { ref, watch } from 'vue'

export default {
  setup() {
    const count = ref(0)

    watch(count, (newValue, oldValue) => {
      console.log(`Count changed from ${oldValue} to ${newValue}`)
    })

    const increment = () => {
      count.value++
    }

    return {
      count,
      increment
    }
  }
}
</script>

使用 watchEffect

如果你需要监听多个属性的变化,或者需要在监听器中执行一些复杂的逻辑,可以使用 watchEffect

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { ref, watchEffect } from 'vue'

export default {
  setup() {
    const count = ref(0)

    watchEffect(() => {
      console.log(`Count is now ${count.value}`)
      console.log(`Double count is now ${count.value * 2}`)
    })

    const increment = () => {
      count.value++
    }

    return {
      count,
      increment
    }
  }
}
</script>
路由与状态管理

Vue Router基础配置

Vue Router 是 Vue.js 官方的路由管理器,用于实现基于 URL 的路由功能。你可以通过它来控制浏览器地址栏中的 URL,并根据不同的路由显示不同的组件。

安装 Vue Router

首先,你需要安装 Vue Router:

npm install vue-router@next

配置 Vue Router

创建一个新的文件 router/index.js,配置 Vue Router:

import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  }
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

export default router

在主文件 main.js 中,引入并使用 Vue Router:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

App.vue 中使用 <router-view> 标签来显示当前路由对应的组件:

<template>
  <router-view></router-view>
</template>

<script>
import { createApp } from 'vue'
import router from './router'

export default {
  name: 'App',
  setup() {
    createApp(App).use(router).mount('#app')
  }
}
</script>

Vuex的状态管理模式

Vuex 是 Vue.js 的官方状态管理库,它可以帮助你更好地管理应用的状态。使用 Vuex 可以让你的应用更容易进行调试,也更容易进行测试和状态管理。

安装 Vuex

安装 Vuex:

npm install vuex@next

配置 Vuex

创建一个新的文件 store/index.js,配置 Vuex:

import { createStore } from 'vuex'

export default createStore({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++
    }
  },
  actions: {
    increment({ commit }) {
      commit('increment')
    }
  },
  getters: {
    doubleCount: (state) => {
      return state.count * 2
    }
  }
})

在主文件 main.js 中,引入并使用 Vuex:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

createApp(App).use(router).use(store).mount('#app')

在组件中使用 Vuex:

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { useStore } from 'vuex'

export default {
  setup() {
    const store = useStore()

    const count = computed(() => store.state.count)
    const doubleCount = computed(() => store.getters.doubleCount)

    const increment = () => {
      store.dispatch('increment')
    }

    return {
      count,
      doubleCount,
      increment
    }
  }
}
</script>

状态管理的基本使用

在 Vuex 中,可以通过 state 来存储应用的状态,通过 mutations 来修改状态,通过 actions 来异步地修改状态,通过 getters 来获取状态。

使用 state

state 是一个对象,用于存储应用的状态。你可以通过 state 来获取当前的状态。

const store = createStore({
  state: {
    count: 0
  }
})

使用 mutations

mutations 是一个方法集合,用来修改 state。每个 mutation 有一个类型(通常是字符串),对应一个处理函数。

const store = createStore({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++
    }
  }
})

使用 actions

actions 是一个方法集合,用来异步地修改 stateactions 可以使用 commit 方法来触发 mutations

const store = createStore({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++
    }
  },
  actions: {
    increment({ commit }) {
      commit('increment')
    }
  }
})

使用 getters

getters 是一个方法集合,用来获取 stategetters 的返回值会基于其依赖缓存,只有依赖发生变化时才会重新计算。

const store = createStore({
  state: {
    count: 0
  },
  getters: {
    doubleCount: (state) => {
      return state.count * 2
    }
  }
})
实战项目案例

小项目实战

我们将通过一个简单的待办事项应用(To-Do List)来展示如何使用 Vue3、Vue Router 和 Vuex 来构建一个完整的应用。

项目结构

my-todo-app/
├── node_modules/
├── public/
│   └── index.html
├── src/
│   ├── assets/
│   ├── components/
│   │   ├── AddTodo.vue
│   │   ├── TodoList.vue
│   ├── views/
│   │   ├── Home.vue
│   │   ├── About.vue
│   ├── App.vue
│   ├── main.js
│   ├── router/
│   │   └── index.js
│   ├── store/
│   │   └── index.js
├── .gitignore
├── babel.config.js
├── package.json
└── vue.config.js

创建组件

创建 AddTodo.vue 组件用于添加新的待办事项:

<template>
  <div class="add-todo">
    <input v-model="newTodo" @keyup.enter="addTodo" placeholder="Add a new todo" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      newTodo: ''
    }
  },
  methods: {
    addTodo() {
      if (this.newTodo) {
        this.$store.dispatch('addTodo', this.newTodo)
        this.newTodo = ''
      }
    }
  }
}
</script>

<style scoped>
.add-todo {
  margin-bottom: 20px;
}
</style>

创建 TodoList.vue 组件用于显示待办事项列表:

<template>
  <ul>
    <li v-for="(todo, index) in todos" :key="index">
      {{ todo }}
      <button @click="removeTodo(index)">Remove</button>
    </li>
  </ul>
</template>

<script>
export default {
  computed: {
    todos() {
      return this.$store.state.todos
    }
  },
  methods: {
    removeTodo(index) {
      this.$store.dispatch('removeTodo', index)
    }
  }
}
</script>

<style scoped>
ul {
  list-style-type: none;
  padding: 0;
}
li {
  margin: 10px 0;
}
</style>

创建路由

router/index.js 中配置路由:

import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  }
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

export default router

创建 Vuex Store

store/index.js 中配置 Vuex:

import { createStore } from 'vuex'

export default createStore({
  state: {
    todos: []
  },
  mutations: {
    addTodo(state, todo) {
      state.todos.push(todo)
    },
    removeTodo(state, index) {
      state.todos.splice(index, 1)
    }
  },
  actions: {
    addTodo({ commit }, todo) {
      commit('addTodo', todo)
    },
    removeTodo({ commit }, index) {
      commit('removeTodo', index)
    }
  },
  getters: {
    todos: (state) => {
      return state.todos
    }
  }
})

创建视图组件

创建 views/Home.vue 组件:

<template>
  <div>
    <h1>Home</h1>
    <AddTodo />
    <TodoList />
  </div>
</template>

<script>
import AddTodo from '../components/AddTodo.vue'
import TodoList from '../components/TodoList.vue'

export default {
  components: {
    AddTodo,
    TodoList
  }
}
</script>

创建 views/About.vue 组件:

<template>
  <div>
    <h1>About</h1>
  </div>
</template>

创建主应用组件

App.vue 中使用 <router-view> 来显示当前路由组件:

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script>
import { createApp } from 'vue'
import router from './router'
import store from './store'

export default {
  name: 'App',
  setup() {
    createApp(App).use(router).use(store).mount('#app')
  }
}
</script>

创建主文件

main.js 中引入并使用 Vue Router 和 Vuex:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

createApp(App).use(router).use(store).mount('#app')

代码优化与调试

在开发过程中,可以通过一些方法来优化代码和调试问题。

代码优化

  1. 减少重复代码:通过抽象和重用组件来减少重复代码。
  2. 优化性能:避免不必要的 DOM 操作和计算,使用 v-once 或者 v-cache 减少不必要的渲染。
  3. 使用 TypeScript:使用 TypeScript 可以帮助你更好地管理代码结构和类型。

调试

  1. 使用 Vue Devtools:Vue Devtools 是一个浏览器插件,可以用来调试 Vue 应用。它提供了许多有用的工具,如检查组件树、查看状态等。
  2. 使用 console.log:通过 console.log 了解组件的状态变化和数据流动。
  3. 使用 Vue CLI 的调试模式:在开发环境下使用 npm run serve 启动服务器,Vue CLI 会提供详细的错误信息和警告。

项目部署与上线

在开发完成后,可以通过以下步骤来部署和上线你的项目。

构建生产环境代码

首先,你需要构建生产环境的代码。在项目根目录下运行以下命令:

npm run build

这会生成一个 dist 目录,其中包含了所有生产环境下需要的文件。

部署到服务器

dist 目录下的所有文件上传到你的服务器。你可以使用 FTP、SFTP 或其他文件传输工具来完成这一步。

配置服务器

确保服务器上的 Web 服务器(如 Nginx 或 Apache)已经正确配置,可以服务静态文件。

例如,如果你使用 Nginx,可以创建一个配置文件 my-todo-app.conf

server {
  listen 80;
  server_name yourdomain.com;

  location / {
    root /path/to/dist;
    try_files $uri /index.html;
  }
}

然后将这个配置文件添加到 Nginx 的配置中,并重启 Nginx 服务:

sudo ln -s /path/to/my-todo-app.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

完成这些步骤后,你的应用就可以通过服务器的域名访问了。

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP