基于vue3.0简单的页面使用

news2024/11/25 7:15:04

基于vue3.0简单的页面使用

    • 项目效果图
    • 项目文件图
    • package.json
    • main.js
    • App.vue
    • views/Tutorial.vue
    • views/TS.vue
    • views/Docs.vue
    • views/Community.vue
    • views/Blog.vue
    • views/About.vue
    • utils/create.jsx
    • utils/defineCom.js
    • utils/DragIcon.js
    • utils/someName.ts
    • utils/TS.ts
    • stores/client.js
    • stores/message.js
    • router/index.js
    • components/createHtml.vue
    • components/footer.vue
    • components/header.vue
    • components/test.vue
    • assets/base.css
    • assets/main.scss
    • assets/styles.scss

项目效果图

在这里插入图片描述

项目文件图

在这里插入图片描述

package.json

{
	"name": "ping-vue",
	"version": "0.0.0",
	"private": true,
	"scripts": {
		"dev": "vite",
		"build": "vite build",
		"preview": "vite preview",
		"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore",
		"format": "prettier --write src/"
	},
	"dependencies": {
		"miao-drag": "^1.0.0",
		"pinia": "^2.0.35",
		"vue": "^3.2.47",
		"vue-router": "^4.1.6"
	},
	"devDependencies": {
		"@rushstack/eslint-patch": "^1.2.0",
		"@vitejs/plugin-vue": "^4.0.0",
		"@vitejs/plugin-vue-jsx": "^3.0.0",
		"@vue/eslint-config-prettier": "^7.1.0",
		"eslint": "^8.34.0",
		"eslint-plugin-vue": "^9.9.0",
		"prettier": "^2.8.4",
		"sass": "^1.62.0",
		"vite": "^4.1.4"
	}
}

main.js

import {
	createApp
} from 'vue'
import {
	createPinia
} from 'pinia'
import App from './App.vue'

import router from './router'

import '@/assets/main.scss'

const pinia = createPinia();
const app = createApp(App);


app.config.globalProperties.isRouterAlive = true;


app.use(router);
app.use(pinia);

app.mount('#app')

App.vue

<template>
	<RouterView v-if="isRouterAlive" />
</template>

<script setup>
	import {
		ref,
		watch,
		getCurrentInstance,
		nextTick
	} from 'vue';

	import {
		RouterView,
		useRoute
	} from 'vue-router';
	const {
		appContext
	} = getCurrentInstance();

	/**
	 * 监听路由是否变化
	 * **/
	const route = useRoute();
	watch(route, (params) => {
		
	}, {
		deep: true,
		immediate: true
	})

	const isRouterAlive = ref(true);
	appContext.config.reload = () => {
		console.log("[萍萍]")
		isRouterAlive.value = false;
		nextTick(() => {
			isRouterAlive.value = true;
		})
	}
	watch(isRouterAlive, (value) => {
		console.log("[监听变化]", value)
	})

	watch(() => appContext.config.globalProperties.isRouterAlive, (value) => {
		console.log("[振-萍]", value)
	}, {
		deep: true,
		immediate: true
	})
</script>

<style lang="scss">
</style>

views/Tutorial.vue

<template>
	<div class="ping-wrap">
		<!-- header -->
		<headerComponent></headerComponent>
		<!-- container -->
		<div class="ping-container">
			手机号:{{ clientStore.phone }}
			<button @click="plusSalaryHandle">年龄{{ clientStore.age }}</button>
			总工资:{{ totalSal }}元
			<button @click="resetHandle">reset</button>
		</div>
		<!-- footer -->
		<footerComponent></footerComponent>
	</div>
</template>

<script setup>
	import headerComponent from '@/components/header.vue'
	import footerComponent from '@/components/footer.vue'
	import {
		useClientStore
	} from '@/stores/client'
	import {
		computed,
		ref,
		watch
	} from 'vue'

	const clientStore = useClientStore()
	console.log('[clientStore]', clientStore)
	const totalSal = ref(0)

	watch(
		() => clientStore.totalSalary,
		(value) => {
			totalSal.value = value
		}, {
			deep: true,
			immediate: true
		}
	)
	totalSal.value = computed(() => clientStore.totalSalary)

	function plusSalaryHandle() {
		console.log('[新增]')
		clientStore.$patch({
			age: 45,
			phone: '15262680856'
		})
	}

	function resetHandle() {
		clientStore.$reset()
	}
</script>

<style lang="scss" scoped>
</style>

views/TS.vue

<template>
	<div class="ping-wrap">
		<!-- header -->
		<headerComponent></headerComponent>
		<!-- container -->
		<div class="ping-container">
			<p v-my-directive:premi="['miao', 'zhen']">{{ name }}</p>
			<createH name="清太祖" :params="tempList"></createH>

			<p v-stname:pers="['ping']">你应该看到我</p>
			<p v-stname:pers="['ze']">你不应该看到我</p>
		</div>
		<!-- footer -->
		<footerComponent></footerComponent>
	</div>
</template>
<script setup>
	import headerComponent from '@/components/header.vue'
	import footerComponent from '@/components/footer.vue'
	import '@/utils/TS.ts'
	import createH from '@/utils/create.jsx'
	import {
		ref
	} from 'vue'

	const name = ref('ping')

	const tempList = [{
			name: '宋太宗',
			age: 29,
			address: '北京市海淀区'
		},
		{
			name: '汉武帝',
			age: 32,
			address: '上海市浦东新区'
		},
		{
			name: '唐太宗',
			age: 27,
			address: '河南省郑州市'
		},
		{
			name: '秦始皇',
			age: 270,
			address: '河南省郑州市'
		},
		{
			name: '',
			age: 450,
			address: '西安市'
		}
	]

	class Miao {
		constructor(firstName, lastName) {
			this._firstName = firstName
			this._lastName = lastName
		}
		get firstName() {
			return this._firstName
		}
		set firstName(value) {
			this._firstName = value
		}
		get lastName() {
			return this._lastName
		}
		set lastName(value) {
			this._lastName = value
		}
		draw() {
			return this._firstName + ' ' + this._lastName
		}
	}
	const miao = new Miao('Miao', 'zhenzhen')
	const fullName = miao.draw()
	console.log(fullName)

	const vMyDirective = (el, binding) => {
		console.log(el)
		console.log(binding)
	}

	const vStname = (el, binding) => {
		if (binding.value.includes('ze')) {
			el.parentNode.removeChild(el)
		}
	}
