提交 4915c8f0 编写于 作者: J Jeff Fox

Chapter 2

上级 02560028
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# vue-example-ch2-github-app-vue-cli
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
此差异已折叠。
{
"name": "vue-example-ch2-github-app-vue-cli",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.6.5",
"register-service-worker": "^1.7.1",
"vue": "^3.0.0-0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-pwa": "^4.5.6",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0-0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^7.0.0-0"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.00251 14.9297L0 1.07422H6.14651L8.00251 4.27503L9.84583 1.07422H16L8.00251 14.9297Z" fill="black"/>
</svg>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<script src="<%= BASE_URL %>octokit-rest.min.js"></script>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
因为 它太大了无法显示 source diff 。你可以改为 查看blob
<template>
<div>
<h1>Github App</h1>
<GitHubTokenForm />
<User />
<Repos />
</div>
</template>
<script>
import GitHubTokenForm from "./components/GitHubTokenForm.vue";
import Repos from "./components/Repos.vue";
import User from "./components/User.vue";
export default {
name: "App",
components: {
GitHubTokenForm,
Repos,
User,
},
};
</script>
<template>
<form @submit.prevent="saveToken">
<div>
<label for="githubToken">Github Token</label>
<br />
<input id="githubToken" v-model="githubToken" />
</div>
<div>
<input type="submit" value="Save token" />
<button type="button" @click="clearToken">Clear token</button>
</div>
</form>
</template>
<script>
export default {
name: "GitHubTokenForm",
data() {
return {
githubToken: "",
};
},
beforeMount() {
this.githubToken = localStorage.getItem("github-token");
},
methods: {
saveToken() {
localStorage.setItem("github-token", this.githubToken);
},
clearToken() {
localStorage.clear();
},
},
};
</script>
<template>
<div>
<h1>Repos</h1>
<div v-for="r of repos" :key="r.id">
<h2>{{r.owner.login}}/{{r.name}}</h2>
<Issues :owner="r.owner.login" :repo="r.name" />
</div>
</div>
</template>
<script>
import Issues from "./repo/Issues.vue";
import { octokitMixin } from "../mixins/octokitMixin";
export default {
name: "Repos",
components: {
Issues,
},
data() {
return {
repos: [],
};
},
mixins: [octokitMixin],
async mounted() {
const octokit = this.createOctokitClient();
const { data: repos } = await octokit.request("/user/repos");
this.repos = repos;
},
};
</script>
<template>
<div>
<h1>User Info</h1>
<ul>
<li>
<img :src="userData.avatar_url" id="avatar" />
</li>
<li>username: {{userData.login}}</li>
<li>followers: {{userData.followers}}</li>
<li>plan: {{userData.pla && userData.plan.name}}</li>
</ul>
</div>
</template>
<script>
import { octokitMixin } from "../mixins/octokitMixin";
export default {
name: "User",
data() {
return {
userData: {},
};
},
mixins: [octokitMixin],
async mounted() {
const octokit = this.createOctokitClient();
const { data: userData } = await octokit.request("/user");
this.userData = userData;
},
methods: {
saveToken() {},
},
};
</script>
<style scoped>
#avatar {
width: 50px;
height: 50px;
}
</style>
<template>
<div v-if="issues.length > 0">
<button @click="showIssues = !showIssues">{{showIssues ? 'Hide' : 'Show'}} issues</button>
<div v-if="showIssues">
<div v-for="i of issues" :key="i.id">
<h3>{{i.title}}</h3>
<a :href="i.url">Go to issue</a>
<IssueComments :owner="owner" :repo="repo" :issueNumber="i.number" />
</div>
</div>
</div>
</template>
<script>
import { octokitMixin } from "../../mixins/octokitMixin";
import IssueComments from "./issue/Comments.vue";
export default {
name: "RepoIssues",
components: {
IssueComments,
},
props: {
owner: {
type: String,
required: true,
},
repo: {
type: String,
required: true,
},
},
mixins: [octokitMixin],
data() {
return {
issues: [],
showIssues: false,
};
},
methods: {
async getRepoIssues(owner, repo) {
if (typeof owner !== "string" || typeof repo !== "string") {
return;
}
const octokit = this.createOctokitClient();
const { data: issues } = await octokit.issues.listForRepo({
owner,
repo,
});
this.issues = issues;
},
},
watch: {
owner: {
immediate: true,
handler(val) {
this.getRepoIssues(val, this.repo);
},
},
repo: {
immediate: true,
handler(val) {
this.getRepoIssues(this.issues, val);
},
},
},
};
</script>
<template>
<div>
<div v-if="comments.length > 0">
<h4>Comments</h4>
<div v-for="c of comments" :key="c.id">{{c.user && c.user.login}} - {{c.body}}</div>
</div>
</div>
</template>
<script>
import { octokitMixin } from "../../../mixins/octokitMixin";
export default {
name: "IssueComments",
props: {
owner: {
type: String,
required: true,
},
repo: {
type: String,
required: true,
},
issueNumber: {
type: Number,
required: true,
},
},
data() {
return {
comments: [],
};
},
mixins: [octokitMixin],
methods: {
async getIssueComments(owner, repo, issueNumber) {
if (
typeof owner !== "string" ||
typeof repo !== "string" ||
typeof issueNumber !== "number"
) {
return;
}
const octokit = this.createOctokitClient();
const { data: comments } = await octokit.issues.listComments({
owner,
repo,
issue_number: issueNumber,
});
this.comments = comments;
},
},
watch: {
owner: {
immediate: true,
handler(val) {
this.getIssueComments(val, this.repo, this.issueNumber);
},
},
repo: {
immediate: true,
handler(val) {
this.getIssueComments(this.owner, val, this.issueNumber);
},
},
issueNumber: {
immediate: true,
handler(val) {
this.getIssueComments(this.owner, this.repo, val);
},
},
},
};
</script>
import { createApp } from 'vue'
import App from './App.vue'
import './registerServiceWorker'
createApp(App).mount('#app')
export const octokitMixin = {
methods: {
createOctokitClient() {
return new window.Octokit({
auth: localStorage.getItem("github-token"),
});
}
}
}
/* eslint-disable no-console */
import { register } from 'register-service-worker'
if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
ready () {
console.log(
'App is being served from cache by a service worker.\n' +
'For more details, visit https://goo.gl/AFskqB'
)
},
registered () {
console.log('Service worker has been registered.')
},
cached () {
console.log('Content has been cached for offline use.')
},
updatefound () {
console.log('New content is downloading.')
},
updated () {
console.log('New content is available; please refresh.')
},
offline () {
console.log('No internet connection found. App is running in offline mode.')
},
error (error) {
console.error('Error during service worker registration:', error)
}
})
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册