npmrun 4 years ago
parent
commit
1c61f9b244
  1. 2
      index.html
  2. 13
      src/App.vue
  3. 14
      src/api/index.js
  4. 25
      src/api/index.ts
  5. 19
      src/api/request/index.ts
  6. 10
      src/assets/script/util.ts
  7. 20
      src/assets/style/common.scss
  8. 48
      src/assets/style/reset.scss
  9. 14
      src/components/Image.vue
  10. 12
      src/main.ts
  11. 16
      src/pages/Demo/Demo.vue
  12. 8
      src/pages/Demo/Detail/Detail.vue
  13. 0
      src/pages/Demo/Detail/github-markdown.scss
  14. 12
      src/pages/Demo/Home/Home.vue
  15. 55
      src/pages/Home/Home.scss
  16. 69
      src/pages/Home/Home.vue
  17. 12
      src/plugins/directive/index.ts
  18. 49
      src/plugins/pulldown.ts
  19. 21
      src/plugins/toast.js
  20. 12
      src/plugins/version.ts
  21. 0
      src/router/index.ts
  22. 22
      src/shim.d.ts
  23. 20
      tsconfig.json
  24. 0
      vite.config.ts

2
index.html

@ -8,6 +8,6 @@
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

13
src/App.vue

@ -7,23 +7,24 @@
</router-view>
</template>
<script>
<script lang="ts">
import {computed} from 'vue'
import {computed, defineComponent} from 'vue'
import {useRoute} from 'vue-router'
export default {
export default defineComponent({
name: 'App',
setup() {
const route = useRoute()
let isAlive = computed(() => !!route.meta.alive)
let fullPath = computed(() => route.fullPath)
const { alive = false } = route.meta
let isAlive = computed<boolean>(() => !!alive)
let fullPath= computed<string>(() => route.fullPath)
return {
fullPath,
isAlive,
}
}
}
})
</script>
<style lang="scss">

14
src/api/index.js

@ -1,14 +0,0 @@
import {onMounted,ref} from "vue"
import {request_} from "./request";
const fuck = {
install(app){
app.provide("$http",fuck)
// app.config.globalProperties.$http = fuck;
},
bannerData: (data)=>request_("GET",'https://gank.io/api/v2/banners',data),
articleData: (data)=>request_("GET",'https://gank.io/api/v2/data/category/GanHuo/type/frontend/page/1/count/10',data),
articleDetail: (data)=>request_("GET",'https://gank.io/api/v2/post/'+data)
}
export default fuck

25
src/api/index.ts

@ -0,0 +1,25 @@
import {onMounted,App} from "vue"
import {request_,EType} from "./request";
type func = (app: App)=>void
type data = (data: { })=>Promise<any>
interface IApi {
install:func;
articleDetail:data;
bannerData:data;
articleData:data;
// [propsName: string]: data | func | void;
}
const fuck:IApi = {
install(app: App){
app.provide("$http",fuck)
// app.config.globalProperties.$http = fuck;
},
bannerData: (data={})=>request_(EType.GET,'https://gank.io/api/v2/banners',data),
articleData: (data={})=>request_(EType.GET,'https://gank.io/api/v2/data/category/GanHuo/type/frontend/page/1/count/10',data),
articleDetail: (data={})=>request_(EType.GET,'https://gank.io/api/v2/post/'+data)
}
export default fuck

19
src/api/request/index.js → src/api/request/index.ts