</script>

<style scoped lang="scss">
</style>

views/Docs.vue

<template>
	<div class="ping-wrap">
		<!-- header -->
		<headerComponent></headerComponent>
		<!-- container -->
		<div class="ping-container">
			<div id="reload">刷新页面</div>
			<div id="btn">按钮</div>

			<input v-model="tempList.name" />
			<input v-model="tempList.age" />
			<input v-model="tempList.wife" />
			<p>单价:</p>
			<input v-model="price" />
			<p>数量:</p>
			<input v-model="count" />
			<p>总价:</p>
			{{ total }}

			x:{{ coordinate.x }}-y:{{ coordinate.y }}
		</div>
		<!-- footer -->
		<footerComponent ref="footerRef">
			<template v-slot:left>
				<div>
					<p>朱元璋</p>
					<p>马皇后</p>
				</div>
			</template>
			<template #center> 2023 </template>
			<template #right>
				<div>
					<p>杨坚</p>
					<p>独孤皇后</p>
				</div>
			</template>
		</footerComponent>
	</div>
</template>

<script setup>
	import {
		onBeforeMount,
		onMounted,
		onBeforeUnmount,
		onUnmounted,
		ref,
		reactive,
		watch,
		watchEffect,
		computed,
		getCurrentInstance
	} from 'vue'
	import headerComponent from '@/components/header.vue'
	import footerComponent from '@/components/footer.vue'

	const footerRef = ref(null)

	const tempList = reactive({
		name: '杨坚',
		age: 29,
		wife: '独孤皇后'
	})

	const coordinate = reactive({
		x: 0,
		y: 0
	})

	watch(
		tempList,
		(value) => {
			console.log('[监听1]', value)
		}, {
			deep: true
		}
	)
	watch(
		() => tempList.age,
		(value) => {
			console.log('[监听]', value)
		}
	)

	watchEffect(() => {
		console.log('[]', tempList.name)
		console.log('[]', tempList.age)
		console.log('[你执行了我]')
	})

	const price = ref(100)
	const count = ref(1)
	watch(count, (newCount, oldCount) => {
		console.log('[数量]', newCount, oldCount)
	})
	const total = computed(() => {
		return price.value * count.value
	})

	onBeforeMount(() => {
		console.log('[onBeforeMount]')
	})
	onMounted(() => {
		console.log('[onMounted]', tempList.name)
		document.querySelector('#btn').addEventListener('click', handleClick)
		document.querySelector('#btn').style.color = 'red'

		document.querySelector("#reload").addEventListener("click", handleReload)
	})

	window.addEventListener('mousemove', (e) => {
		coordinate.x = e.clientX
		coordinate.y = e.clientY
	})

	onBeforeUnmount(() => {
		console.log('[onBeforeUnmount]')
	})
	onUnmounted(() => {
		console.log('[onUnmounted]')
	})

	const {
		appContext
	} = getCurrentInstance()

	function handleClick() {
		footerRef.value.init()
		console.log('[footer]', footerRef.value.publice)
	}

	function handleReload() {
		appContext.config.reload()
	}
	//vue3.0中的自定义指令
	const vMyDirective = (el, binding) => {
		console.log(el)
		console.log(binding)
	}
</script>

<style lang="scss" scoped>
</style>

views/Community.vue

<template>
  <div class="ping-wrap">
    <!-- header -->
    <headerComponent></headerComponent>
    <!-- container -->
    <div class="ping-container">
      <test message="你是好人"></test>
      <clientComponent></clientComponent>
    </div>
    <!-- footer -->
    <footerComponent></footerComponent>
  </div>
</template>

<script setup>
import clientComponent from '@/utils/defineCom'
import headerComponent from '@/components/header.vue'
import footerComponent from '@/components/footer.vue'
import test from '@/components/test.vue'
import { reactive } from 'vue'
const dataList = reactive([
  {
    name: '周武王',
    id: 1
  },
  {
    name: '汉光帝',
    id: 2
  },
  {
    name: '乾隆皇帝',
    id: 3
  }
])
console.log('[]', dataList)
const tempList = dataList.map((item) => {
  return item.id + 1
})
console.log(tempList)
</script>

<style lang="scss" scoped>
</style>

views/Blog.vue

<template>
	<div class="ping-wrap">
		<!-- header -->
		<headerComponent></headerComponent>
		<!-- container -->
		<div class="ping-container">

			<p>标题:{{messageStore.title}}</p>
			<p>内容:{{messageStore.content}}</p>
			<p>总数量:{{messageStore.totalCount}}</p>
			<button @click="changeCountHandle">改变数量</button>
		</div>
		<!-- footer -->
		<footerComponent></footerComponent>
	</div>
</template>

<script setup>
	import headerComponent from "@/components/header.vue"
	import footerComponent from "@/components/footer.vue"
	import {
		useMessageStore
	} from "@/stores/message.js";

	const messageStore = useMessageStore();
	console.log("[messageStore]", messageStore);

	function changeCountHandle() {
		console.log("[改变]")
		messageStore.setCount(12)
	}
</script>

<style lang="scss" scoped>
</style>

views/About.vue

<template>
  <div class="ping-wrap">
    <!-- header -->
    <headerComponent></headerComponent>
    <!-- container -->
    <div class="ping-container">关于我们{{ count }}</div>
    <!-- footer -->
    <footerComponent></footerComponent>
  </div>
</template>

<script setup>
import headerComponent from '@/components/header.vue'
import footerComponent from '@/components/footer.vue'
import { ref, onMounted, onUnmounted, watch } from 'vue'
const count = ref(0)
const timerHandle = ref(null)
timerHandle.value = setInterval(() => {
  count.value += 1
  console.log('[计时器]', count.value)
}, 1000)

watch(count, (newVal, oldVal) => {
  console.log('[watch]', newVal, oldVal)
})

onMounted(() => {
  console.log('[onMounted]')
})
onUnmounted(() => {
  console.log('[onUnmounted]')
  clearInterval(timerHandle.value)
})
</script>

<style lang="scss" scoped>
</style>

utils/create.jsx

import { defineComponent } from 'vue'
import '@/assets/main.scss'

const defaultStyles = {
  border: '1px solid #eee',
  borderRadius: '5px',
  padding: '10px 15px',
  margin: '10px 0'
}

export default defineComponent({
  props: {
    name: {
      type: String,
      default: 'hello world'
    },
    params: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      count: 0,
      styles: {
        border: '1px solid #eee',
        borderRadius: '5px',
        padding: '10px 15px',
        margin: '10px 0'
      }
    }
  },
  render(props) {
    return (
      <>
        <div style={this.styles}>
          <h1>当前计数:{this.count}</h1>
          <p style={{ color: 'red' }}>姓名:{props.name}</p>
          <button onClick={() => this.count++}>增加</button>
        </div>
        <div style={defaultStyles}>
          <div className="row">
            <div className="col-6">col-6</div>
            <div className="col-6">col-6</div>
          </div>
          {props.params.map((item, index) => {
            if (item.age > 30) {
              return (
                <ul className="ul-block ul-block-current" key={index}>
                  <li>{index + 1}</li>
                  <li>{item.name ? '真实姓名' : '你个骗子'}</li>
                  <li>{item.age}</li>
                  <li>{item.address}</li>
                </ul>
              )
            } else {
              return (
                <ul className="ul-block" key={index}>
                  <li>{index + 1}</li>
                  <li>{item.name ? '真实姓名' : '你个骗子'}</li>
                  <li>{item.age}</li>
                  <li>{item.address}</li>
                </ul>
              )
            }
          })}
        </div>
      </>
    )
  }
})

utils/defineCom.js

import {
	h,
	defineComponent
} from "vue";

const clientComponent = defineComponent({
	name: "clientComponent",
	props: {

	},
	setup() {
		console.log("[我是组件-defineComponent]")
	},
	render() {
		return h('div', '我是组件')
	}
})

export default clientComponent;

utils/DragIcon.js

"use strict"
/**
 * 可拖拽悬浮框
 * 
 * el:被拖拽的元素,如:#dragIcon|.dragIcon
 * 
 * top:初始化悬浮框距离窗口顶部的距离,如100px|10%
 * 
 * left:初始化悬浮框距离窗口左边的距离,如100px|10%
 * 
 * onClick:悬浮框点击触发事件
 **/
class DragIcon {
	static DEFINED_CONFIG = {
		el: '#dragIcon',
		top: '100px',
		left: '100px',
		onClick: () => {

		}
	}

	constructor(options) {
		console.log("[]", options)
		if (Object.prototype.toString.call(options) !== '[object Object]') {
			throw "配置项必须为对象,你传递的是" + Object.prototype.toString.call(options);
		}
		this.config = Object.assign({}, DragIcon.DEFINED_CONFIG, options);
		this.dragElement = document.querySelector(this.config.el);
		this.clientWidth = document.documentElement.clientWidth || window.innerWidth;
		this.clientHeight = document.documentElement.clientHeight || window.innerHeight;
		this.create();
		this.drag();

		this.isDragging = false; // 初始化时未拖拽
	}
	/**
	 * 初始化悬浮框
	 **/
	create() {
		const {
			top,
			left
		} = this.config;
		this.dragElement.style.top = `${top}`;
		this.dragElement.style.left = `${left}`;
	}
	/**
	 * 悬浮框拖拽事件
	 **/
	drag() {
		this.dragElement.addEventListener("mousedown", (e) => {
			e.preventDefault();
			this.isDragging = true; // 拖拽开始
			const rect = this.dragElement.getBoundingClientRect();
			const disX = e.clientX - rect.left;
			const disY = e.clientY - rect.top;

			const onMouseMove = (e) => {
				let moveX = e.clientX - disX;
				let moveY = e.clientY - disY;
				moveX = Math.min(moveX, this.clientWidth - rect.width);
				moveY = Math.min(moveY, this.clientHeight - rect.height);

				moveX = Math.max(0, moveX);
				moveY = Math.max(0, moveY)

				this.dragElement.style.left = `${moveX}px`;
				this.dragElement.style.top = `${moveY}px`;
				this.isDragging = false; // 拖拽结束
			}

			const onMouseUp = () => {
				window.removeEventListener("mousemove", onMouseMove);
				window.removeEventListener("mouseup", onMouseUp);
				this.onClick();
			}

			window.addEventListener("mousemove", onMouseMove);
			window.addEventListener("mouseup", onMouseUp);

		});


	}
	/**
	 * 悬浮框点击事件
	 **/
	onClick() {
		if (this.isDragging) {
			this.config.onClick();
			this.isDragging = false; // 拖拽结束
		}
	}
}


export default DragIcon;

utils/someName.ts

namespace MiaoName {
    export interface person {
        name: string;
        age: number;
    }

    export interface student extends person {
        school: string;
    }


    class Miao implements student {
        name: string;
        age: number;
        school: string;
        constructor(name: string, age: number) {
            this.name = name;
            this.age = age
        }
    }
}

utils/TS.ts

