We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ES2015+
IE11
3.0.0-alpha.8
先看一个 vue 3.0 结合了 vue-router 和 伪 vuex 的效果:
vue-router
vuex
记得 Evan You 好像在哪里说过,Vue 一定不会像某些框架一样,一定要依赖一个编译器,源码需要编译后才能运行在浏览器上。相反,Vue 一定会支持一个完整独立的 js,支持使用 CDN,可以直接在 html 中单独引入 js 使用。
Evan You
所以,我们的第一个示例就是一个最简单的 html 页面。
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue3.0 Demo</title> <meta content="一个最简单的示例" name="description"> <script src="https://unpkg.com/[email protected]/dist/vue.global.js"></script> </head> <body> <div id="app"> {{ message }} </div> <script> const { createApp, ref } = Vue; const App = { setup() { const message = ref('Hello Vue!'); return { message } } }; createApp(App).mount('#app'); </script> </body> </html>
示例参考地址:vue-composition-api-rfc.netlify.com/#basic-exam…
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue3.0 Demo</title> <meta content="稍微带一些交互的示例" name="description"> <script src="https://unpkg.com/[email protected]/dist/vue.global.js"></script> </head> <body> <div id="app"> <button @click="increment"> Count is: {{ state.count }}, double is: {{ state.double }} </button> </div> <script> const { createApp, reactive, computed } = Vue; const App = { setup() { const state = reactive({ count: 0, double: computed(() => state.count * 2) }); function increment() { state.count++ }; return { state, increment }; } }; createApp(App).mount('#app'); </script> </body> </html>
在实际大型项目中,我们一般都是工程化的思路在架构前端,所以很少简单的写一个 html 页面,引入 vue 脚本,而是需要依赖编译器,一般是 webpack。
示例参考地址:github.com/vuejs/vue-n…
源码:点击下载
目录结构:
. ├── 1 index.html ├── 2 webpack.config.js ├── src │ ├── 3 App.vue │ └── 4 main.js └── 5 package.json
1、index.html
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Vue3.0 Demo</title> </head> <body> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
2、webpack.config.js
webpack.config.js
const path = require('path') const { VueLoaderPlugin } = require('vue-loader') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = (env = {}) => ({ mode: env.prod ? 'production' : 'development', devtool: env.prod ? 'source-map' : 'cheap-module-eval-source-map', entry: path.resolve(__dirname, './src/main.js'), output: { path: path.resolve(__dirname, './dist'), publicPath: '/' }, resolve: { alias: { // this isn't technically needed, since the default `vue` entry for bundlers // is a simple `export * from '@vue/runtime-dom`. However having this // extra re-export somehow causes webpack to always invalidate the module // on the first HMR update and causes the page to reload. 'vue': '@vue/runtime-dom' } }, module: { rules: [ { test: /\.vue$/, use: 'vue-loader' }, { test: /\.png$/, use: { loader: 'url-loader', options: { limit: 8192 } } }, { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] } ] }, plugins: [ new VueLoaderPlugin(), new HtmlWebpackPlugin({ template: './index.html', filename: 'index.html' }) ], devServer: { inline: true, hot: true, stats: 'minimal', contentBase: __dirname, overlay: true, publicPath: '/', historyApiFallback: true } })
3、src/App.vue
src/App.vue
<template> <h1>Hello Vue 3!</h1> <button @click="inc">Clicked {{ count }} times.</button> </template> <script> import { ref } from 'vue' export default { setup() { const count = ref(0) const inc = () => { count.value++ } return { count, inc } } } </script> <style scoped> h1 { font-family: Arial, Helvetica, sans-serif; } </style>
4、src/main.js
src/main.js
import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app')
5、package.json
package.json
{ "private": true, "scripts": { "dev": "webpack-dev-server", "build": "webpack --env.prod" }, "dependencies": { "vue": "^3.0.0-alpha.8" }, "devDependencies": { "@vue/compiler-sfc": "^3.0.0-alpha.8", "css-loader": "^3.4.0", "file-loader": "^5.0.2", "html-webpack-plugin": "^3.2.0", "style-loader": "^1.1.3", "url-loader": "^3.0.0", "vue-loader": "^16.0.0-alpha.1", "webpack": "^4.41.4", "webpack-cli": "^3.3.10", "webpack-dev-server": "^3.10.1" } }
所有文件准备就绪后,执行以下命令即可:
npm i && npm run dev
经过一翻折腾,将 vue-router 成功引入到项目中,但是 vuex 由于目前官网还没有适配 vue 3.0,所以只能换一种新的思路了。
以下是目前发现的问题清单(vue3 生态还有待完善):
lazy-loaded
. ├── 1 index.html ├── 2 webpack.config.js ├── src │ ├── 3 App.vue │ ├── 4 main.js │ ├── router │ │ └── 5 index.js │ ├── store │ │ └── 6 index.js │ └── views │ ├── 7 Page1.vue │ └── 8 Page2.vue └── 9 package.json
相比上一个示例,本示例增加了3个目录 router、store 和 views,同时修改了 main.js 和 App.vue。
<template> <h1>{{ message }}</h1> <p>count:{{count}}</p> <router-link to="/">Home</router-link> <router-link to="/page1">Page1</router-link> <router-link to="/page2">Page2</router-link> <router-view></router-view> </template> <script> import { toRefs } from 'vue' import store from './store'; export default { setup() { let data = store.getState(); // WARNING:这里无法直接修改属性 readonly data.count++; return { ...toRefs(data) } } } </script> <style scoped> h1 { font-family: Arial, Helvetica, sans-serif; } a + a { margin-left: 10px; } </style>
import { createApp } from 'vue' import App from './App.vue' import router from './router' createApp(App) .use(router) .mount('#app')
5、src/router/index.js
src/router/index.js
import { createRouter, createHistory } from '@posva/vue-router-next' import Page1 from '../views/Page1.vue' import Page2 from '../views/Page2.vue' const routes = [ { path: '/page1', name: 'page1', component: Page1 }, { path: '/page2', name: 'page2', // lazy-loaded doesn't seem to be implemented yet // https://github.com/vuejs/vue-next/issues/777 component: Page2 } ] export const routerHistory = createHistory() export const router = createRouter({ history: routerHistory, base: process.env.BASE_URL, routes }) router.beforeEach((to, from, next) => { console.log('beforeEach', to.name); next() }) export default router
6、src/store/index.js
src/store/index.js
import {reactive, readonly } from 'vue'; let store = reactive({ message: 'Hello Vue3!', count: 1 }); export default { getState() { return readonly(store); }, updateCnt() { console.log('updateCnt', store.count); store.count++; } }
7、src/views/Page1.vue
src/views/Page1.vue
<template> <h2>Page1</h2> </template> <script> import store from '../store'; export default { name: 'page2', setup() { // 更新 visit 全局变量 store.updateCnt(); } } </script> <style scoped> </style>
8、src/views/Page2.vue
src/views/Page2.vue
<template> <h2>Page2</h2> </template> <script> import store from '../store'; export default { name: 'page1', setup() { // 更新 visit 全局变量 store.updateCnt(); } } </script> <style scoped> </style>
9、package.json
{ "private": true, "scripts": { "dev": "webpack-dev-server", "build": "webpack --env.prod" }, "dependencies": { "@posva/vue-router-next": "^4.0.0-alpha.0", "vue": "^3.0.0-alpha.8" }, "devDependencies": { "@vue/compiler-sfc": "^3.0.0-alpha.8", "css-loader": "^3.4.0", "file-loader": "^5.0.2", "html-webpack-plugin": "^3.2.0", "style-loader": "^1.1.3", "url-loader": "^3.0.0", "vue-loader": "^16.0.0-alpha.1", "webpack": "^4.41.4", "webpack-cli": "^3.3.10", "webpack-dev-server": "^3.10.1" } }
最终效果:
![img](data:image/svg+xml;utf8,)
本示例参考:dev.to/lmillucci/b…
相比上一个示例,本示例大致的修改:
typescript
ts-loader
.js
.ts
.vue
export
defineComponent
<script>
<script lang="ts">
shims-vue.d.ts
tsconfig.json
文件清单:
. ├── 1 index.html ├── 2 webpack.config.js ├── src │ ├── 3 App.vue │ ├── 4 main.ts │ ├── 5 shims-vue.d.ts │ ├── router │ │ └── 6 index.ts │ ├── store │ │ └── 7 index.ts │ └── views │ ├── 8 Page1.vue │ └── 9 Page2.vue ├── 10 tsconfig.json └── 11 package.json
const path = require('path') const { VueLoaderPlugin } = require('vue-loader') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = (env = {}) => ({ mode: env.prod ? 'production' : 'development', devtool: env.prod ? 'source-map' : 'cheap-module-eval-source-map', entry: path.resolve(__dirname, './src/main.ts'), output: { path: path.resolve(__dirname, './dist'), publicPath: '/' }, resolve: { extensions: ['.ts', '.js', '.vue', '.json'], alias: { // this isn't technically needed, since the default `vue` entry for bundlers // is a simple `export * from '@vue/runtime-dom`. However having this // extra re-export somehow causes webpack to always invalidate the module // on the first HMR update and causes the page to reload. 'vue': '@vue/runtime-dom' } }, module: { rules: [ { test: /\.vue$/, use: 'vue-loader' }, { test: /\.ts$/, loader: 'ts-loader', options: { appendTsSuffixTo: [/\.vue$/], } }, { test: /\.png$/, use: { loader: 'url-loader', options: { limit: 8192 } } }, { test: /\.css$/, use: [ 'style-loader', 'css-loader' ] } ] }, plugins: [ new VueLoaderPlugin(), new HtmlWebpackPlugin({ template: './index.html', filename: 'index.html' }) ], devServer: { inline: true, hot: true, stats: 'minimal', contentBase: __dirname, overlay: true, publicPath: '/', historyApiFallback: true } })
<template> <h1>{{ message }}</h1> <p>Ts count:{{count}}</p> <router-link to="/">Home</router-link> <router-link to="/page1">Page1</router-link> <router-link to="/page2">Page2</router-link> <router-view></router-view> </template> <script lang="ts"> import { defineComponent, toRefs } from 'vue' import store from './store'; export default defineComponent({ setup() { let data = store.getState(); // WARNING:这里无法直接修改属性 readonly // data.count++; return { ...toRefs(data) } } }) </script> <style scoped> h1 { font-family: Arial, Helvetica, sans-serif; } a + a { margin-left: 10px; } </style>
4、src/main.ts
src/main.ts
5、src/shims-vue.d.ts
src/shims-vue.d.ts
这个文件只需要放到 src 目录下就可以了,为什么?
src
declare module '*.vue' { import { defineComponent } from 'vue'; const Component: ReturnType<typeof defineComponent>; export default Component; }
6、src/router/index.ts
src/router/index.ts
import { createRouter, createHistory } from '@posva/vue-router-next' import Page1 from '../views/Page1.vue' import Page2 from '../views/Page2.vue' const routes = [ { path: '/page1', name: 'page1', component: Page1 }, { path: '/page2', name: 'page2', // lazy-loaded doesn't seem to be implemented yet // https://github.com/vuejs/vue-next/issues/777 component: Page2 } ] export const routerHistory = createHistory() export const router = createRouter({ history: routerHistory, routes }) router.beforeEach((to, from, next) => { console.log('beforeEach', to.name); next() }) export default router
7、src/store/index.ts
src/store/index.ts
import {reactive, readonly } from 'vue'; let store = reactive({ message: 'Hello Ts Vue3!', count: 1 }); export default { getState() { return readonly(store); }, updateCnt() { console.log('updateCnt', store.count); store.count++; } }
8、src/views/Page1.vue
<template> <h2>Ts Page1</h2> </template> <script lang="ts"> import { defineComponent } from 'vue' import store from '../store'; export default defineComponent({ name: 'page2', setup() { // 更新 visit 全局变量 store.updateCnt(); } }) </script> <style scoped> </style>
9、src/views/Page2.vue
<template> <h2>Ts Page2</h2> </template> <script lang="ts"> import { defineComponent } from 'vue' import store from '../store'; export default defineComponent({ name: 'page1', setup() { // 更新 visit 全局变量 store.updateCnt(); } }) </script> <style scoped> </style>
10、tsconfig.json
{ "compilerOptions": { "allowJs": true, "allowSyntheticDefaultImports": true, "declaration": false, "esModuleInterop": true, "experimentalDecorators": true, "module": "es2015", "moduleResolution": "node", "noImplicitAny": false, "noLib": false, "sourceMap": true, "strict": true, "strictPropertyInitialization": false, "suppressImplicitAnyIndexErrors": true, "target": "es2015", "baseUrl": "." }, "exclude": [ "./node_modules" ], "include": [ "./src/**/*.ts", "./src/**/*.vue" ] }
11、package.json
{ "private": true, "scripts": { "dev": "webpack-dev-server", "build": "webpack --env.prod" }, "dependencies": { "@posva/vue-router-next": "^4.0.0-alpha.0", "vue": "^3.0.0-alpha.8" }, "devDependencies": { "@vue/compiler-sfc": "^3.0.0-alpha.8", "css-loader": "^3.4.0", "file-loader": "^5.0.2", "html-webpack-plugin": "^3.2.0", "style-loader": "^1.1.3", "ts-loader": "^6.2.1", "typescript": "^3.8.3", "url-loader": "^3.0.0", "vue-loader": "^16.0.0-alpha.1", "webpack": "^4.41.4", "webpack-cli": "^3.3.10", "webpack-dev-server": "^3.10.1" } }
到此为止,相信大家搭建 vue 3.0 的工程应该就没啥大问题了。后续我们就结合这现有的工程,详细说明 vue3 的一些新特性,欢迎大家关注和点赞。
(本文完)
The text was updated successfully, but these errors were encountered:
sunmaobin
No branches or pull requests
1 说明
ES2015+
语法(比如用高级浏览器)IE11
(后续应该会推出支持的版本)3.0.0-alpha.8
先看一个 vue 3.0 结合了
vue-router
和 伪vuex
的效果:2 一个简单的 html 页面
记得
Evan You
好像在哪里说过,Vue 一定不会像某些框架一样,一定要依赖一个编译器,源码需要编译后才能运行在浏览器上。相反,Vue 一定会支持一个完整独立的 js,支持使用 CDN,可以直接在 html 中单独引入 js 使用。所以,我们的第一个示例就是一个最简单的
html
页面。3 稍微带一些交互逻辑的示例
示例参考地址:vue-composition-api-rfc.netlify.com/#basic-exam…
4 一个工程化的集成 webpack 的简单示例
在实际大型项目中,我们一般都是工程化的思路在架构前端,所以很少简单的写一个 html 页面,引入 vue 脚本,而是需要依赖编译器,一般是 webpack。
示例参考地址:github.com/vuejs/vue-n…
源码:点击下载
目录结构:
1、
index.html
2、
webpack.config.js
3、
src/App.vue
4、
src/main.js
5、
package.json
所有文件准备就绪后,执行以下命令即可:
源码:点击下载
5 尝试引入 vue2.x 中的 vue-router 和 vuex 的示例
经过一翻折腾,将 vue-router 成功引入到项目中,但是 vuex 由于目前官网还没有适配 vue 3.0,所以只能换一种新的思路了。
以下是目前发现的问题清单(vue3 生态还有待完善):
lazy-loaded
,查看 这个ISSUE源码:点击下载
目录结构:
相比上一个示例,本示例增加了3个目录 router、store 和 views,同时修改了 main.js 和 App.vue。
1、
index.html
2、
webpack.config.js
3、
src/App.vue
4、
src/main.js
5、
src/router/index.js
6、
src/store/index.js
7、
src/views/Page1.vue
8、
src/views/Page2.vue
9、
package.json
所有文件准备就绪后,执行以下命令即可:
源码:点击下载
最终效果:
![img](data:image/svg+xml;utf8,)
6 使用 Typescript 语法创建一个工程化的示例
本示例参考:dev.to/lmillucci/b…
相比上一个示例,本示例大致的修改:
typescript
和ts-loader
webpack.config.js
增加ts-loader
.js
文件修改为.ts
文件.vue
文件中export
对象变 Ts 对象,使用 vue3 内置方法defineComponent
<script>
变为<script lang="ts">
shims-vue.d.ts
,不然 IDE 会解析报错tsconfig.json
,TS 配置文件源码:点击下载
文件清单:
1、
index.html
2、
webpack.config.js
3、
src/App.vue
4、
src/main.ts
5、
src/shims-vue.d.ts
这个文件只需要放到
src
目录下就可以了,为什么?6、
src/router/index.ts
7、
src/store/index.ts
8、
src/views/Page1.vue
9、
src/views/Page2.vue
10、
tsconfig.json
11、
package.json
所有文件准备就绪后,执行以下命令即可:
源码:点击下载
最终效果:
到此为止,相信大家搭建 vue 3.0 的工程应该就没啥大问题了。后续我们就结合这现有的工程,详细说明 vue3 的一些新特性,欢迎大家关注和点赞。
(本文完)
The text was updated successfully, but these errors were encountered: