├── README.md ├── index.html ├── my-app ├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ └── index.html └── src │ ├── App.vue │ ├── assets │ └── logo.png │ ├── components │ ├── HelloWorld.vue │ └── TodoItem.vue │ └── main.js ├── router-demo ├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ └── index.html └── src │ ├── App.vue │ ├── assets │ └── logo.png │ ├── components │ ├── RouterChildrenDemo.vue │ └── RouterDemo.vue │ ├── main.js │ └── routes.js ├── test-demo ├── .browserslistrc ├── .eslintrc.js ├── .gitignore ├── README.md ├── babel.config.js ├── jest.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public │ ├── favicon.ico │ └── index.html ├── src │ ├── App.vue │ ├── assets │ │ └── logo.png │ ├── components │ │ ├── Counter.vue │ │ └── HelloWorld.vue │ └── main.js └── tests │ └── unit │ ├── .eslintrc.js │ ├── Counter.spec.js │ ├── __snapshots__ │ └── Counter.spec.js.snap │ └── example.spec.js ├── vscode-setting.json ├── vuex-demo1 ├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ └── index.html └── src │ ├── App.vue │ ├── assets │ └── logo.png │ ├── components │ └── HelloWorld.vue │ └── main.js ├── vuex-demo2 ├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ └── index.html └── src │ ├── App.vue │ ├── assets │ └── logo.png │ ├── components │ └── HelloWorld.vue │ ├── main.js │ └── min-vuex.js ├── vuex-demo2_a ├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ └── index.html └── src │ ├── App.vue │ ├── assets │ └── logo.png │ ├── components │ └── HelloWorld.vue │ ├── main.js │ └── min-vuex.js ├── vuex-demo3 ├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ └── index.html └── src │ ├── App.vue │ ├── api │ └── shop.js │ ├── assets │ └── logo.png │ ├── components │ ├── ProductList.vue │ └── ShoppingCart.vue │ ├── main.js │ └── store │ ├── index.js │ ├── modules │ ├── cart.js │ └── products.js │ └── mutation-types.js ├── vuex-demo3_a ├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ └── index.html └── src │ ├── App.vue │ ├── api │ └── shop.js │ ├── assets │ └── logo.png │ ├── components │ ├── ProductList.vue │ └── ShoppingCart.vue │ ├── main.js │ └── store │ ├── index.js │ ├── modules │ ├── cart.js │ └── products.js │ └── mutation-types.js ├── 《Vue开发实战》基础篇课件.pdf ├── 《Vue开发实战》生态篇课件.pdf ├── 基础篇4-7 ├── index4.html ├── index5.html ├── index6.html └── index7.html ├── 基础篇8-10 └── vue-demo1 │ ├── .gitignore │ ├── README.md │ ├── babel.config.js │ ├── package.json │ ├── public │ ├── favicon.ico │ └── index.html │ ├── src │ ├── App.vue │ ├── assets │ │ └── logo.png │ ├── components │ │ ├── HelloWorld.vue │ │ ├── TodoItem.vue │ │ └── TodoList.vue │ └── main.js │ └── yarn.lock └── 演示DEMO源码 ├── .eslintrc.json ├── .gitignore ├── README.md ├── babel.config.js ├── cypress.json ├── jest.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── favicon.ico └── index.html ├── src ├── App.vue ├── assets │ └── logo.png ├── components │ └── HelloWorld.vue ├── main.js ├── router.js ├── store.js └── views │ ├── 1.10 │ ├── AnchoredHeading.js │ ├── AnchoredHeading.jsx │ ├── AnchoredHeading.vue │ └── index.vue │ ├── 1.4 │ ├── PropsAndData.vue │ └── index.vue │ ├── 1.5 │ ├── Computed.vue │ ├── Computed1.vue │ ├── Watch.vue │ ├── Watch1.vue │ ├── Watch1_pro.vue │ └── index.vue │ ├── 1.6 │ ├── Clock.vue │ ├── Functional.vue │ ├── TempVar.js │ └── index.vue │ ├── 1.7 │ ├── CustomerDirectives.vue │ ├── Directives.vue │ └── index.vue │ ├── 1.8 │ ├── ChildrenA.vue │ ├── ChildrenA_a.vue │ ├── ChildrenB.vue │ ├── ChildrenC.vue │ ├── ChildrenD.vue │ ├── ChildrenE.vue │ ├── ChildrenF.vue │ ├── ChildrenG.vue │ ├── ChildrenH.vue │ ├── ChildrenI.vue │ └── index.vue │ ├── 1.9 │ ├── ChildrenA.vue │ ├── ChildrenB.vue │ ├── ChildrenC.vue │ ├── ChildrenD.vue │ ├── ChildrenE.vue │ ├── ChildrenF.vue │ ├── ChildrenG.vue │ ├── ChildrenH.vue │ ├── ChildrenI.vue │ └── index.vue │ ├── About.vue │ └── Home.vue └── tests ├── e2e ├── .eslintrc.js ├── plugins │ └── index.js ├── specs │ └── test.js └── support │ ├── commands.js │ └── index.js └── unit ├── .eslintrc.js └── example.spec.js /README.md: -------------------------------------------------------------------------------- 1 | # geektime-vue-1 2 | 极客时间基础篇&生态篇代码 3 | 4 | ## 源码使用指南 5 | 6 | 进入相应文件夹(有package.json的那个)后执行以下步骤: 7 | 8 | ### 安装依赖 9 | ``` 10 | npm install 11 | ``` 12 | 13 | ### 启动环境 14 | ``` 15 | npm run serve 16 | ``` 17 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 |
13 | {{msg}} 14 |
15 | 16 | 17 |
18 | 21 |
22 | 23 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /my-app/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | -------------------------------------------------------------------------------- /my-app/README.md: -------------------------------------------------------------------------------- 1 | # my-app 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /my-app/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /my-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "vue": "^2.6.6" 12 | }, 13 | "devDependencies": { 14 | "@vue/cli-plugin-babel": "^3.5.0", 15 | "@vue/cli-plugin-eslint": "^3.5.0", 16 | "@vue/cli-service": "^3.5.0", 17 | "babel-eslint": "^10.0.1", 18 | "eslint": "^5.8.0", 19 | "eslint-plugin-vue": "^5.0.0", 20 | "vue-template-compiler": "^2.5.21" 21 | }, 22 | "eslintConfig": { 23 | "root": true, 24 | "env": { 25 | "node": true 26 | }, 27 | "extends": [ 28 | "plugin:vue/essential", 29 | "eslint:recommended" 30 | ], 31 | "rules": {}, 32 | "parserOptions": { 33 | "parser": "babel-eslint" 34 | } 35 | }, 36 | "postcss": { 37 | "plugins": { 38 | "autoprefixer": {} 39 | } 40 | }, 41 | "browserslist": [ 42 | "> 1%", 43 | "last 2 versions", 44 | "not ie <= 8" 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /my-app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/my-app/public/favicon.ico -------------------------------------------------------------------------------- /my-app/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | my-app 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /my-app/src/App.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 40 | 41 | 44 | -------------------------------------------------------------------------------- /my-app/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/my-app/src/assets/logo.png -------------------------------------------------------------------------------- /my-app/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 41 | 42 | 43 | 59 | -------------------------------------------------------------------------------- /my-app/src/components/TodoItem.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 18 | 19 | 24 | -------------------------------------------------------------------------------- /my-app/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | Vue.config.productionTip = false 5 | 6 | new Vue({ 7 | render: h => h(App), 8 | }).$mount('#app') 9 | -------------------------------------------------------------------------------- /router-demo/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | -------------------------------------------------------------------------------- /router-demo/README.md: -------------------------------------------------------------------------------- 1 | # router-demo 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /router-demo/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /router-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "router-demo", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "vue": "^2.6.6", 12 | "vue-router": "^3.0.2" 13 | }, 14 | "devDependencies": { 15 | "@vue/cli-plugin-babel": "^3.5.0", 16 | "@vue/cli-plugin-eslint": "^3.5.0", 17 | "@vue/cli-service": "^3.5.0", 18 | "babel-eslint": "^10.0.1", 19 | "eslint": "^5.8.0", 20 | "eslint-plugin-vue": "^5.0.0", 21 | "vue-template-compiler": "^2.5.21" 22 | }, 23 | "eslintConfig": { 24 | "root": true, 25 | "env": { 26 | "node": true 27 | }, 28 | "extends": [ 29 | "plugin:vue/essential", 30 | "eslint:recommended" 31 | ], 32 | "rules": {}, 33 | "parserOptions": { 34 | "parser": "babel-eslint" 35 | } 36 | }, 37 | "postcss": { 38 | "plugins": { 39 | "autoprefixer": {} 40 | } 41 | }, 42 | "browserslist": [ 43 | "> 1%", 44 | "last 2 versions", 45 | "not ie <= 8" 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /router-demo/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/router-demo/public/favicon.ico -------------------------------------------------------------------------------- /router-demo/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | router-demo 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /router-demo/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 16 | 17 | 27 | -------------------------------------------------------------------------------- /router-demo/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/router-demo/src/assets/logo.png -------------------------------------------------------------------------------- /router-demo/src/components/RouterChildrenDemo.vue: -------------------------------------------------------------------------------- 1 | 6 | 18 | 19 | -------------------------------------------------------------------------------- /router-demo/src/components/RouterDemo.vue: -------------------------------------------------------------------------------- 1 | 21 | 34 | 35 | -------------------------------------------------------------------------------- /router-demo/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | import App from './App.vue' 4 | import routes from './routes' 5 | 6 | Vue.config.productionTip = false 7 | 8 | Vue.use(VueRouter) 9 | 10 | const router = new VueRouter({ 11 | mode: 'history', 12 | routes, 13 | }) 14 | 15 | new Vue({ 16 | router, 17 | render: h => h(App), 18 | }).$mount('#app') 19 | -------------------------------------------------------------------------------- /router-demo/src/routes.js: -------------------------------------------------------------------------------- 1 | import RouterDemo from './components/RouterDemo' 2 | import RouterChildrenDemo from './components/RouterChildrenDemo' 3 | 4 | const routes = [ 5 | { path: '/foo', component: RouterDemo, name: '1' }, 6 | { path: '/bar', component: RouterDemo, name: '2' }, 7 | // 当 /user/:id 匹配成功, 8 | // RouterDemo 会被渲染在 App 的 中 9 | { path: '/user/:id', 10 | component: RouterDemo, 11 | name: '3', 12 | props: true, 13 | children: [ 14 | { 15 | // 当 /user/:id/profile 匹配成功, 16 | // RouterChildrenDemo 会被渲染在 RouterDemo 的 中 17 | path: 'profile', 18 | component: RouterChildrenDemo, 19 | name: '3-1' 20 | }, 21 | { 22 | // 当 /user/:id/posts 匹配成功 23 | // RouterChildrenDemo 会被渲染在 RouterDemo 的 中 24 | path: 'posts', 25 | component: RouterChildrenDemo 26 | } 27 | ] 28 | }, 29 | { path: '/a', redirect: '/bar' }, 30 | { path: '*', component: RouterDemo, name: '404' } 31 | ] 32 | 33 | export default routes -------------------------------------------------------------------------------- /test-demo/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /test-demo/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | extends: ["plugin:vue/essential", "@vue/prettier"], 7 | rules: { 8 | "no-console": process.env.NODE_ENV === "production" ? "error" : "off", 9 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off" 10 | }, 11 | parserOptions: { 12 | parser: "babel-eslint" 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /test-demo/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | -------------------------------------------------------------------------------- /test-demo/README.md: -------------------------------------------------------------------------------- 1 | # test-demo 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Run your unit tests 29 | ``` 30 | npm run test:unit 31 | ``` 32 | 33 | ### Customize configuration 34 | See [Configuration Reference](https://cli.vuejs.org/config/). 35 | -------------------------------------------------------------------------------- /test-demo/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@vue/app"] 3 | }; 4 | -------------------------------------------------------------------------------- /test-demo/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: ["js", "jsx", "json", "vue"], 3 | transform: { 4 | "^.+\\.vue$": "vue-jest", 5 | ".+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$": 6 | "jest-transform-stub", 7 | "^.+\\.jsx?$": "babel-jest" 8 | }, 9 | transformIgnorePatterns: ["/node_modules/"], 10 | moduleNameMapper: { 11 | "^@/(.*)$": "/src/$1" 12 | }, 13 | snapshotSerializers: ["jest-serializer-vue"], 14 | testMatch: [ 15 | "**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)" 16 | ], 17 | testURL: "http://localhost/" 18 | }; 19 | -------------------------------------------------------------------------------- /test-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-demo", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint", 9 | "test": "vue-cli-service test:unit" 10 | }, 11 | "dependencies": { 12 | "vue": "^2.6.6" 13 | }, 14 | "devDependencies": { 15 | "@vue/cli-plugin-babel": "^3.5.0", 16 | "@vue/cli-plugin-eslint": "^3.5.0", 17 | "@vue/cli-plugin-unit-jest": "^3.5.0", 18 | "@vue/cli-service": "^3.5.0", 19 | "@vue/eslint-config-prettier": "^4.0.1", 20 | "@vue/test-utils": "1.0.0-beta.29", 21 | "babel-core": "7.0.0-bridge.0", 22 | "babel-eslint": "^10.0.1", 23 | "babel-jest": "^23.6.0", 24 | "eslint": "^5.8.0", 25 | "eslint-plugin-vue": "^5.0.0", 26 | "sinon": "^7.3.1", 27 | "vue-template-compiler": "^2.5.21" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test-demo/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /test-demo/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/test-demo/public/favicon.ico -------------------------------------------------------------------------------- /test-demo/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | test-demo 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /test-demo/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 18 | 19 | 29 | -------------------------------------------------------------------------------- /test-demo/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/test-demo/src/assets/logo.png -------------------------------------------------------------------------------- /test-demo/src/components/Counter.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /test-demo/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 96 | 97 | 105 | 106 | 107 | 123 | -------------------------------------------------------------------------------- /test-demo/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import App from "./App.vue"; 3 | 4 | Vue.config.productionTip = false; 5 | 6 | new Vue({ 7 | render: h => h(App) 8 | }).$mount("#app"); 9 | -------------------------------------------------------------------------------- /test-demo/tests/unit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | jest: true 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /test-demo/tests/unit/Counter.spec.js: -------------------------------------------------------------------------------- 1 | import { mount } from "@vue/test-utils"; 2 | import Counter from "@/components/Counter.vue"; 3 | import sinon from "sinon"; 4 | 5 | describe("Counter.vue", () => { 6 | const change = sinon.spy(); 7 | const wrapper = mount(Counter, { 8 | listeners: { 9 | change 10 | } 11 | }); 12 | it("renders counter html", () => { 13 | expect(wrapper.html()).toMatchSnapshot(); 14 | }); 15 | it("count++", () => { 16 | const button = wrapper.find("button"); 17 | button.trigger("click"); 18 | expect(wrapper.vm.count).toBe(1); 19 | expect(change.called).toBe(true); 20 | button.trigger("click"); 21 | expect(change.callCount).toBe(2); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /test-demo/tests/unit/__snapshots__/Counter.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Counter.vue renders counter html 1`] = `
count: 0
`; 4 | -------------------------------------------------------------------------------- /test-demo/tests/unit/example.spec.js: -------------------------------------------------------------------------------- 1 | import { mount } from "@vue/test-utils"; 2 | import HelloWorld from "@/components/HelloWorld.vue"; 3 | 4 | describe("HelloWorld.vue", () => { 5 | it("renders props.msg when passed", () => { 6 | const msg = "new message"; 7 | const wrapper = mount(HelloWorld, { 8 | propsData: { msg } 9 | }); 10 | expect(wrapper.text()).toMatch(msg); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /vscode-setting.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensions.ignoreRecommendations": false, 3 | "team.showWelcomeMessage": false, 4 | "git.enableSmartCommit": true, 5 | "vsicons.dontShowNewVersionMessage": true, 6 | "git.autofetch": true, 7 | "react.beautify.onSave": true, 8 | "files.associations": { 9 | "*.js": "javascriptreact" 10 | }, 11 | "git.confirmSync": false, 12 | "explorer.confirmDelete": false, 13 | "[markdown]": {}, 14 | "eslint.enable": true, 15 | "eslint.options": { 16 | "extensions": [ 17 | ".js", 18 | ".jsx", 19 | ".vue" 20 | ] 21 | }, 22 | "eslint.validate": [ 23 | "javascript", 24 | "javascriptreact", 25 | { 26 | "language": "vue", 27 | "autoFix": true 28 | } 29 | ], 30 | "vetur.validation.template": false, 31 | "eslint.autoFixOnSave": true, 32 | "editor.tabSize": 2, 33 | "jest.autoEnable": false, 34 | "jest.pathToConfig": "./.jest.js", 35 | "terminal.integrated.rendererType": "dom", 36 | "window.zoomLevel": 0, 37 | "editor.quickSuggestions": { 38 | "strings": true 39 | }, 40 | "diffEditor.renderSideBySide": true 41 | } -------------------------------------------------------------------------------- /vuex-demo1/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | -------------------------------------------------------------------------------- /vuex-demo1/README.md: -------------------------------------------------------------------------------- 1 | # vuex-demo1 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /vuex-demo1/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /vuex-demo1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuex-demo1", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "vue": "^2.6.6", 12 | "vuex": "^3.1.0" 13 | }, 14 | "devDependencies": { 15 | "@vue/cli-plugin-babel": "^3.5.0", 16 | "@vue/cli-plugin-eslint": "^3.5.0", 17 | "@vue/cli-service": "^3.5.0", 18 | "babel-eslint": "^10.0.1", 19 | "eslint": "^5.8.0", 20 | "eslint-plugin-vue": "^5.0.0", 21 | "vue-template-compiler": "^2.5.21" 22 | }, 23 | "eslintConfig": { 24 | "root": true, 25 | "env": { 26 | "node": true 27 | }, 28 | "extends": [ 29 | "plugin:vue/essential", 30 | "eslint:recommended" 31 | ], 32 | "rules": {}, 33 | "parserOptions": { 34 | "parser": "babel-eslint" 35 | } 36 | }, 37 | "postcss": { 38 | "plugins": { 39 | "autoprefixer": {} 40 | } 41 | }, 42 | "browserslist": [ 43 | "> 1%", 44 | "last 2 versions", 45 | "not ie <= 8" 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /vuex-demo1/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/vuex-demo1/public/favicon.ico -------------------------------------------------------------------------------- /vuex-demo1/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vuex-demo1 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /vuex-demo1/src/App.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 22 | 23 | 26 | -------------------------------------------------------------------------------- /vuex-demo1/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/vuex-demo1/src/assets/logo.png -------------------------------------------------------------------------------- /vuex-demo1/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 41 | 42 | 43 | 59 | -------------------------------------------------------------------------------- /vuex-demo1/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import App from './App.vue' 4 | 5 | Vue.use(Vuex) 6 | Vue.config.productionTip = false 7 | 8 | const store = new Vuex.Store({ 9 | state: { 10 | count: 0, 11 | }, 12 | mutations: { 13 | increment(state) { 14 | state.count++ 15 | } 16 | }, 17 | actions: { 18 | increment({commit}) { 19 | setTimeout(()=>{ 20 | // state.count++ // 不要对state进行更改操作,应该通过commit交给mutations去处理 21 | commit('increment') 22 | }, 3000) 23 | } 24 | }, 25 | getters: { 26 | doubleCount(state) { 27 | return state.count * 2 28 | } 29 | } 30 | }) 31 | 32 | new Vue({ 33 | store, 34 | render: h => h(App), 35 | }).$mount('#app') 36 | -------------------------------------------------------------------------------- /vuex-demo2/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | -------------------------------------------------------------------------------- /vuex-demo2/README.md: -------------------------------------------------------------------------------- 1 | # vuex-demo1 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /vuex-demo2/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /vuex-demo2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuex-demo1", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "vue": "^2.6.6", 12 | "vuex": "^3.1.0" 13 | }, 14 | "devDependencies": { 15 | "@vue/cli-plugin-babel": "^3.5.0", 16 | "@vue/cli-plugin-eslint": "^3.5.0", 17 | "@vue/cli-service": "^3.5.0", 18 | "babel-eslint": "^10.0.1", 19 | "eslint": "^5.8.0", 20 | "eslint-plugin-vue": "^5.0.0", 21 | "vue-template-compiler": "^2.5.21" 22 | }, 23 | "eslintConfig": { 24 | "root": true, 25 | "env": { 26 | "node": true 27 | }, 28 | "extends": [ 29 | "plugin:vue/essential", 30 | "eslint:recommended" 31 | ], 32 | "rules": {}, 33 | "parserOptions": { 34 | "parser": "babel-eslint" 35 | } 36 | }, 37 | "postcss": { 38 | "plugins": { 39 | "autoprefixer": {} 40 | } 41 | }, 42 | "browserslist": [ 43 | "> 1%", 44 | "last 2 versions", 45 | "not ie <= 8" 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /vuex-demo2/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/vuex-demo2/public/favicon.ico -------------------------------------------------------------------------------- /vuex-demo2/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vuex-demo1 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /vuex-demo2/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 18 | 19 | 22 | -------------------------------------------------------------------------------- /vuex-demo2/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/vuex-demo2/src/assets/logo.png -------------------------------------------------------------------------------- /vuex-demo2/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 41 | 42 | 43 | 59 | -------------------------------------------------------------------------------- /vuex-demo2/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from './min-vuex' 3 | import App from './App.vue' 4 | 5 | Vue.use(Vuex) 6 | Vue.config.productionTip = false 7 | 8 | const store = new Vuex.Store({ 9 | state: { 10 | count: 0, 11 | }, 12 | mutations: { 13 | increment(state) { 14 | state.count++ 15 | } 16 | }, 17 | // actions: { 18 | // increment({commit}) { 19 | // setTimeout(()=>{ 20 | // // state.count++ // 不要对state进行更改操作,应该通过commit交给mutations去处理 21 | // commit('increment') 22 | // }, 3000) 23 | // } 24 | // }, 25 | // getters: { 26 | // doubleCount(state) { 27 | // return state.count * 2 28 | // } 29 | // } 30 | }) 31 | Vue.prototype.$store = store 32 | new Vue({ 33 | // store, 34 | render: h => h(App), 35 | }).$mount('#app') 36 | -------------------------------------------------------------------------------- /vuex-demo2/src/min-vuex.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | const Store = function Store (options = {}) { 3 | const {state = {}, mutations={}} = options 4 | this._vm = new Vue({ 5 | data: { 6 | $$state: state 7 | }, 8 | }) 9 | this._mutations = mutations 10 | } 11 | Store.prototype.commit = function(type, payload){ 12 | if(this._mutations[type]) { 13 | this._mutations[type](this.state, payload) 14 | } 15 | } 16 | Object.defineProperties(Store.prototype, { 17 | state: { 18 | get: function(){ 19 | return this._vm._data.$$state 20 | } 21 | } 22 | }); 23 | export default {Store} -------------------------------------------------------------------------------- /vuex-demo2_a/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | -------------------------------------------------------------------------------- /vuex-demo2_a/README.md: -------------------------------------------------------------------------------- 1 | # vuex-demo1 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /vuex-demo2_a/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /vuex-demo2_a/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuex-demo1", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "vue": "^2.6.6", 12 | "vuex": "^3.1.0" 13 | }, 14 | "devDependencies": { 15 | "@vue/cli-plugin-babel": "^3.5.0", 16 | "@vue/cli-plugin-eslint": "^3.5.0", 17 | "@vue/cli-service": "^3.5.0", 18 | "babel-eslint": "^10.0.1", 19 | "eslint": "^5.8.0", 20 | "eslint-plugin-vue": "^5.0.0", 21 | "vue-template-compiler": "^2.5.21" 22 | }, 23 | "eslintConfig": { 24 | "root": true, 25 | "env": { 26 | "node": true 27 | }, 28 | "extends": [ 29 | "plugin:vue/essential", 30 | "eslint:recommended" 31 | ], 32 | "rules": {}, 33 | "parserOptions": { 34 | "parser": "babel-eslint" 35 | } 36 | }, 37 | "postcss": { 38 | "plugins": { 39 | "autoprefixer": {} 40 | } 41 | }, 42 | "browserslist": [ 43 | "> 1%", 44 | "last 2 versions", 45 | "not ie <= 8" 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /vuex-demo2_a/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/vuex-demo2_a/public/favicon.ico -------------------------------------------------------------------------------- /vuex-demo2_a/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vuex-demo1 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /vuex-demo2_a/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 19 | 20 | 23 | -------------------------------------------------------------------------------- /vuex-demo2_a/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/vuex-demo2_a/src/assets/logo.png -------------------------------------------------------------------------------- /vuex-demo2_a/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 41 | 42 | 43 | 59 | -------------------------------------------------------------------------------- /vuex-demo2_a/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from './min-vuex' 3 | import App from './App.vue' 4 | 5 | Vue.use(Vuex) 6 | Vue.config.productionTip = false 7 | 8 | const store = new Vuex.Store({ 9 | state: { 10 | count: 0, 11 | }, 12 | mutations: { 13 | increment(state) { 14 | state.count++ 15 | } 16 | }, 17 | // actions: { 18 | // increment({commit}) { 19 | // setTimeout(()=>{ 20 | // // state.count++ // 不要对state进行更改操作,应该通过commit交给mutations去处理 21 | // commit('increment') 22 | // }, 3000) 23 | // } 24 | // }, 25 | getters: { 26 | doubleCount(state) { 27 | return state.count * 2 28 | } 29 | } 30 | }) 31 | 32 | new Vue({ 33 | store, 34 | render: h => h(App), 35 | }).$mount('#app') 36 | -------------------------------------------------------------------------------- /vuex-demo2_a/src/min-vuex.js: -------------------------------------------------------------------------------- 1 | 2 | let Vue; 3 | function install (_Vue) { 4 | Vue = _Vue; 5 | function vuexInit () { 6 | var options = this.$options; 7 | // store injection 8 | if (options.store) { 9 | this.$store = typeof options.store === 'function' 10 | ? options.store() 11 | : options.store; 12 | } else if (options.parent && options.parent.$store) { 13 | this.$store = options.parent.$store; 14 | } 15 | } 16 | Vue.mixin({ beforeCreate: vuexInit }); 17 | } 18 | 19 | const Store = function Store (options = {}) { 20 | const {state = {}, mutations={}, getters={}} = options 21 | const computed = {} 22 | const store = this 23 | store.getters = {}; 24 | for (let [key, fn] of Object.entries(getters)) { 25 | computed[key] = function () { return fn(store.state, store.getters); }; 26 | Object.defineProperty(store.getters, key, { 27 | get: function () { return store._vm[key]; }, 28 | }); 29 | } 30 | this._vm = new Vue({ 31 | data: { 32 | $$state: state 33 | }, 34 | computed, 35 | }) 36 | this._mutations = mutations 37 | } 38 | Store.prototype.commit = function(type, payload){ 39 | if(this._mutations[type]) { 40 | this._mutations[type](this.state, payload) 41 | } 42 | } 43 | Object.defineProperties(Store.prototype, { 44 | state: { 45 | get: function(){ 46 | return this._vm._data.$$state 47 | } 48 | } 49 | }); 50 | export default {Store, install} -------------------------------------------------------------------------------- /vuex-demo3/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | -------------------------------------------------------------------------------- /vuex-demo3/README.md: -------------------------------------------------------------------------------- 1 | # hello-world 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /vuex-demo3/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /vuex-demo3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hello-world", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "vue": "^2.6.6", 12 | "vuex": "^3.1.0" 13 | }, 14 | "devDependencies": { 15 | "@vue/cli-plugin-babel": "^3.5.0", 16 | "@vue/cli-plugin-eslint": "^3.5.0", 17 | "@vue/cli-service": "^3.5.0", 18 | "babel-eslint": "^10.0.1", 19 | "eslint": "^5.8.0", 20 | "eslint-plugin-vue": "^5.0.0", 21 | "vue-template-compiler": "^2.5.21" 22 | }, 23 | "eslintConfig": { 24 | "root": true, 25 | "env": { 26 | "node": true 27 | }, 28 | "extends": [ 29 | "plugin:vue/essential", 30 | "eslint:recommended" 31 | ], 32 | "rules": {}, 33 | "parserOptions": { 34 | "parser": "babel-eslint" 35 | } 36 | }, 37 | "postcss": { 38 | "plugins": { 39 | "autoprefixer": {} 40 | } 41 | }, 42 | "browserslist": [ 43 | "> 1%", 44 | "last 2 versions", 45 | "not ie <= 8" 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /vuex-demo3/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/vuex-demo3/public/favicon.ico -------------------------------------------------------------------------------- /vuex-demo3/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | hello-world 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /vuex-demo3/src/App.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 25 | -------------------------------------------------------------------------------- /vuex-demo3/src/api/shop.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Mocking client-server processing 3 | */ 4 | const _products = [ 5 | {"id": 1, "title": "华为 Mate 20", "price": 3999, "inventory": 2}, 6 | {"id": 2, "title": "小米 9", "price": 2999, "inventory": 0}, 7 | {"id": 3, "title": "OPPO R17", "price": 2999, "inventory": 5} 8 | ] 9 | 10 | export default { 11 | getProducts (cb) { 12 | setTimeout(() => cb(_products), 100) 13 | }, 14 | 15 | buyProducts (products, cb, errorCb) { 16 | setTimeout(() => { 17 | // simulate random checkout failure. 18 | Math.random() > 0.5 19 | ? cb() 20 | : errorCb() 21 | }, 100) 22 | } 23 | } -------------------------------------------------------------------------------- /vuex-demo3/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/vuex-demo3/src/assets/logo.png -------------------------------------------------------------------------------- /vuex-demo3/src/components/ProductList.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 42 | -------------------------------------------------------------------------------- /vuex-demo3/src/components/ShoppingCart.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 53 | -------------------------------------------------------------------------------- /vuex-demo3/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import store from './store' 4 | 5 | Vue.config.productionTip = false 6 | 7 | new Vue({ 8 | store, 9 | render: h => h(App), 10 | }).$mount('#app') 11 | -------------------------------------------------------------------------------- /vuex-demo3/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import cart from './modules/cart' 4 | import products from './modules/products' 5 | 6 | Vue.use(Vuex) 7 | export default new Vuex.Store({ 8 | state: { 9 | userInfo: { 10 | email: "xxxxxx@qq.com" 11 | } 12 | }, 13 | modules: { 14 | cart, 15 | products 16 | }, 17 | }) -------------------------------------------------------------------------------- /vuex-demo3/src/store/modules/cart.js: -------------------------------------------------------------------------------- 1 | import shop from '../../api/shop' 2 | import { CART, PRODUCTS } from '../mutation-types' 3 | 4 | // initial state 5 | // shape: [{ id, quantity }] 6 | const state = { 7 | items: [], 8 | checkoutStatus: null 9 | } 10 | 11 | // getters 12 | const getters = { 13 | cartProducts: (state, getters, rootState) => { 14 | return state.items.map(({ id, quantity }) => { 15 | const product = rootState.products.all.find(product => product.id === id) 16 | return { 17 | title: product.title, 18 | price: product.price, 19 | quantity 20 | } 21 | }) 22 | }, 23 | 24 | cartTotalPrice: (state, getters) => { 25 | return getters.cartProducts.reduce((total, product) => { 26 | return total + product.price * product.quantity 27 | }, 0) 28 | } 29 | } 30 | 31 | // actions 32 | const actions = { 33 | checkout ({ commit, state }, products) { 34 | const savedCartItems = [...state.items] 35 | commit(CART.SET_CHECKOUT_STATUS, null) 36 | // empty cart 37 | commit(CART.SET_CART_ITEMS, { items: [] }) 38 | shop.buyProducts( 39 | products, 40 | () => commit(CART.SET_CHECKOUT_STATUS, 'successful'), 41 | () => { 42 | commit(CART.SET_CHECKOUT_STATUS, 'failed') 43 | // rollback to the cart saved before sending the request 44 | commit(CART.SET_CART_ITEMS, { items: savedCartItems }) 45 | } 46 | ) 47 | }, 48 | 49 | addProductToCart ({ state, commit }, product) { 50 | commit(CART.SET_CHECKOUT_STATUS, null) 51 | if (product.inventory > 0) { 52 | const cartItem = state.items.find(item => item.id === product.id) 53 | if (!cartItem) { 54 | commit(CART.PUSH_PRODUCT_TO_CART, { id: product.id }) 55 | } else { 56 | commit(CART.INCREMENT_ITEM_QUANTITY, cartItem) 57 | } 58 | // remove 1 item from stock 59 | commit(`products/${PRODUCTS.DECREMENT_PRODUCT_INVENTORY}`, { id: product.id }, { root: true }) 60 | } 61 | } 62 | } 63 | 64 | // mutations 65 | const mutations = { 66 | [CART.PUSH_PRODUCT_TO_CART] (state, { id }) { 67 | state.items.push({ 68 | id, 69 | quantity: 1 70 | }) 71 | }, 72 | 73 | [CART.INCREMENT_ITEM_QUANTITY] (state, { id }) { 74 | const cartItem = state.items.find(item => item.id === id) 75 | cartItem.quantity++ 76 | }, 77 | 78 | [CART.SET_CART_ITEMS] (state, { items }) { 79 | state.items = items 80 | }, 81 | 82 | [CART.SET_CHECKOUT_STATUS] (state, status) { 83 | state.checkoutStatus = status 84 | } 85 | } 86 | 87 | export default { 88 | namespaced: true, 89 | state, 90 | getters, 91 | actions, 92 | mutations 93 | } 94 | -------------------------------------------------------------------------------- /vuex-demo3/src/store/modules/products.js: -------------------------------------------------------------------------------- 1 | import shop from '../../api/shop' 2 | import {PRODUCTS} from '../mutation-types' 3 | 4 | // initial state 5 | const state = { 6 | all: [] 7 | } 8 | 9 | // getters 10 | const getters = {} 11 | 12 | // actions 13 | const actions = { 14 | getAllProducts ({ commit }) { 15 | shop.getProducts(products => { 16 | commit(PRODUCTS.SET_PRODUCTS, products) 17 | }) 18 | } 19 | } 20 | 21 | // mutations 22 | const mutations = { 23 | [PRODUCTS.SET_PRODUCTS] (state, products) { 24 | state.all = products 25 | }, 26 | 27 | [PRODUCTS.DECREMENT_PRODUCT_INVENTORY] (state, { id }) { 28 | const product = state.all.find(product => product.id === id) 29 | product.inventory-- 30 | } 31 | } 32 | 33 | export default { 34 | namespaced: true, 35 | state, 36 | getters, 37 | actions, 38 | mutations 39 | } -------------------------------------------------------------------------------- /vuex-demo3/src/store/mutation-types.js: -------------------------------------------------------------------------------- 1 | export const CART = { 2 | PUSH_PRODUCT_TO_CART: 'pushProductToCart', 3 | INCREMENT_ITEM_QUANTITY: 'incrementItemQuantity', 4 | SET_CART_ITEMS: 'setCartItems', 5 | SET_CHECKOUT_STATUS: 'setCheckoutStatus', 6 | } 7 | 8 | export const PRODUCTS = { 9 | SET_PRODUCTS:'setProducts', 10 | DECREMENT_PRODUCT_INVENTORY: 'decrementProductInventory' 11 | } -------------------------------------------------------------------------------- /vuex-demo3_a/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw* 22 | -------------------------------------------------------------------------------- /vuex-demo3_a/README.md: -------------------------------------------------------------------------------- 1 | # hello-world 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /vuex-demo3_a/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /vuex-demo3_a/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hello-world", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "vue": "^2.6.6", 12 | "vuex": "^3.1.0" 13 | }, 14 | "devDependencies": { 15 | "@vue/cli-plugin-babel": "^3.5.0", 16 | "@vue/cli-plugin-eslint": "^3.5.0", 17 | "@vue/cli-service": "^3.5.0", 18 | "babel-eslint": "^10.0.1", 19 | "eslint": "^5.8.0", 20 | "eslint-plugin-vue": "^5.0.0", 21 | "vue-template-compiler": "^2.5.21" 22 | }, 23 | "eslintConfig": { 24 | "root": true, 25 | "env": { 26 | "node": true 27 | }, 28 | "extends": [ 29 | "plugin:vue/essential", 30 | "eslint:recommended" 31 | ], 32 | "rules": {}, 33 | "parserOptions": { 34 | "parser": "babel-eslint" 35 | } 36 | }, 37 | "postcss": { 38 | "plugins": { 39 | "autoprefixer": {} 40 | } 41 | }, 42 | "browserslist": [ 43 | "> 1%", 44 | "last 2 versions", 45 | "not ie <= 8" 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /vuex-demo3_a/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/vuex-demo3_a/public/favicon.ico -------------------------------------------------------------------------------- /vuex-demo3_a/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | hello-world 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /vuex-demo3_a/src/App.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 25 | -------------------------------------------------------------------------------- /vuex-demo3_a/src/api/shop.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Mocking client-server processing 3 | */ 4 | const _products = [ 5 | {"id": 1, "title": "华为 Mate 20", "price": 3999, "inventory": 2}, 6 | {"id": 2, "title": "小米 9", "price": 2999, "inventory": 0}, 7 | {"id": 3, "title": "OPPO R17", "price": 2999, "inventory": 5} 8 | ] 9 | 10 | export default { 11 | getProducts (cb) { 12 | setTimeout(() => cb(_products), 100) 13 | }, 14 | 15 | buyProducts (products, cb, errorCb) { 16 | setTimeout(() => { 17 | // simulate random checkout failure. 18 | Math.random() > 0.5 19 | ? cb() 20 | : errorCb() 21 | }, 100) 22 | } 23 | } -------------------------------------------------------------------------------- /vuex-demo3_a/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/vuex-demo3_a/src/assets/logo.png -------------------------------------------------------------------------------- /vuex-demo3_a/src/components/ProductList.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 70 | -------------------------------------------------------------------------------- /vuex-demo3_a/src/components/ShoppingCart.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 53 | -------------------------------------------------------------------------------- /vuex-demo3_a/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import store from './store' 4 | 5 | Vue.config.productionTip = false 6 | 7 | new Vue({ 8 | store, 9 | render: h => h(App), 10 | }).$mount('#app') 11 | -------------------------------------------------------------------------------- /vuex-demo3_a/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import cart from './modules/cart' 4 | import products from './modules/products' 5 | 6 | Vue.use(Vuex) 7 | export default new Vuex.Store({ 8 | state: { 9 | userInfo: { 10 | email: "xxxxxx@qq.com" 11 | } 12 | }, 13 | modules: { 14 | cart, 15 | products 16 | }, 17 | }) -------------------------------------------------------------------------------- /vuex-demo3_a/src/store/modules/cart.js: -------------------------------------------------------------------------------- 1 | import shop from '../../api/shop' 2 | import { CART, PRODUCTS } from '../mutation-types' 3 | 4 | // initial state 5 | // shape: [{ id, quantity }] 6 | const state = { 7 | items: [], 8 | checkoutStatus: null 9 | } 10 | 11 | // getters 12 | const getters = { 13 | cartProducts: (state, getters, rootState) => { 14 | return state.items.map(({ id, quantity }) => { 15 | const product = rootState.products.all.find(product => product.id === id) 16 | return { 17 | title: product.title, 18 | price: product.price, 19 | quantity 20 | } 21 | }) 22 | }, 23 | 24 | cartTotalPrice: (state, getters) => { 25 | return getters.cartProducts.reduce((total, product) => { 26 | return total + product.price * product.quantity 27 | }, 0) 28 | } 29 | } 30 | 31 | // actions 32 | const actions = { 33 | checkout ({ commit, state }, products) { 34 | const savedCartItems = [...state.items] 35 | commit(CART.SET_CHECKOUT_STATUS, null) 36 | // empty cart 37 | commit(CART.SET_CART_ITEMS, { items: [] }) 38 | shop.buyProducts( 39 | products, 40 | () => commit(CART.SET_CHECKOUT_STATUS, 'successful'), 41 | () => { 42 | commit(CART.SET_CHECKOUT_STATUS, 'failed') 43 | // rollback to the cart saved before sending the request 44 | commit(CART.SET_CART_ITEMS, { items: savedCartItems }) 45 | } 46 | ) 47 | }, 48 | 49 | addProductToCart ({ state, commit }, {product, number}) { 50 | commit(CART.SET_CHECKOUT_STATUS, null) 51 | if (product.inventory > 0) { 52 | const cartItem = state.items.find(item => item.id === product.id) 53 | if (!cartItem) { 54 | commit(CART.PUSH_PRODUCT_TO_CART, { id: product.id, number }) 55 | } else { 56 | commit(CART.INCREMENT_ITEM_QUANTITY, {cartItem, number}) 57 | } 58 | // remove number item from stock 59 | commit(`products/${PRODUCTS.DECREMENT_PRODUCT_INVENTORY}`, { id: product.id, number }, { root: true }) 60 | } 61 | } 62 | } 63 | 64 | // mutations 65 | const mutations = { 66 | [CART.PUSH_PRODUCT_TO_CART] (state, { id, number }) { 67 | state.items.push({ 68 | id, 69 | quantity: number 70 | }) 71 | }, 72 | 73 | [CART.INCREMENT_ITEM_QUANTITY] (state, { cartItem: {id}, number }) { 74 | const cartItem = state.items.find(item => item.id === id) 75 | cartItem.quantity += number 76 | }, 77 | 78 | [CART.SET_CART_ITEMS] (state, { items }) { 79 | state.items = items 80 | }, 81 | 82 | [CART.SET_CHECKOUT_STATUS] (state, status) { 83 | state.checkoutStatus = status 84 | } 85 | } 86 | 87 | export default { 88 | namespaced: true, 89 | state, 90 | getters, 91 | actions, 92 | mutations 93 | } 94 | -------------------------------------------------------------------------------- /vuex-demo3_a/src/store/modules/products.js: -------------------------------------------------------------------------------- 1 | import shop from '../../api/shop' 2 | import {PRODUCTS} from '../mutation-types' 3 | 4 | // initial state 5 | const state = { 6 | all: [] 7 | } 8 | 9 | // getters 10 | const getters = {} 11 | 12 | // actions 13 | const actions = { 14 | getAllProducts ({ commit }) { 15 | shop.getProducts(products => { 16 | commit(PRODUCTS.SET_PRODUCTS, products) 17 | }) 18 | } 19 | } 20 | 21 | // mutations 22 | const mutations = { 23 | [PRODUCTS.SET_PRODUCTS] (state, products) { 24 | state.all = products 25 | }, 26 | 27 | [PRODUCTS.DECREMENT_PRODUCT_INVENTORY] (state, { id, number }) { 28 | const product = state.all.find(product => product.id === id) 29 | product.inventory -= number 30 | } 31 | } 32 | 33 | export default { 34 | namespaced: true, 35 | state, 36 | getters, 37 | actions, 38 | mutations 39 | } -------------------------------------------------------------------------------- /vuex-demo3_a/src/store/mutation-types.js: -------------------------------------------------------------------------------- 1 | export const CART = { 2 | PUSH_PRODUCT_TO_CART: 'pushProductToCart', 3 | INCREMENT_ITEM_QUANTITY: 'incrementItemQuantity', 4 | SET_CART_ITEMS: 'setCartItems', 5 | SET_CHECKOUT_STATUS: 'setCheckoutStatus', 6 | } 7 | 8 | export const PRODUCTS = { 9 | SET_PRODUCTS:'setProducts', 10 | DECREMENT_PRODUCT_INVENTORY: 'decrementProductInventory' 11 | } -------------------------------------------------------------------------------- /《Vue开发实战》基础篇课件.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/《Vue开发实战》基础篇课件.pdf -------------------------------------------------------------------------------- /《Vue开发实战》生态篇课件.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/《Vue开发实战》生态篇课件.pdf -------------------------------------------------------------------------------- /基础篇4-7/index4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 |
13 | {{message}} {{message + message}} 14 |
15 |
    16 |
  • 17 | {{item.title}} 18 | {{item.title}} 19 | 20 |
  • 21 |
22 |
23 | 24 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /基础篇4-7/index5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 |
13 | {{message}} {{message + message}} 14 |
15 | 18 | 19 |
20 | 21 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /基础篇4-7/index6.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 |
13 | {{message}} {{message + message}} 14 |
15 | 18 | 19 |
20 | 21 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /基础篇4-7/index7.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 |
13 | {{message}} {{message + message}} 14 |
15 | 18 | 19 | 20 | 23 | 24 | 25 | 26 |
27 | 28 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /基础篇8-10/vue-demo1/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /基础篇8-10/vue-demo1/README.md: -------------------------------------------------------------------------------- 1 | # vue-demo 2 | 3 | ## Project setup 4 | ``` 5 | yarn install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | yarn run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | yarn run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | yarn run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | yarn run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /基础篇8-10/vue-demo1/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /基础篇8-10/vue-demo1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-demo", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "core-js": "^3.1.2", 12 | "vue": "^2.6.10" 13 | }, 14 | "devDependencies": { 15 | "@vue/cli-plugin-babel": "^4.0.0", 16 | "@vue/cli-plugin-eslint": "^4.0.0", 17 | "@vue/cli-service": "^4.0.0", 18 | "babel-eslint": "^10.0.1", 19 | "eslint": "^5.16.0", 20 | "eslint-plugin-vue": "^5.0.0", 21 | "vue-template-compiler": "^2.6.10" 22 | }, 23 | "eslintConfig": { 24 | "root": true, 25 | "env": { 26 | "node": true 27 | }, 28 | "extends": [ 29 | "plugin:vue/essential", 30 | "eslint:recommended" 31 | ], 32 | "rules": {}, 33 | "parserOptions": { 34 | "parser": "babel-eslint" 35 | } 36 | }, 37 | "postcss": { 38 | "plugins": { 39 | "autoprefixer": {} 40 | } 41 | }, 42 | "browserslist": [ 43 | "> 1%", 44 | "last 2 versions" 45 | ] 46 | } -------------------------------------------------------------------------------- /基础篇8-10/vue-demo1/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/基础篇8-10/vue-demo1/public/favicon.ico -------------------------------------------------------------------------------- /基础篇8-10/vue-demo1/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vue-demo 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /基础篇8-10/vue-demo1/src/App.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 53 | -------------------------------------------------------------------------------- /基础篇8-10/vue-demo1/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/基础篇8-10/vue-demo1/src/assets/logo.png -------------------------------------------------------------------------------- /基础篇8-10/vue-demo1/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 41 | 42 | 43 | 59 | -------------------------------------------------------------------------------- /基础篇8-10/vue-demo1/src/components/TodoItem.vue: -------------------------------------------------------------------------------- 1 | 10 | 33 | -------------------------------------------------------------------------------- /基础篇8-10/vue-demo1/src/components/TodoList.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /基础篇8-10/vue-demo1/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import TodoList from './components/TodoList.vue' 4 | 5 | Vue.component('todo-list', TodoList) 6 | Vue.config.productionTip = false 7 | 8 | new Vue({ 9 | render: h => h(App), 10 | }).$mount('#app') 11 | -------------------------------------------------------------------------------- /演示DEMO源码/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "env": { 4 | "node": true 5 | }, 6 | "extends": [ 7 | "plugin:vue/recommended", 8 | "@vue/eslint-config-prettier" 9 | ], 10 | "rules": { 11 | "vue/require-default-prop": "off", 12 | "no-console": "off", 13 | "vue/v-bind-style": "off", 14 | "vue/v-on-style": "off", 15 | "no-unused-vars": "off", 16 | "vue/no-v-html": "off" 17 | }, 18 | "parserOptions": { 19 | "parser": "babel-eslint" 20 | }, 21 | "globals": { 22 | "location": true, 23 | "document": true, 24 | "window": true, 25 | "GLOBAL": true 26 | } 27 | } -------------------------------------------------------------------------------- /演示DEMO源码/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | -------------------------------------------------------------------------------- /演示DEMO源码/README.md: -------------------------------------------------------------------------------- 1 | # geektime-vue 2 | 3 | ## 安装依赖 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### 启动环境 9 | ``` 10 | npm run serve 11 | ``` -------------------------------------------------------------------------------- /演示DEMO源码/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@vue/app"] 3 | }; 4 | -------------------------------------------------------------------------------- /演示DEMO源码/cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginsFile": "tests/e2e/plugins/index.js" 3 | } 4 | -------------------------------------------------------------------------------- /演示DEMO源码/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: ["js", "jsx", "json", "vue"], 3 | transform: { 4 | "^.+\\.vue$": "vue-jest", 5 | ".+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$": 6 | "jest-transform-stub", 7 | "^.+\\.jsx?$": "babel-jest" 8 | }, 9 | moduleNameMapper: { 10 | "^@/(.*)$": "/src/$1" 11 | }, 12 | snapshotSerializers: ["jest-serializer-vue"], 13 | testMatch: [ 14 | "**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)" 15 | ], 16 | testURL: "http://localhost/" 17 | }; 18 | -------------------------------------------------------------------------------- /演示DEMO源码/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "geektime-vue", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint", 9 | "test:e2e": "vue-cli-service test:e2e", 10 | "test:unit": "vue-cli-service test:unit" 11 | }, 12 | "dependencies": { 13 | "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0-beta.2", 14 | "@vue/babel-preset-jsx": "^1.0.0-beta.2", 15 | "ant-design-vue": "^1.3.5", 16 | "moment": "^2.24.0", 17 | "vue": "^2.6.8", 18 | "vue-ref": "^1.0.4", 19 | "vue-router": "^3.0.1", 20 | "vuex": "^3.0.1" 21 | }, 22 | "devDependencies": { 23 | "@vue/cli-plugin-babel": "^3.4.0", 24 | "@vue/cli-plugin-e2e-cypress": "^3.4.0", 25 | "@vue/cli-plugin-eslint": "^3.4.0", 26 | "@vue/cli-plugin-unit-jest": "^3.4.0", 27 | "@vue/cli-service": "^3.4.0", 28 | "@vue/eslint-config-prettier": "^4.0.1", 29 | "@vue/test-utils": "^1.0.0-beta.20", 30 | "babel-core": "7.0.0-bridge.0", 31 | "babel-eslint": "^10.0.1", 32 | "babel-jest": "^23.6.0", 33 | "eslint": "^5.8.0", 34 | "eslint-plugin-vue": "^5.0.0", 35 | "less": "^3.0.4", 36 | "less-loader": "^4.1.0", 37 | "vue-template-compiler": "^2.6.8" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /演示DEMO源码/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /演示DEMO源码/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/演示DEMO源码/public/favicon.ico -------------------------------------------------------------------------------- /演示DEMO源码/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | geektime-vue 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /演示DEMO源码/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | -------------------------------------------------------------------------------- /演示DEMO源码/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geektime-geekbang/geektime-vue-1/1dc856cf235869163437ce8e9d21833dfa1b53b1/演示DEMO源码/src/assets/logo.png -------------------------------------------------------------------------------- /演示DEMO源码/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 104 | 105 | 113 | 114 | 115 | 131 | -------------------------------------------------------------------------------- /演示DEMO源码/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import antd from "ant-design-vue"; 3 | import ref from "vue-ref"; 4 | import App from "./App.vue"; 5 | import router from "./router"; 6 | import store from "./store"; 7 | import "ant-design-vue/dist/antd.css"; 8 | 9 | Vue.config.productionTip = false; 10 | 11 | Vue.use(antd); 12 | Vue.use(ref, { name: "ant-ref" }); 13 | 14 | new Vue({ 15 | router, 16 | store, 17 | render: h => h(App) 18 | }).$mount("#app"); 19 | -------------------------------------------------------------------------------- /演示DEMO源码/src/router.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import Router from "vue-router"; 3 | import Home from "./views/Home.vue"; 4 | 5 | Vue.use(Router); 6 | 7 | export default new Router({ 8 | routes: [ 9 | { 10 | path: "/", 11 | name: "home", 12 | component: Home 13 | }, 14 | { 15 | path: "/1.4", 16 | name: "如何触发组件的更新", 17 | component: () => import("./views/1.4") 18 | }, 19 | { 20 | path: "/1.5", 21 | name: "合理应用计算属性和侦听器", 22 | component: () => import("./views/1.5") 23 | }, 24 | { 25 | path: "/1.6", 26 | name: "生命周期的应用场景和函数式组件", 27 | component: () => import("./views/1.6") 28 | }, 29 | { 30 | path: "/1.7", 31 | name: "指令的本质", 32 | component: () => import("./views/1.7") 33 | }, 34 | { 35 | path: "/1.8", 36 | name: "provie/inject", 37 | component: () => import("./views/1.8") 38 | }, 39 | { 40 | path: "/1.9", 41 | name: "如何优雅的获取跨层级组件(拒绝递归)", 42 | component: () => import("./views/1.9") 43 | }, 44 | { 45 | path: "/1.10", 46 | name: "template 和 JSX 对比及其他们的本质", 47 | component: () => import("./views/1.10") 48 | } 49 | ] 50 | }); 51 | -------------------------------------------------------------------------------- /演示DEMO源码/src/store.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import Vuex from "vuex"; 3 | 4 | Vue.use(Vuex); 5 | 6 | export default new Vuex.Store({ 7 | state: {}, 8 | mutations: {}, 9 | actions: {} 10 | }); 11 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.10/AnchoredHeading.js: -------------------------------------------------------------------------------- 1 | export default { 2 | props: { 3 | level: { 4 | type: Number, 5 | default: 1 6 | } 7 | }, 8 | render: function(createElement) { 9 | return createElement( 10 | "h" + this.level, // 标签名称 11 | this.$slots.default // 子元素数组 12 | ); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.10/AnchoredHeading.jsx: -------------------------------------------------------------------------------- 1 | export default { 2 | props: { 3 | level: { 4 | type: Number, 5 | default: 1 6 | } 7 | }, 8 | render: function(h) { 9 | const Tag = `h${this.level}`; 10 | return {this.$slots.default}; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.10/AnchoredHeading.vue: -------------------------------------------------------------------------------- 1 | 21 | 31 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.10/index.vue: -------------------------------------------------------------------------------- 1 | 12 | 43 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.4/PropsAndData.vue: -------------------------------------------------------------------------------- 1 | 12 | 37 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.4/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 45 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.5/Computed.vue: -------------------------------------------------------------------------------- 1 | 11 | 42 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.5/Computed1.vue: -------------------------------------------------------------------------------- 1 | 9 | 29 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.5/Watch.vue: -------------------------------------------------------------------------------- 1 | 8 | 48 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.5/Watch1.vue: -------------------------------------------------------------------------------- 1 | 9 | 28 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.5/Watch1_pro.vue: -------------------------------------------------------------------------------- 1 | 9 | 34 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.5/index.vue: -------------------------------------------------------------------------------- 1 | 21 | 37 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.6/Clock.vue: -------------------------------------------------------------------------------- 1 | 8 | 63 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.6/Functional.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.6/TempVar.js: -------------------------------------------------------------------------------- 1 | export default { 2 | functional: true, 3 | render: (h, ctx) => { 4 | return ctx.scopedSlots.default && ctx.scopedSlots.default(ctx.props || {}); 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.6/index.vue: -------------------------------------------------------------------------------- 1 | 25 | 43 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.7/CustomerDirectives.vue: -------------------------------------------------------------------------------- 1 | 11 | 43 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.7/Directives.vue: -------------------------------------------------------------------------------- 1 | 30 | 42 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.7/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 21 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.8/ChildrenA.vue: -------------------------------------------------------------------------------- 1 | 10 | 48 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.8/ChildrenA_a.vue: -------------------------------------------------------------------------------- 1 | 10 | 40 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.8/ChildrenB.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.8/ChildrenC.vue: -------------------------------------------------------------------------------- 1 | 8 | 25 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.8/ChildrenD.vue: -------------------------------------------------------------------------------- 1 | 9 | 21 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.8/ChildrenE.vue: -------------------------------------------------------------------------------- 1 | 7 | 24 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.8/ChildrenF.vue: -------------------------------------------------------------------------------- 1 | 6 | 17 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.8/ChildrenG.vue: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.8/ChildrenH.vue: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.8/ChildrenI.vue: -------------------------------------------------------------------------------- 1 | 6 | 15 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.8/index.vue: -------------------------------------------------------------------------------- 1 | 7 | 17 | 32 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.9/ChildrenA.vue: -------------------------------------------------------------------------------- 1 | 10 | 45 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.9/ChildrenB.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.9/ChildrenC.vue: -------------------------------------------------------------------------------- 1 | 8 | 18 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.9/ChildrenD.vue: -------------------------------------------------------------------------------- 1 | 9 | 26 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.9/ChildrenE.vue: -------------------------------------------------------------------------------- 1 | 8 | 18 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.9/ChildrenF.vue: -------------------------------------------------------------------------------- 1 | 8 | 31 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.9/ChildrenG.vue: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.9/ChildrenH.vue: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.9/ChildrenI.vue: -------------------------------------------------------------------------------- 1 | 6 | 15 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/1.9/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 14 | 29 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/About.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /演示DEMO源码/src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 50 | 51 | 63 | -------------------------------------------------------------------------------- /演示DEMO源码/tests/e2e/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: ["cypress"], 3 | env: { 4 | mocha: true, 5 | "cypress/globals": true 6 | }, 7 | rules: { 8 | strict: "off" 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /演示DEMO源码/tests/e2e/plugins/index.js: -------------------------------------------------------------------------------- 1 | // https://docs.cypress.io/guides/guides/plugins-guide.html 2 | 3 | // if you need a custom webpack configuration you can uncomment the following import 4 | // and then use the `file:preprocessor` event 5 | // as explained in the cypress docs 6 | // https://docs.cypress.io/api/plugins/preprocessors-api.html#Examples 7 | 8 | /* eslint-disable import/no-extraneous-dependencies, global-require, arrow-body-style */ 9 | // const webpack = require('@cypress/webpack-preprocessor') 10 | 11 | module.exports = (on, config) => { 12 | // on('file:preprocessor', webpack({ 13 | // webpackOptions: require('@vue/cli-service/webpack.config'), 14 | // watchOptions: {} 15 | // })) 16 | 17 | return Object.assign({}, config, { 18 | fixturesFolder: "tests/e2e/fixtures", 19 | integrationFolder: "tests/e2e/specs", 20 | screenshotsFolder: "tests/e2e/screenshots", 21 | videosFolder: "tests/e2e/videos", 22 | supportFile: "tests/e2e/support/index.js" 23 | }); 24 | }; 25 | -------------------------------------------------------------------------------- /演示DEMO源码/tests/e2e/specs/test.js: -------------------------------------------------------------------------------- 1 | // https://docs.cypress.io/api/introduction/api.html 2 | 3 | describe("My First Test", () => { 4 | it("Visits the app root url", () => { 5 | cy.visit("/"); 6 | cy.contains("h1", "Welcome to Your Vue.js App"); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /演示DEMO源码/tests/e2e/support/commands.js: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | // 11 | // 12 | // -- This is a parent command -- 13 | // Cypress.Commands.add("login", (email, password) => { ... }) 14 | // 15 | // 16 | // -- This is a child command -- 17 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) 18 | // 19 | // 20 | // -- This is a dual command -- 21 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) 22 | // 23 | // 24 | // -- This is will overwrite an existing command -- 25 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) 26 | -------------------------------------------------------------------------------- /演示DEMO源码/tests/e2e/support/index.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import "./commands"; 18 | 19 | // Alternatively you can use CommonJS syntax: 20 | // require('./commands') 21 | -------------------------------------------------------------------------------- /演示DEMO源码/tests/unit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | jest: true 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /演示DEMO源码/tests/unit/example.spec.js: -------------------------------------------------------------------------------- 1 | import { shallowMount } from "@vue/test-utils"; 2 | import HelloWorld from "@/components/HelloWorld.vue"; 3 | 4 | describe("HelloWorld.vue", () => { 5 | it("renders props.msg when passed", () => { 6 | const msg = "new message"; 7 | const wrapper = shallowMount(HelloWorld, { 8 | propsData: { msg } 9 | }); 10 | expect(wrapper.text()).toMatch(msg); 11 | }); 12 | }); 13 | --------------------------------------------------------------------------------