class People {
    /**
     * public:公共访问修饰符,可以在类内或者类外使用public修饰的属性或者行为,默认修饰符。
     * private:私有访问修饰符,只能在类内使用private修饰的属性或者行为。
     * protected:受保护的访问修饰符,可以本类和子类中使用protected修饰的属性和行为。
     * **/
    public _firstName: string;//公共属性
    public _lastName: string;//公共属性
    private _age: number;//私有属性
    protected _phone: number;//受保护的属性
    //公共属性与静态属性的区别
    //公共属性:每次实例化都会生成一个新的属性
    //静态属性:每次实例化都会共用一个属性
    static _site: string = "www.baidu.com";//静态属性
    _website: string = "www.baidu.com";//公共属性
    //什么是静态成员?
    //静态成员是指在类中通过static修饰的属性或者方法,静态成员只能通过类名.的方式调用。
    //静态成员可以被继承吗?
    //可以
    //静态成员可以被子类重写吗?
    //不可以
    //静态成员可以被实例化调用吗?
    //不可以
    //静态成员可以被实例化修改吗?
    //不可以
    //静态成员可以被实例化删除吗?
    //不可以
    //静态成员可以被实例化添加吗?
    //不可以
    //静态成员可以被实例化访问吗?
    //不可以
    //静态成员可以被实例化继承吗?
    //不可以
    //静态成员可以被实例化重写吗?
    //不可以
    //静态成员可以被实例化调用吗?
    //不可以

    //什么是实例成员?
    //实例成员是指在类中通过this.的方式定义的属性或者方法,实例成员只能通过实例化对象.的方式调用。
    //实例成员可以被继承吗?
    //可以
    //实例成员可以被子类重写吗?
    //可以
    //实例成员可以被实例化调用吗?
    //可以
    //实例成员可以被实例化修改吗?
    //可以
    //实例成员可以被实例化删除吗?
    //可以
    //实例成员可以被实例化添加吗?
    //可以
    //实例成员可以被实例化访问吗?
    //可以
    //实例成员可以被实例化继承吗?
    //可以
    //实例成员可以被实例化重写吗?
    //可以
    //实例成员可以被实例化调用吗?
    //可以

    //实例员工分为哪几种?
    //公共实例成员:公共实例成员是指在类中通过public修饰的属性或者方法,公共实例成员可以在本类、子类和实例化对象中使用。
    //私有实例成员:私有实例成员是指在类中通过private修饰的属性或者方法,私有实例成员只能在本类中使用。
    //私有实例成员:私有实例成员是指在类中通过private修饰的属性或者方法,私有实例成员只能在本类中使用。可以被实例化调用吗?
    //不可以
    //受保护的实例成员:受保护的实例成员是指在类中通过protected修饰的属性或者方法,受保护的实例成员只能在本类和子类中使用。
    //受保护的实例成员:受保护的实例成员是指在类中通过protected修饰的属性或者方法,受保护的实例成员只能在本类和子类中使用。可以被实例化调用吗?
    //不可以
    //静态实例成员:静态实例成员是指在类中通过static修饰的属性或者方法,静态实例成员只能通过类名.的方式调用。

    constructor(firstName: string, lastName: string, age: number, phone: number) {
        console.log("构造函数");
        this._firstName = firstName;
        this._lastName = lastName;
        this._age = age;
        this._phone = phone;
        this.showAge();
        console.log("[static]", People._site);
        console.log("[public]", this._website);
    }
    /**
     * void:用于标识方法返回值的类型,表示该方法没有返回值。
     * **/
    init(): void {
        console.log("init");
        console.log("[public]", this._firstName);
        console.log("[public]", this._lastName);
        console.log("[private]", this._age);
        console.log("[protected]", this._phone);

        const price: number = 103;
        const num: number = 2.456;
        const total: number = price * num;
        console.log("[number]", total);



        interface person {
            name: string,
            age: number,
            phone?: number,
            family?: family[]
        }
        interface family {
            name: string,
            age: number,
            phone: number
        }
        let dataList: person[] = [];
        dataList.push({ name: "张三", age: 18, phone: 123456789 });
        dataList.push({ name: "张三", age: 18, phone: 123456789, family: [{ name: "张三", age: 18, phone: 123456789 }] });
        console.log("[interface]", dataList);
        dataList[0].age = 19;
        console.log("[interface]", dataList);

        dataList.forEach((item: person, index: number) => {
            console.log("[interface]", item, index);
        })
    }

    get firstName(): string {
        return this._firstName;
    }
    set firstName(value: string) {
        this._firstName = value;
    }

    showFullName(): string {
        console.log("[姓名:]", this._firstName + "" + this._lastName);
        return this._firstName + "" + this._lastName;
    }
    private showAge(): number {
        console.log("[年龄:]", this._age);
        return this._age;
    }
    protected showPhone() {
        console.log("[手机号:]", this._phone);
    }

}
const site = new People("张", "三", 18, 123456789);
console.log(site.firstName);
site.firstName = "李";
console.log(site.firstName);
site.showFullName();
site.init();
console.log("[People]", People._site);

/**
 * 子类继承父类
 * **/
class Woman extends People {
    constructor(firstName: string, lastName: string, age: number, phone: number) {
        super(firstName, lastName, age, phone);
        console.log("子类构造函数");
        console.log("[Woman]", Woman._site);
    }
    show() {
        console.log("子类", this._phone);
    }
}
const woman = new Woman("李", "四", 19, 123456789);

woman.show();
//子类可以使用父类的静态属性吗?
//可以
//子类可以使用父类的公共属性吗?
//可以
//子类可以使用父类的私有属性吗?
//不可以
//子类可以使用父类的受保护的属性吗?
//可以

console.log("[Woman]", Woman._site)
//循环数据时,使用forEach,for,find,还是map
//forEach:只能遍历数组,不能return,不能返回一个新的数组
//for:可以遍历数组,可以return,返回一个新的数组
//map:可以遍历数组,可以return,返回一个新的数组
//find:可以遍历数组,可以return,只返回第一个符合条件的数据

const dataList: any[] = [{
    name: "张三",
    age: 18,
    phone: 123456789
}, {
    name: "张四",
    age: 19,
    phone: 123456789
}, {
    name: "张五",
    age: 20,
    phone: 123456789
}, {
    name: "张六",
    age: 21,
    phone: 123456789
}, {
    name: "张七",
    age: 22,
    phone: 123456789
}, {
    name: "张八",
    age: 23,
    phone: 123456789
}]