@ -1,6 +1,6 @@
import axios from "axios"
import axios,{AxiosResponse} from "axios"
const checkERR = (err, type) => {
const checkERR = (err:AxiosResponse, type:string|number) => {
console.log(err);
switch (type) {
case 0:
@ -12,9 +12,18 @@ const checkERR = (err, type) => {
}
}
export interface IData {
params?: object;
data?: object;
}
export enum EType{
GET= "GET",
POST= "POST"
}
// 静默执行
export function request_(type = 'GET', url, data = {}, ContentType="application/json") {
var __data = {}
export function request_(type:EType = EType.GET, url:string, data:IData = {}, ContentType:string="application/json") {
var __data:IData = {}
if (type.toUpperCase() == 'GET') {
__data.params = data
}
@ -25,7 +34,7 @@ export function request_(type = 'GET', url, data = {}, ContentType="application/
var reg = /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)/;
var realUrl = url;
if (!reg.test(url)) {
realUrl = config.BASEURL + url;
realUrl = ''//config.BASEURL + url;
}
axios({
url: realUrl,

10
src/assets/script/util.js → src/assets/script/util.ts

@ -1,11 +1,16 @@
import {App} from "vue";
export function useExportData() {
let result = {};
let result:any = {};
result = new Proxy(result,{
get(target, key) {
// @ts-ignore
return target[key];
},
set(target, key, value, receiver) {
// @ts-ignore
if (target[key]){
// @ts-ignore
console.warn(target.toString()+"已存在字段"+key);
}
return Reflect.set(target, key, value);
@ -13,3 +18,6 @@ export function useExportData() {
})
return result
}
useExportData.install = (app:App)=>{
app.provide("$export",useExportData);
}

20
src/assets/style/common.scss

@ -1,4 +1,10 @@
@import "./github-markdown.scss";
@import "./reset.scss";
a{
text-decoration: none;
color: inherit;
display: inline-block;
}
html,body{
margin: 0;
padding: 0;
@ -16,12 +22,24 @@ html,body{
background-color: #f5f5f5;
}
.a-wrap{
width: 1160px !important;
margin: 0 auto;
}
.a-clearfix{
@include clearfix;
}
//一行溢出
.a-ov{
@include ellipsis()
}
//两行溢出
.a-ov2{
@include ellipsis(2)
}
//图片
.a-image{
position: relative;
overflow: hidden;

48
src/assets/style/reset.scss

@ -0,0 +1,48 @@
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}

14
src/components/Image.vue

@ -5,7 +5,7 @@
</template>
<script>
import {watchEffect,ref} from "vue"
import {ref} from "vue"
export default {
props: {
@ -21,26 +21,28 @@
type: String,
default: ''
},
loading: {
type: Boolean,
default: true
},
className: {
type: String,
default: ''
}
},
setup(props) {
const {src} = props;
const {src, loading} = props;
let realSrc = ref('')
watchEffect( async () => {
let img = '/logo.png'
let img = loading ? '/logo.png' : ''
let image = new Image()
realSrc.value = img;
image.src= src;
image.src = src;
image.onload = () => {
realSrc.value = src;
}
image.onerror = () => {
realSrc.value = img;
}
})
return {
realSrc
}

12
src/main.js → src/main.ts

@ -1,7 +1,9 @@
import {createApp} from 'vue'
import {createApp, h} from 'vue'
import router from "./router/index"
// import "@/plugins/toast"
import App from './App.vue'
import api from "./api/index"
import version from "./plugins/version"
import Header from "@/components/Header.vue"
import Image from "@/components/Image.vue"
import Mobile from "@/components/Mobile.vue"
@ -9,13 +11,17 @@ import Mobile from "@/components/Mobile.vue"
const app = createApp(App);
app.use(router);
app.use(api)
app.use(version)
app.config.globalProperties.name = 'xianyu'
app.config.errorHandler=(err)=>{
console.log(err)
}
app.mount('#app')
app.component("Header",Header)
app.component("Image",Image)
app.component("Mobile",Mobile)
app.mount('#app')

16
src/pages/Demo/Demo.vue

@ -4,20 +4,20 @@
</Mobile>
</template>
<script>
import { getCurrentInstance,inject, onMounted } from "vue";
export default {
setup(props,context) {
<script lang="ts">
import {defineComponent, getCurrentInstance, inject, onMounted} from "vue";
export default defineComponent({
setup(props, context) {
console.log(context);
// context
// setup
const $http = inject('$http')
console.log($http);
const {ctx} = getCurrentInstance()
console.log(ctx);
const instance = getCurrentInstance()
onMounted(() => {
console.log("ctx", ctx.name); // xianyu
console.log("proxy", instance!.proxy!.$version);
});
},
};
})
</script>

8
src/pages/Demo/Detail/Detail.vue

@ -13,12 +13,12 @@
<script>
import {useExportData} from '@/assets/script/util.js'
import {useRoute} from "vue-router";
import {onMounted,ref,nextTick} from 'vue'
import http from '@/api/index.js'
import {onMounted, ref, nextTick, inject} from 'vue'
import markdownIt from "markdown-it"
export default {
name: "Detail",
setup(){
const http = inject('$http')
const route = useRoute()
const exportData = useExportData()
let source = ref({})
@ -29,6 +29,7 @@
let md = markdownIt();
let result = md.render(res.data.data.markdown);
res.data.data.markdown = result
await nextTick()
source.value = res.data.data
})
return exportData
@ -36,6 +37,9 @@
}
</script>
<style lang="scss">
@import "./github-markdown.scss";
</style>
<style scoped lang="scss">
.page.detail{
display: flex;

0
src/assets/style/github-markdown.scss → src/pages/Demo/Detail/github-markdown.scss

12
src/pages/Demo/Home/Home.vue

@ -48,17 +48,17 @@
</div>
</div>
</template>
<script>
<script lang="ts">
import {useRoute, useRouter} from 'vue-router'
import {nextTick, onMounted, ref} from 'vue'
import http from '@/api/index.js'
import pulldown from '@/plugins/pulldown.js'
import {useExportData} from '@/assets/script/util.js'
import http from '@/api/index.ts'
import pulldown from '@/plugins/pulldown'
import {useExportData} from '@/assets/script/util'
import Swiper from 'swiper'
import "swiper/swiper.min.css"
export default {
setup(props, context) {
setup(props:any, context:any) {
const exportData = useExportData()
const router = useRouter()
const route = useRoute()
@ -89,7 +89,7 @@
}
exportData.isRefresh = isRefresh;
exportData.isLoading = isLoading;
onMounted((done) => {
onMounted(() => {
Refreshing(false, true)
RefreshEvent((done) => {
console.log('下拉刷新')

55
src/pages/Home/Home.scss

@ -0,0 +1,55 @@
.box {
background-color: #090723;
height: 200px;
color: white;
}
header {
height: 50px;
line-height: 50px;
.logo {
float: left;
position: relative;
.logo__name {
font-weight: bold;
font-size: 23px;
}
}
.menus {
float: left;
padding-left: 20px;
font-size: 14px;
color: rgba(255, 255, 255, .5);
.menu {
float: left;
margin: 0 20px;
cursor: pointer;
position: relative;
.dropdown {
position: absolute;
top: 100%;
left: 0;
overflow: hidden;
max-height: 0;
background-color: black;
line-height: 1.2;
transition: max-height .5s linear;
}
&:hover {
color: white;
.dropdown {
max-height: none;
}
}
}
}
.operation{
float: right;
color: rgba(255, 255, 255, .5);
&:hover {
color: white;
}
}
}

69
src/pages/Home/Home.vue

@ -1,8 +1,31 @@
<template>
<Header :back="false">
彩虹Demo列表
</Header>
<div class="box">
<div class="a-wrap a-clearfix">
<header>
<div class="logo">
<div class="logo__name">电影资源网</div>
</div>
<ul class="menus">
<a href="javascript:void(0)" class="menu">
热门
<div class="dropdown">
<div class="dropdown-item">
qw
</div>
</div>
</a>
<a href="javascript:void(0)" class="menu">科幻</a>
<a href="javascript:void(0)" class="menu">动作</a>
<a href="javascript:void(0)" class="menu">爱情</a>
<a href="javascript:void(0)" class="menu">仙侠</a>
<a href="javascript:void(0)" class="menu">动漫</a>
</ul>
<a class="operation" href="javascript:void(0)">
登录/注册
</a>
</header>
</div>
</div>
<div class="rainbow-list">
<div class="rainbow-item red">
<router-link to="/demo">Demo页面</router-link>
@ -22,51 +45,59 @@
<div class="rainbow-item blue">
暂空
</div>
<div class="rainbow-item purple">
暂空
</div>
<div class="rainbow-item purple">暂空</div>
</div>
</template>
<style lang="scss" scoped>
.rainbow-list{
@import "./Home.scss";
.rainbow-list {
width: 500px;
@include media(xs) {
width: 100%;
}
margin: 0 auto;
margin-top: 20px;
.rainbow-item{
.rainbow-item {
height: 50px;
line-height: 50px;
text-align: center;
color: white;
font-size: 25px;
a{
a {
text-decoration: none;
color: inherit;
}
&.red{
&.red {
background-color: red;
}
&.orange{
&.orange {
background-color: orange;
}
&.yellow{
&.yellow {
background-color: yellow;
}
&.green{
&.green {
background-color: green;
}
&.greenyellow{
&.greenyellow {
background-color: greenyellow;
}
&.blue{
&.blue {
background-color: blue;
}
&.purple{
&.purple {
background-color: purple;
}
}
}
}
</style>

12
src/plugins/directive/index.ts

@ -0,0 +1,12 @@
import {App} from "vue";
export default {
install(app: App) {
app.directive('focus', {
mounted(el) {
el.focus()
}
})
}
}

49
src/plugins/pulldown.js → src/plugins/pulldown.ts

@ -1,15 +1,15 @@
import {onMounted, ref} from "vue";
export function OnRefresh(hookEvent) {
export function OnRefresh(hookEvent:()=>{}) {
}
export function OnLoadMore(hookEvent) {
export function OnLoadMore(hookEvent:()=>{}) {
}
export default function (el) {
let exportData = {}
export default function (el:string) {
let exportData:any = {}
let ELoading = {
NORMAL: 0,
LOADING: 1,
@ -26,19 +26,19 @@ export default function (el) {
exportData.isRefresh = isRefresh;
exportData.isLoading = isLoading;
let refreshArray = [];
exportData.RefreshEvent = (hook) => {
let refreshArray:((done:Function)=>{})[] = [];
exportData.RefreshEvent = (hook:()=>{}) => {
refreshArray.push(hook)
}
let loadMoreArray = [];
exportData.LoadMoreEvent = (hook) => {
let loadMoreArray:((done:Function)=>{})[] = [];
exportData.LoadMoreEvent = (hook:()=>{}) => {
loadMoreArray.push(hook)
}
let list = null
let list:HTMLElement|null = null
function Refreshing(needAnim) {
function Refreshing(needAnim?:boolean) {
if (!list) {
return
}
@ -50,6 +50,9 @@ export default function (el) {
let done = ()=>{
isRefresh.value = ERefresh.END
setTimeout(() => {
if (!list) {
return
}
list.style.transform = `translateY(${0}px)`;
setTimeout(() => {
isRefresh.value = ERefresh.NORMAL
@ -68,7 +71,7 @@ export default function (el) {
loadMoreArray.forEach(v => v(done))
}
exportData.Refreshing = (type, needAnim) => {
exportData.Refreshing = (type:string, needAnim:boolean) => {
setTimeout(() => {
if (type == undefined) {
Refreshing()
@ -77,7 +80,7 @@ export default function (el) {
Refreshing(needAnim)
}
if (!type) {
LoadMoreing(needAnim)
LoadMoreing()
}
},0)
}
@ -90,14 +93,14 @@ export default function (el) {
let zu = .2
let pageHeight = window.innerHeight; // 屏幕高度
let moreHeight = 50;
let parentNode = list.parentNode
let parentNode = list!.parentNode
let recordPoint = true // 是否可以记录起始点(下拉加载用)
let canRefresh = true // 是否可以刷新(下拉加载用)
let canLoading = true //
let lastScrollTop = 0
parentNode.addEventListener("scroll", (e) => {
let listHeight = list.offsetHeight; // 列表高度
let top = parentNode.scrollTop;
parentNode!.addEventListener("scroll", (e) => {
let listHeight = list!.offsetHeight; // 列表高度
let top = (<HTMLElement>parentNode)!.scrollTop;
if (top <= 50) {
//下拉刷新
canRefresh = true
@ -110,10 +113,10 @@ export default function (el) {
}
lastScrollTop = top
})
list.addEventListener("touchstart", (e) => {
list!.addEventListener("touchstart", (e) => {
isMove = true
})
list.addEventListener("touchmove", (e) => {
list!.addEventListener("touchmove", (e) => {
if (!isMove || !canRefresh ||
(isRefresh.value != ERefresh.NORMAL
&& isRefresh.value != ERefresh.PRELOADING
@ -128,8 +131,8 @@ export default function (el) {
}
let y = (touch.clientY - startY) * zu;
if (y > 0) {
list.style.transform = `translateY(${y}px)`
list.style.transition = ''
list!.style.transform = `translateY(${y}px)`
list!.style.transition = ''
if (y > 70) {
isRefresh.value = ERefresh.PRELOADING
} else {
@ -138,18 +141,18 @@ export default function (el) {
}
})
list.addEventListener("touchend", (e) => {
list!.addEventListener("touchend", (e) => {
isMove = false
recordPoint = true
if (isRefresh.value == ERefresh.LOADING) {
return
}
list.style.transition = `transform .4s ease`;
list!.style.transition = `transform .4s ease`;
if (isRefresh.value == ERefresh.PRELOADING) {
Refreshing()
} else {
isRefresh.value = ERefresh.NORMAL
list.style.transform = `translateY(${0})`;
list!.style.transform = `translateY(${0})`;
}
})

21
src/plugins/toast.js

@ -0,0 +1,21 @@
import {createApp, h ,onMounted} from "vue";
let toast = document.createElement("div")
toast.id = "toast";
document.body.appendChild(toast);
const toastData = createApp({
setup(){
return ()=> h("div",{
onClick: ($event)=>{
console.log(toastData)
},
style: {
color: 'red'
},
on:{
}
},"sadsa")
}
}).mount('#toast');

12
src/plugins/version.ts

@ -0,0 +1,12 @@
import { App } from "vue"
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$version: string
}
}
export default {
install(app: App) {
app.config.globalProperties.$version = 'xianyu'
}
}

0
src/router/index.js → src/router/index.ts

22
src/shim.d.ts

@ -0,0 +1,22 @@
// 文件路径 shims-vue.d.ts
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
// 对vue进行类型补充说明
// declare module '@vue/runtime-core' {
// interface ComponentCustomProperties {
// name: string
// }
// }
//
// declare module 'vue/types/vue' {
// interface Vue {
// $globalData: any;
// }
// interface ComponentInternalInstance {
// proxy: any
// }
// }

20
tsconfig.json

@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom", "node"],
"types": ["vite/client"],
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "vite.config.ts"],
"exclude": ["node_modules"]
}

0
vite.config.js → vite.config.ts

Loading…
Cancel
Save