├── .gitignore ├── README.md ├── package.json ├── public └── index.html ├── src ├── App.vue ├── components │ ├── Menu.js │ ├── MyButton.vue │ ├── Position.js │ └── child.vue ├── main.js ├── router │ └── index.js └── views │ ├── About.vue │ ├── Computed.vue │ ├── Dad.vue │ ├── Father.vue │ ├── Home.vue │ ├── Life.vue │ └── Parent.vue └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | tmp/ 5 | log/ 6 | static/upfiles/* 7 | npm-debug.log* 8 | yarn-debug.log* 9 | yarn-error.log* 10 | **/*.log 11 | 12 | tests/**/coverage/ 13 | tests/e2e/reports 14 | selenium-debug.log 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.local 24 | 25 | package-lock.json 26 | yarn.lock 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue3.0 Composition API 入门教程 2 | 3 | 光阴荏苒,vue3.0已经进入了 beta 版本了。很多朋友说,你该出个系列的教程了,毕竟当年我写得 vue 2.0 的系列的博文在网上影响并不小。那就写吧,我力求简洁明了的把新的知识点都覆盖到。 4 | 5 | ## 安装以及运行 6 | 7 | ```bash 8 | # clone 项目 9 | git clone https://github.com/fengcms/vue3-demo 10 | # 进入项目文件夹 11 | cd vue3-demo 12 | # 安装依赖 13 | npm i 14 | # 运行开发环境 15 | npm run dev 16 | # 编译代码 17 | npm run build 18 | ``` 19 | 20 | 文章目录地址 https://blog.csdn.net/fungleo/category_10020552.html 21 | 22 | ## 文章目录: 23 | 24 | 1. [vue3.0 Composition API 上手初体验 构建基本项目开发环境](https://blog.csdn.net/FungLeo/article/details/106208252) 25 | 2. [vue3.0 Composition API 上手初体验 构建 vue 基础代码](https://blog.csdn.net/FungLeo/article/details/106208323) 26 | 3. [vue3.0 Composition API 上手初体验 使用 vue-router 构建多页面应用](https://blog.csdn.net/FungLeo/article/details/106208378) 27 | 4. [vue3.0 Composition API 上手初体验 神奇的 setup 函数 (一) 响应数据的绑定](https://blog.csdn.net/FungLeo/article/details/106208437) 28 | 5. [vue3.0 Composition API 上手初体验 神奇的 setup 函数 (二) 响应对象数据的绑定](https://blog.csdn.net/FungLeo/article/details/106208494) 29 | 6. [vue3.0 Composition API 上手初体验 神奇的 setup 函数 (三) 生命周期函数](https://blog.csdn.net/FungLeo/article/details/106208514) 30 | 7. [vue3.0 Composition API 上手初体验 神奇的 setup 函数 (四) 计算属性 computed](https://blog.csdn.net/FungLeo/article/details/106208574) 31 | 8. [vue3.0 Composition API 上手初体验 普通组件的开发与使用](https://blog.csdn.net/FungLeo/article/details/106208611) 32 | 9. [vue3.0 Composition API 上手初体验 vue组件的具名插槽 slot 的变化](https://blog.csdn.net/FungLeo/article/details/106215722) 33 | 10. [vue3.0 Composition API 上手初体验 函数组件的开发与使用](https://blog.csdn.net/FungLeo/article/details/106208639) 34 | 11. [vue3.0 Composition API 上手初体验 用路由循环,做个导航菜单](https://blog.csdn.net/FungLeo/article/details/106211657) 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue3-demo", 3 | "version": "1.0.0", 4 | "description": "一个基于vue3的demo演示", 5 | "main": "webpack.config.js", 6 | "scripts": { 7 | "dev": "webpack-dev-server", 8 | "build": "webpack --env.prod" 9 | }, 10 | "keywords": [ 11 | "vue3" 12 | ], 13 | "author": "FungLeo", 14 | "license": "MIT", 15 | "dependencies": { 16 | "vue": "^3.0.0-beta.13", 17 | "vue-router": "^4.0.0-alpha.11" 18 | }, 19 | "devDependencies": { 20 | "@vue/compiler-sfc": "^3.0.0-beta.13", 21 | "clean-webpack-plugin": "^3.0.0", 22 | "css-loader": "^3.5.3", 23 | "html-webpack-plugin": "^4.3.0", 24 | "node-sass": "^4.14.1", 25 | "sass-loader": "^8.0.2", 26 | "style-loader": "^1.2.1", 27 | "vue-loader": "^16.0.0-beta.2", 28 | "webpack": "^4.43.0", 29 | "webpack-cli": "^3.3.11", 30 | "webpack-dev-server": "^3.11.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | VUE 3.0 Demo 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 12 | 26 | -------------------------------------------------------------------------------- /src/components/Menu.js: -------------------------------------------------------------------------------- 1 | // 引入路由 2 | import router from '@/router' 3 | // 导出为函数 4 | export default () => { 5 | // 通过 getRoutes() 函数,获取所有的路由信息 6 | const routes = router.getRoutes() 7 | console.log(routes) 8 | const links = [] 9 | // 循环路由信息,将数据整理并 push 到 links 数组 10 | routes.forEach((route, index) => { 11 | links.push({ 12 | name: route.meta.title || `未命名${index}`, 13 | link: route.path 14 | }) 15 | }) 16 | // 将 links 数组返回 17 | return links 18 | } 19 | -------------------------------------------------------------------------------- /src/components/MyButton.vue: -------------------------------------------------------------------------------- 1 | 15 | 52 | 91 | -------------------------------------------------------------------------------- /src/components/Position.js: -------------------------------------------------------------------------------- 1 | // 函数式组件, 该组件会返回鼠标在屏幕上的坐标值 2 | // toFefs 是将 reactive 对象的所有 key 都转化为 ref 值 3 | // 这样,在引入使用的组件中,就可以 用 const { x, y } = xx 来使用这些 key 对应的 value 了 4 | import { onMounted, onUnmounted, reactive, toRefs } from 'vue' 5 | 6 | // 这里导出,就不是对象,而是一个函数了。 7 | export default () => { 8 | // 定义一个准备导出的对象数据 9 | const position = reactive({ 10 | x: 0, 11 | y: 0 12 | }) 13 | // 定义一个会改变数据的函数 14 | const update = page => { 15 | position.x = page.pageX 16 | position.y = page.pageY 17 | } 18 | // 使用生命周期,绑定和移除事件 19 | onMounted (() => { 20 | window.addEventListener('mousemove', update) 21 | }) 22 | onUnmounted (() => { 23 | window.removeEventListener('mousemove', update) 24 | }) 25 | // 将 reactive 对象 转化为 ref 响应式的值,并返回 26 | return toRefs(position) 27 | } 28 | -------------------------------------------------------------------------------- /src/components/child.vue: -------------------------------------------------------------------------------- 1 | 26 | 37 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | import router from './router' 4 | 5 | // 将创建的 App 搞个别名 6 | const app = createApp(App) 7 | 8 | // 使用路由配置 9 | app.use(router) 10 | 11 | // 挂载运行 12 | app.mount('#app') 13 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | // 可以根据路由模式的不同,后面俩可以只引用一个 2 | import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router' 3 | import Home from '@/views/Home.vue' 4 | 5 | // 构建我们的页面路由配置,可以看到,这里和原来的写法并无二致。 6 | const routes = [ 7 | { 8 | path: '/', 9 | component: Home, 10 | meta: { title: '首页-响应式数据计数器 Demo' } 11 | }, { 12 | path: '/about', 13 | component: () => import('@/views/About.vue'), 14 | meta: { title: '关于我们-响应式对象数据 Demo' } 15 | }, { 16 | path: '/life', 17 | component: () => import('@/views/Life.vue'), 18 | meta: { title: '生命周期 Demo' } 19 | }, { 20 | path: '/computed', 21 | component: () => import('@/views/Computed.vue'), 22 | meta: { title: '计算属性 Demo' } 23 | }, { 24 | path: '/parent', 25 | component: () => import('@/views/Parent.vue'), 26 | meta: { title: '普通组件 Demo' } 27 | }, { 28 | path: '/father', 29 | component: () => import('@/views/Father.vue'), 30 | meta: { title: '函数组件 Demo' } 31 | }, { 32 | path: '/dad', 33 | component: () => import('@/views/Dad.vue'), 34 | meta: { title: '具名插槽组件 Demo' } 35 | } 36 | ] 37 | 38 | // 用 history 模式构建路由 39 | // const routerHistory = createWebHistory() 40 | 41 | const router = createRouter({ 42 | // 使用 hash 模式构建路由( url中带 # 号的那种) 43 | history: createWebHashHistory(), 44 | // 使用 history 模式构建路由 ( url 中没有 # 号,但生产环境需要特殊配置) 45 | // history: createWebHistory(), 46 | routes 47 | }) 48 | export default router 49 | -------------------------------------------------------------------------------- /src/views/About.vue: -------------------------------------------------------------------------------- 1 | 9 | 34 | -------------------------------------------------------------------------------- /src/views/Computed.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 44 | -------------------------------------------------------------------------------- /src/views/Dad.vue: -------------------------------------------------------------------------------- 1 | 15 | 21 | -------------------------------------------------------------------------------- /src/views/Father.vue: -------------------------------------------------------------------------------- 1 | 7 | 19 | -------------------------------------------------------------------------------- /src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 31 | 42 | -------------------------------------------------------------------------------- /src/views/Life.vue: -------------------------------------------------------------------------------- 1 | 7 | 58 | -------------------------------------------------------------------------------- /src/views/Parent.vue: -------------------------------------------------------------------------------- 1 | 10 | 35 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const { VueLoaderPlugin } = require('vue-loader') 3 | const HtmlWebpackPlugin = require('html-webpack-plugin') 4 | const { CleanWebpackPlugin } = require('clean-webpack-plugin') 5 | 6 | module.exports = (env = {}) => ({ 7 | mode: env.prod ? 'production' : 'development', 8 | devtool: env.prod ? 'source-map' : 'inline-source-map', 9 | entry: path.resolve(__dirname, './src/main.js'), 10 | output: { 11 | path: path.resolve(__dirname, './dist'), 12 | publicPath: '/' 13 | }, 14 | resolve: { 15 | alias: { 16 | 'vue': '@vue/runtime-dom', 17 | '@': path.resolve(__dirname, './src') 18 | } 19 | }, 20 | module: { 21 | rules: [ 22 | { 23 | test: /\.vue$/, 24 | use: 'vue-loader' 25 | }, { 26 | test: /\.css$/, 27 | use: ['style-loader', 'css-loader'] 28 | }, { 29 | test: /\.scss$/, 30 | use: ['style-loader', 'css-loader', 'sass-loader'] 31 | } 32 | ] 33 | }, 34 | plugins: [ 35 | new VueLoaderPlugin(), 36 | new CleanWebpackPlugin(), 37 | new HtmlWebpackPlugin({ 38 | template: path.resolve(__dirname, './public/index.html'), 39 | filename: 'index.html' 40 | }) 41 | ], 42 | devServer: { 43 | publicPath: '/', 44 | inline: true, 45 | hot: true, 46 | stats: 'minimal', 47 | contentBase: __dirname, 48 | overlay: true, 49 | historyApiFallback: true 50 | } 51 | }) 52 | --------------------------------------------------------------------------------