dataList.map((item: any, index: number) => {
    item['id'] = index
    return item;
})
console.log("[map]", dataList);

dataList.find((item: any, index: number) => {
    item['code'] = index;
    return item
})
console.log("[find]", dataList);

dataList.forEach((item: any, index: number) => {
    item['code'] = index;
})
console.log("[forEach]", dataList);

const str: string = "MiaoZhenZhen";
console.log("[slice]", str.slice(2, 3));
console.log("[substr]", str.substr(2, 3));
console.log("[substring]", str.substring(2, 3));
const count = new Number(123);
console.log("[toString]", count);
console.log("[valueOf]", count.valueOf());
//slice:截取字符串,返回一个新的字符串,不会改变原来的字符串
//substr:截取字符串,返回一个新的字符串,不会改变原来的字符串
//substring:截取字符串,返回一个新的字符串,不会改变原来的字符串
//slice与substring的区别:slice可以接受负数,substring不可以接受负数
//slice与substr的区别:slice第二个参数是截取的长度,substr第二个参数是截取的结束位置

const temp = [{
    name: "张三1",

}, {
    name: "张三2",
}]
console.log("[temp]", temp);
temp.push({
    name: "张三3",

})
console.log("[temp]", temp);
//为什么两次console。log(temp)值一样
//因为temp是一个引用类型,指向的是同一个内存地址,所以改变temp的值,会改变内存地址的值,所以两次打印的值一样
//如何解决两次值一样的问题?
//使用深拷贝,浅拷贝
//深拷贝:拷贝的是值,不是内存地址
//浅拷贝:拷贝的是内存地址,不是值
//如何实现深拷贝?
//JSON.parse(JSON.stringify(temp))
//如何实现浅拷贝?
//Object.assign({},temp)
const tempStr = JSON.parse(JSON.stringify(temp));
console.log("[JSON.parse(JSON.stringify(temp))]", tempStr);
tempStr.push({
    name: "张三4",
})
console.log("[JSON.parse(JSON.stringify(temp))]", tempStr);
//使用JSON.parse(JSON.stringify(temp))实现深拷贝,但是有一个问题,如果temp中有函数,会怎么样?
//函数会被忽略掉
//使用Object.assign({},temp)实现浅拷贝,但是有一个问题,如果temp中有函数,会怎么样?
//函数会被忽略掉
//使用JSON.parse(JSON.stringify(temp))处理过的数据,需要重新赋值新变量吗?
//需要
//为什么不能继续使用temp变量
//因为temp变量已经被重新赋值了
//如果继续使用temp变量,会怎么样?
//会报错,因为temp变量已经被重新赋值了
//在js中,每创建一个变量,都会在内存中开辟一个空间,存储这个变量的值,
//如果这个变量的值是一个引用类型,那么这个变量存储的是一个内存地址,这个内存地址指向的是引用类型的值,
//如果这个变量的值是一个基本类型,那么这个变量存储的是一个基本类型的值,
//什么是基本类型?什么是引用类型?
//基本类型:string,number,boolean,null,undefined,symbol
//引用类型:object,array,function
//如何判断一个变量是基本类型还是引用类型?
//typeof

const tempArr: any[] = ["miao", "zhen", "zhen", 1, 3, 5, 6, 8];
console.log("[tempArr]", tempArr.join(","));
console.log("[tempArr]", tempArr.toString());//join(",")与toString()的区别?

//元组和数组的区别?
//元组:可以存储不同类型的数据
//数组:只能存储相同类型的数据
//元组和数组的相同点?
//都可以存储多个数据
//如何定义元组?
const tempTuple: [string, number, boolean] = ["miao", 1, true]
tempTuple.push("zhen")
console.log("[tempTuple]", tempTuple);
//如何定义数组?
//const tempArr:any[] = ["miao",1,true]
//如何获取元组中的数据?
//tempTuple[0]
//如何获取数组中的数据?
//tempArr[0]
//如何修改元组中的数据?
//tempTuple[0] = "zhen"
//如何修改数组中的数据?
//tempArr[0] = "zhen"


const tempMap = new Map();
tempMap.set("name", "miao");
tempMap.set("age", 18);
console.log("[tempMap]", tempMap);

console.log("[Map-1]", Map)
console.log("[Map-tempMap-2]", tempMap)
//Map有原型吗?
//有
//Map的原型是什么?
//Map.prototype
//Map的原型是谁?
//Map.prototype.constructor



///<reference path="./test.ts" />
console.log(Object.prototype)
const obj: { name: string, age: number, school: string } = {
    name: "miao",
    age: 18,
    school: '北京大学'
};
const obj1: MiaoName.student = {
    name: "miao",
    age: 18,
    school: '北京大学'
};
console.log("[obj]", obj);

//如何引入其他文件的内容?
console.log("[MiaoName.temp]",)
const p: MiaoName.person[] = [{
    name: "miao",
    age: 18
}]
const p1: MiaoName.student[] = [{
    name: "miao",
    age: 18,
    school: '北京大学'
}]
console.log("[MiaoName.temp]", p)
console.log("[MiaoName.temp]", p1)


function test(): MiaoName.person[] {
    return [{
        name: "miao",
        age: 18
    }]
}

console.log("[MiaoName.temp]", test.prototype.constructor())

class Person {
    name: string;
    age: number;
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age
    }
    say() {
        console.log("[say]", "hello")
    }
}

stores/client.js

import {
	defineStore
} from "pinia";

export const useClientStore = defineStore("client", {
	state: () => {
		return {
			name: '忽必烈',
			age: 29,
			salary: 10,
			phone: '18895350000'
		}
	},
	getters: {
		totalSalary: (state) => {
			console.log("[state]", state)
			return state.age * state.salary
		}
	},
	actions: {
		setAge(params) {
			console.log("[params]", params)
			this.age = params;
		}
	}
})

stores/message.js

import {
	defineStore
} from "pinia";
import {
	computed,
	ref
} from "vue";

export const useMessageStore = defineStore("message", () => {
	const title = ref("标题");
	const content = ref("内容");
	const count = ref(0);

	const totalCount = computed(() => {
		return count.value * 12
	})

	function setCount(params) {
		console.log("[]", params)
		count.value = params
	}
	

	return {
		title,
		content,
		totalCount,
		setCount
	}
})

router/index.js

import {
	createRouter,
	createWebHistory
} from 'vue-router'

const router = createRouter({
	history: createWebHistory(import.meta.env.BASE_URL),
	routes: [{
			path: '',
			redirect: '/docs',
		}, {
			path: '/docs',
			name: 'Docs',
			meta: {
				title: '文档'
			},
			component: () => import('@/views/Docs.vue')
		},
		{
			path: '/tutorial',
			name: 'Tutorial',
			meta: {
				title: '教程'
			},
			component: () => import('@/views/Tutorial.vue')
		},
		{
			path: '/blog',
			name: 'Blog',
			meta: {
				title: '博客'
			},
			component: () => import('@/views/Blog.vue')
		},
		{
			path: '/community',
			name: 'Community',
			meta: {
				title: '社区'
			},
			component: () => import('@/views/Community.vue')
		},
		{
			path: '/about',
			name: 'About',
			meta: {
				title: '关于'
			},
			component: () => import('@/views/About.vue')
		},
		{
			path: '/ts',
			name: 'Ts',
			meta: {
				title: 'TypeScript 教程'
			},
			component: () => import('@/views/TS.vue')
		}
	],
	scrollBehavior: () => {

		return {
			top: 0
		}
	}
})

import {
	useClientStore
} from '@/stores/client'
router.beforeEach((to, from, next) => {
	console.log("[to]", to)
	const store = useClientStore();
	console.log("[store]", store)
	next();
})

export default router

components/createHtml.vue

<script>
import { defineComponent } from 'vue';

export default defineComponent({
  data() {
    return {
      count: 0,
    };
  },
  render() {
    return (
      <div>
        <h1>当前计数:{this.count}</h1>
        <button onClick={() => this.count++}>增加</button>
      </div>
    );
  },
});
</script>

components/footer.vue

<template>
	<div class="footer-wrap">
		<slot name="left" v-if="!isShow"></slot>
		<p>Copyright © <slot name="center"></slot> Meta Platforms, Inc.</p>
		<slot name="right" v-if="isShow"></slot>
	</div>
</template>

<script setup>
	import {
		ref,
		watch
	} from 'vue';
	const publice = ref('123');
	const isShow = ref(true)

	function init() {
		console.log("[我是footer]")
		publice.value = '456';
	}
	watch(publice, (value) => {
		console.log("[我改变了]", value, publice.value)
		isShow.value = false;
	})

	defineExpose({
		init,
		publice
	})
</script>

<style lang="scss" scoped>
	.footer-wrap {
		width: 100%;
		min-height: 100px;
		background-color: rgb(249, 249, 251);
		display: flex;
		justify-content: center;
		align-items: center;
	}
</style>

components/header.vue

<template>
	<div class="header-wrap">
		<div class="header-tips">This site is no longer updated.</div>
		<ul class="header-content">
			<li class="header-icon" @click="goLinkHandle('docs')">
				<img :src="icon" />
				<span>React</span>
			</li>
			<template v-for="(item,index) in menuList" :key="index">
				<li class="header-li" :class="{'header-li-current':currentPath==item.path}"
					@click="goLinkHandle(item.type)">{{item.name}}</li>
			</template>

		</ul>
	</div>
	<div id="dragIcon"></div>
</template>

<script setup>
	import dragIcon from "miao-drag";
	import {
		watch,
		ref,
		reactive,
		onMounted
	} from 'vue';
	import {
		useRoute,
		useRouter
	} from 'vue-router';
	const icon = ref(
		'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ii0xMS41IC0xMC4yMzE3NCAyMyAyMC40NjM0OCI+CiAgPHRpdGxlPlJlYWN0IExvZ288L3RpdGxlPgogIDxjaXJjbGUgY3g9IjAiIGN5PSIwIiByPSIyLjA1IiBmaWxsPSIjNjFkYWZiIi8+CiAgPGcgc3Ryb2tlPSIjNjFkYWZiIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiPgogICAgPGVsbGlwc2Ugcng9IjExIiByeT0iNC4yIi8+CiAgICA8ZWxsaXBzZSByeD0iMTEiIHJ5PSI0LjIiIHRyYW5zZm9ybT0icm90YXRlKDYwKSIvPgogICAgPGVsbGlwc2Ugcng9IjExIiByeT0iNC4yIiB0cmFuc2Zvcm09InJvdGF0ZSgxMjApIi8+CiAgPC9nPgo8L3N2Zz4K'
	)

	const currentPath = ref('');
	const route = useRoute();
	watch(route, (params) => {
		currentPath.value = params.path;
	}, {
		deep: true,
		immediate: true
	})

	onMounted(() => {
		console.log("[onMounted]")
		setDragIcon();
	});


	const menuList = reactive([{
		id: 1,
		name: 'Docs',
		path: '/docs',
		type: 'docs'
	}, {
		id: 2,
		name: 'Tutorial',
		path: '/tutorial',
		type: 'tutorial'
	}, {
		id: 3,
		name: 'Blog',
		path: '/blog',
		type: 'blog'
	}, {
		id: 4,
		name: 'Community',
		path: '/community',
		type: 'community'
	}, {
		id: 5,
		name: 'About',
		path: '/about',
		type: 'about'
	}, {
		id: 5,
		name: 'TypeScript 教程',
		path: '/ts',
		type: 'ts'
	}])


	//进行页面跳转
	const router = useRouter();

	function goLinkHandle(type) {
		if (type == 'docs') {
			router.push({
				path: '/docs'
			})
		} else if (type == 'tutorial') {
			router.push({
				path: '/tutorial'
			})
		} else if (type == 'blog') {
			router.push({
				path: '/blog'
			})
		} else if (type == 'community') {
			router.push({
				path: '/community'
			})
		} else if (type == 'about') {
			router.push({
				path: '/about'
			})
		} else if (type == 'ts') {
			router.push({
				path: '/ts'
			})
		}
	}


	function setDragIcon() {
		const clientHeight = document.documentElement.clientHeight;
		const clientWidth = document.documentElement.clientWidth;
		new dragIcon({
			el: '#dragIcon',
			top: ((clientHeight / 2) - 50) + 'px',
			left: (clientWidth - 250) + 'px',
			onClick: () => {
				console.log("我是点击事件")
			}
		});
	}
</script>

<style lang="scss" scoped>
	.header-wrap {
		width: 100%;
		display: flex;
		flex-direction: column;
		background-color: rgb(22, 24, 29);

		.header-tips {
			width: 100%;
			max-width: 1200px;
			display: flex;
			flex-direction: row;
			justify-content: center;
			align-items: center;
			font-size: 18px;
			font-weight: bold;
			color: #ffffff;
			margin: 12px auto;
		}

		.header-content {
			width: 100%;
			max-width: 1200px;
			display: flex;
			flex-direction: row;
			margin: 12px auto;
			align-items: center;

			.header-icon {
				height: auto;
				display: flex;
				flex-direction: row;
				color: #61dafb;
				align-items: center;
				justify-content: center;
				margin-right: 100px;
				cursor: pointer;

				img {
					width: 40px;
					height: 40px;
				}

				span {
					font-weight: 700;
					font-size: 20px;
					margin-left: 12px;
				}
			}

			.header-li {
				height: 40px;
				position: relative;
				font-size: 18px;
				color: #ffffff;
				padding-left: 15px;
				padding-right: 15px;
				cursor: pointer;
			}

			.header-li-current {
				color: #61dafb;
			}

			.header-li-current::after {
				content: " ";
				height: 3px;
				position: absolute;
				width: 100%;
				left: 50%;
				transform: translate(-50%);
				bottom: 0px;
				background-color: #61dafb;
				animation: identifier 1s ease;
			}

			@keyframes identifier {
				0% {
					width: 0%;
				}

				100% {
					width: 100%;
				}
			}
		}
	}

	#dragIcon {
		border: 1px solid #00a2ef;
		border-radius: 8px;
		width: 100px;
		height: 100px;
		position: fixed;
		cursor: pointer;
		z-index: 999;
	}
</style>

components/test.vue

<template>
	<div>
		<p>{{message}}</p>
	</div>
</template>

<script>
	export default {
		props: {
			message: {
				type: String,
				default: () => {
					return "消息"
				}
			}
		},
		setup(props) {
			console.log("[props]", props)


			console.log("[this]", props.message)
			return {

			}
		}
	}
</script>

<style>
</style>

assets/base.css

* {
	padding: 0px;
	margin: 0px;
	box-sizing: border-box;
	-webkit-box-sizing: border-box;
}

html,
body {
	width: 100%;
	background-color: #f2f2f2;
}

a {
	text-decoration: none;
}

ul,
li,
ol {
	list-style: none;
}

button {
	cursor: pointer;
}

button::after {
	border: none;
}

assets/main.scss

@import './base.css';
@import './styles.scss';

.ping-wrap {
	width: 100%;
	display: flex;
	flex-direction: column;

	.ping-container {
		width: 100%;
		max-width: 1200px;
		min-height: 100vh;
		margin: 0px auto;
		display: flex;
		flex-direction: column;
		background-color: #fff;
	}
}

assets/styles.scss

.row {
  border: 1px solid red;
  width: 100%;
  display: flex;
}
.col-6 {
  border: 1px solid red;
  width: 50%;
}
.ul-block {
  border: 1px solid #dcdcdc;
  border-radius: 12px;
  padding: 10px;
  margin-bottom: 12px;
  li {
    border-bottom: 1px solid #dcdcdc;
    padding: 12px 0px;
  }
  li:last-child {
    border-bottom: none;
  }
}
.ul-block-current{
  border: 1px solid #00a2ef;
}

vue3.0官网
Pinia官网
Vue Router4.X官网
Vite官网

https://github.com/zzmiao/vue3.0.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/588858.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

win11任务栏时间改成12时制

需求&#xff1a;默认24小时值&#xff0c;想改成12小时3:49 方法&#xff1a;设置-时间和语言-语言和区域-管理语言设置-格式 将时间格式改成带tt的

2022年长三角高校数学建模竞赛C题隧道的升级改造与设计解题全过程文档及程序

2022年长三角高校数学建模竞赛 C题 隧道的升级改造与设计 原题再现&#xff1a; 某地现存一旧式双洞隧道&#xff0c;现计划将该隧道在旧貌基础上升级改造。在升级改造前&#xff0c;需进行定标与设计。考虑到该隧道洞壁附着特殊涂料&#xff0c;无人机在洞内通信信号较差&am…

网络面试题:什么是 TCP/IP?

目录标题 什么是 TCP/IP?1) 网络接口层:2) 网络层:3) 传输层:4) 应用层: 2.数据包3.网络接口层4.网络层1) IP:2)地址解析协议 ARP3)子网 5 传输层1&#xff09;UDP&#xff1a;2&#xff09;TCP&#xff1a; 6 应用层运行在TCP协议上的协议&#xff1a;运行在UDP协议上的协议&…

Netty 实现百万级连接服务的难点和优点分析总结

推送服务 还记得一年半前&#xff0c;做的一个项目需要用到 Android 推送服务。和 iOS 不同&#xff0c;Android 生态中没有统一的推送服务。Google 虽然有 Google Cloud Messaging &#xff0c;但是连国外都没统一&#xff0c;更别说国内了&#xff0c;直接被墙。 所以之前在…

Lua学习笔记:C/C++和Lua的相互调用

前言 本篇在讲什么 C/C和Lua的相互调用 本篇适合什么 适合初学Lua的小白 适合需要C/C和lua结合开发的人 本篇需要什么 对Lua语法有简单认知 对C/C语法有简单认知 依赖Lua5.1的环境 依赖VS 2017编辑器 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&…

云南智慧档案库综合管理系统建设解决方案

一、智慧档案管理系统建设背景 档案作为一种特殊的文献&#xff0c;是人类社会活动的产物&#xff0c;具有特殊的价值&#xff0c;其价值可以概括为现实价值和历史价值。档案是人类留给国家和社会的宝贵财富&#xff0c;它在经济与社会建设中起着重要的作用。档案是反映一个单…

多重共线性的处理方法

回归分析需要考虑多重共线性问题。多重共线性是指自变量之间存在高度相关性&#xff0c;导致回归模型的系数估计不稳定和假设检验不可靠。在实际应用中&#xff0c;许多自变量之间都可能存在一定程度的相关性&#xff0c;如果没有进行控制&#xff0c;就会导致多重共线性问题的…

设计模式之美-实战二:如何对接口鉴权这样一个功能开发做面向对象分析?

面向对象的三个环节&#xff1a;面向对象分析&#xff08;OOA&#xff09;、面向对象设计&#xff08;OOD&#xff09;、面向对象编程&#xff08;OOP&#xff09;。只知道OOA、OOD、OOP只能说有一个宏观了解&#xff0c;我们更重要的还是要知道“如何做”&#xff0c;也就是&a…

【快应用】多语言适配案例

【关键词】 多语言&#xff0c;$t 【问题背景】 快应用平台的能力会覆盖多个国家地区&#xff0c;平台支持多语言的能力后&#xff0c;可以让一个快应同时支持多个语言版本的切换&#xff0c;开发者无需开发多个不同语言的源码项目&#xff0c;避免给项目维护带来困难。使用系…

子串分值--子串分值和 模拟,找规律

子串分值和 n有十万&#xff0c;需要找规律&#xff0c;O(n^2)不满足要求 分析样例&#xff1a; Ababc 01234 长度是n5 索引下标-对应字符 0A贡献 112 a;ab;---22*1 next a 2&#xff1b; pre a -1 1b贡献 112 b;ba;---42*2 next b 3&#xff1b; pre b -1 2a贡献 1113…

2023年测试前景?测试开发工程师养成记,开发企业级测试平台...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 测试开发&#xff…

IDS 和 IPS 日志监控

什么是IDS/IPS 入侵检测系统 &#xff08;IDS&#xff09; 和入侵防御系统 &#xff08;IPS&#xff09; 是监视组织网络中的流量以检测和防止恶意活动和策略违规的网络组件。 入侵检测系统&#xff08;IDS&#xff09;和入侵防御系统&#xff08;IPS&#xff09;可以说是企业…

C语言学习分享(第八次)------数据的存储

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:C语言学习分享⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多C语言知识   &#x1f51d;&#x1f51d; 数据的存储 1. 前言&#x1f6a9;2…

现代化智慧档案室建设图文推介

1、防火。建立档案库房防火制度&#xff0c;档案库房附近严禁存放易燃、易爆物品&#xff0c;库房内严禁吸烟&#xff0c;并备有灭火器&#xff0c;经常进行检查更换。 主要设备为&#xff1a;烟雾探测器和感温探测器和七氟丙烷灭火系统。 2、防潮。库房内备有温湿度计&#x…

GB28181 对接海康平台,解决音视频卡顿问题

GB28181 对接海康平台,解决音视频卡顿问题 一、概述二、问题分析1、设备对比分析2、抓包对比分析3、验证分析结果三、总结四、讨论一、概述 设备使用GB28181协议对接海康平台时,发现音频和视频存在卡顿现象,不是一直卡顿,有时候卡有时候不卡,但是卡顿的时候音视频一起卡顿…

炫技操作--递归实现翻转链表(java)

递归实现链表的逆序 leetcode 206题。 翻转链表递归解法普通方式实现链表翻转链表专题 leetcode 206题。 翻转链表 leetcode链接用于测试 题目&#xff1a;描述 将一个链表翻转&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 递归解法 解题思路…

chatgpt赋能python:Python中删除的SEO

Python中删除的SEO Python是一个强大的编程语言&#xff0c;它广泛应用于各种领域&#xff0c;包括SEO。在SEO领域中&#xff0c;Python可以用来处理各种数据&#xff0c;包括删除不必要的数据。本文将介绍如何在Python中删除SEO数据。 什么是SEO数据&#xff1f; SEO是搜索…

代码创造的欢乐世界-通用人工智能让儿童熟练应用编程

想要复杂的参考这一篇&#xff0c;使用云平台即可完成&#xff1a; 美美的圣诞树画出来-CoCube- 把圣诞树换成六一儿童节主题的就可以啦。 这一篇是使用chatgpt类应用&#xff0c;给出关键提示词&#xff0c;代码自动生成哦。 神十六发射成功&#xff0c;科技工作者博士学位…

python接口自动化使用requests库发送http请求

目录 前言一、requests库二、HTTP 请求方法三、发送GET请求四、发送POST请求五、获取响应数据六、高级操作 6.1文件下载6.2文件上传6.3SSL证书验证6.4保持会话6.5requests封装总结 前言 今天笔者想和大家来聊聊python接口自动化如何使用requests库发送http请求&#xff0c;废…

【JavaSE】Java基础语法(三十七):Java 中的 String 类(源码级别)

文章目录 1. 构造方法1.1 String()1.2 String(String original)1.3 String(char[] chars)1.4 String(char数组,起始下标,长度)1.5 String(byte数组)1.6 String(byte数组,起始下标,长度)1.7 String(StringBuffer buffer)1.8 String(StringBuilder builder) 2. 普通方法2.1 char …