vue3 常用命令,函数,插件,创建命令

vue3 常用命令,函数,插件,创建命令

1.vu3 基本命令:
v-model
v-if
v-else
v-binding
v-for
v-show

2.setup 函数
   第一步安装:npm i vite-plugin-vue-setup-extend -D
   第二步配置:vite.config.ts
		import { defineConfig } from 'vite'
		import VueSetupExtend from 'vite-plugin-vue-setup-extend'

		export default defineConfig({
		  plugins: [ VueSetupExtend() ]
		})
   第三步使用:<script setup lang="ts" name="Person">
    import {ref} from 'vue'
	let name1 = '张三'  //不是响应式的了
	let name2 = ref('张三')  //是响应式的了
	
3. ref 响应式函数
    作用:定义响应式变量,基本数据类型做为入参
	语法:let xxx = ref(初始值)
	返回值:一个RefImpl的实例对象,简称ref对象或ref,ref对象的value属性是响应式的
    注意点:
             JS中操作数据需要:xxx.value,但模板中不需要.value,直接使用即可
			 对于let name = ref('张三')来说,name不是响应式的,name.value是响应式的

4.reactive响应式函数
    作用:定义响应式变量,对象类型做为入参
	语法:let xxx = reactive(源对象)
	返回值:一个Proxy的实例对象
    注意点:
            reactive定义的响应式数据是“深层次”的。

5. ref vs reactive
	ref用来定义:基本类型数据、对象类型数据
	reactive用来定义:对象类型数据
	ref创建的变量必须使用.value(可以使用volar插件自动添加.value)
	reactive重新分配一个新对象,会失去响应式(可以使用Object.assign去整体替换)Object.assgin(car,{barnd:'小米',price:30}
	
6.toRefs,toRef
   作用:
        将一个响应式对象中的每一个属性,转换为ref对象
		toRefs与toRef功能一致,但toRefs可以批量转换
   import {ref,reactive,toRefs,toRef} from 'vue'
      // 数据
     let person = reactive({name:'张三', age:18, gender:'男'})
     let {name,gender} =  toRefs(person) //toRefs将person对象中的n个属性批量取出,且依然保持响应式的能力
	 let age = toRef(person,'age') //通过toRef将person对象中的age 1个属性取出,且依然保持响应式的能力
	 
7.computed
   作用:
           根据已有数据计算出新数据(和Vue2中的computed作用一致)
           计算属性有缓存,方法没缓存
      import {ref,computed} from 'vue'
	    let firstName = ref('zhang')
        let lastName =  ref('san')
	     // 计算属性——只读取,不修改
		  /* let fullName = computed(()=>{
			return firstName.value + '-' + lastName.value
		  }) */
		  
		  // 计算属性——既读取又修改
			  let fullName = computed({
				// 读取
				get(){
				  return firstName.value + '-' + lastName.value
				},
				// 修改
				set(val){
				  console.log('有人修改了fullName',val)
				  firstName.value = val.split('-')[0]
				  lastName.value = val.split('-')[1]
				}
			  })
  
8.watch
   作用:监视数据的变化(和Vue2中的watch作用一致)
   特点:Vue3中的watch只能监视以下四种数据
        1. ref定义的数据。
		2. reactive定义的数据。
		3. 函数返回一个值(getter函数)。
		4. 一个包含上述内容的数组。
   import {ref,reactive,watch} from 'vue'
	  // 数据
	  let sum = ref(0)
	  // 方法
	  function changeSum(){
		sum.value += 1
	  }
	  // 监视,情况一:监视【ref】定义的【基本类型】数据
	  const stopWatch = watch(sum,(newValue,oldValue)=>{
		if(newValue >= 10){
		  stopWatch()
		}
	  })
	  let person = ref({
							name:'张三',
							age:18
						  })
      function changeAge(){
			person.value.age += 1
		  }
		function changePerson(){
			person.value = {name:'李四',age:90}
		  }
		 //监视【ref】定义的【对象类型】数据
      watch(person,(newValue,oldValue)=>{
			console.log('person变化了',newValue,oldValue)
		  },{deep:true})
		
		let person = reactive({
			name:'张三',
			age:18
		  })	

		  function changePerson(){
			Object.assign(person,{name:'李四',age:80})
		  }
		// 监视,情况三:监视【reactive】定义的【对象类型】数据,且默认是开启深度监视的
		  watch(person,(newValue,oldValue)=>{
			console.log('person变化了',newValue,oldValue)
		  })
		  // 监视,情况四:监视响应式对象中的某个属性,且该属性是对象类型的,可以直接写,也能写函数,更推荐写函数
		  watch(()=>person.car,(newValue,oldValue)=>{
			console.log('person.car变化了',newValue,oldValue)
		  },{deep:true})
		  
		  // 监视,情况五:监视上述的多个数据
		  watch([()=>person.name,person.car],(newValue,oldValue)=>{
			console.log('person.car变化了',newValue,oldValue)
		  },{deep:true})
  
9.watch vs  watchEffect
    watch:要明确指出监视的数据入参
	watchEffect:不用明确指出监视的数据(函数中用到哪些属性,那就监视哪些属性)
	import {ref,watch,watchEffect} from 'vue'
	  // 数据
	  let temp = ref(0)
	  let height = ref(0)
       // 用watch实现,需要明确的指出要监视:temp、height
	  watch([temp,height],(value)=>{
		const [newTemp,newHeight] = value
		// 室温达到50℃,或水位达到20cm,立刻联系服务器
		if(newTemp >= 50 || newHeight >= 20){
		  console.log('联系服务器')
		}
	  })
	  
	  // 用watchEffect实现,不用
	  const stopWtach = watchEffect(()=>{
		// 水温达到100,或水位达到50,取消监视
		if(temp.value === 100 || height.value === 50){
		  console.log('清理了')
		  stopWtach()
		}
	  })
  
 
10. vue3生命周期
      让开发者有机会在特定阶段运行自己的代码,这些特定的函数统称为:生命周期钩子
	    创建阶段:setup
		挂载阶段:onBeforeMount、onMounted
		更新阶段:onBeforeUpdate、onUpdated
		卸载阶段:onBeforeUnmount、onUnmounted
		常用的钩子:onMounted(挂载完毕)、onUpdated(更新完毕)、onBeforeUnmount(卸载之前)
		 import { 
			ref, 
			onBeforeMount, 
			onMounted, 
			onBeforeUpdate, 
			onUpdated, 
			onBeforeUnmount, 
			onUnmounted 
		  } from 'vue'

		  // 数据
		  let sum = ref(0)
		  // 方法
		  function changeSum() {
			sum.value += 1
		  }
		  console.log('setup')
		  // 生命周期钩子
		  onBeforeMount(()=>{
			console.log('挂载之前')
		  })
		  onMounted(()=>{
			console.log('挂载完毕')
		  })
		  onBeforeUpdate(()=>{
			console.log('更新之前')
		  })
		  onUpdated(()=>{
			console.log('更新完毕')
		  })
		  onBeforeUnmount(()=>{
			console.log('卸载之前')
		  })
		  onUnmounted(()=>{
			console.log('卸载完毕')
		  })
		  
		  
11. 自定义函数:hook:
     优势:复用代码, 让setup中的逻辑更清楚易懂
      useDog.ts
	    import {reactive,onMounted} from 'vue'
		import axios,{AxiosError} from 'axios'

		export default function(){
		  let dogList = reactive<string[]>([])

		  // 方法
		  async function getDog(){
			try {
			  // 发请求
			  let {data} = await axios.get('https://dog.ceo/api/breed/pembroke/images/random')
			  // 维护数据
			  dogList.push(data.message)
			} catch (error) {
			  // 处理错误
			  const err = <AxiosError>error
			  console.log(err.message)
			}
		  }

		  // 挂载钩子
		  onMounted(()=>{
			getDog()
		  })
			
		  //向外部暴露数据
		  return {dogList,getDog}
		}

    1.hook的使用demo: http.js(axios+拦截器)
		// axios基础的封装
		import axios from 'axios'
		import { ElMessage } from 'element-plus'
		import { useUserStore } from '@/stores/userStore'
		const httpInstance = axios.create({
		  baseURL: 'http://webapi.net',
		  timeout: 5000
		})

		// 拦截器

		// axios请求拦截器
		httpInstance.interceptors.request.use(config => {
		  // 1. 从pinia获取token数据
		  const userStore = useUserStore()
		  // 2. 按照后端的要求拼接token数据
		  const token = userStore.userInfo.token
		  if (token) {
			config.headers.Authorization = `Bearer ${token}`
		  }
		  return config
		}, e => Promise.reject(e))

		// axios响应式拦截器
		httpInstance.interceptors.response.use(res => res.data, e => {
		  // 统一错误提示
		  ElMessage({
			type: 'warning',
			message: e.response.data.message
		  })
		  return Promise.reject(e)
		})
        
		//导出实列对象
		export default httpInstance

		2.user.js
		// 封装所有和用户相关的接口函数
		import httpInstance from '@/utils/http'

		export const loginAPI = ({ account, password }) => {
		  return httpInstance({
			url: '/login',
			method: 'POST',
			data: {          //post
			  account,
			  password
			}
		  })
		}
		
       3.category.js		
		import request from '@/utils/http'
		export function getCategoryAPI (id) {
		  return request({
			url: '/category',
			params: {         //get
			  id
			}
		  })
		}
		
		4.user.js 标准写法
		    import {reactive,onMounted} from 'vue'
			import axios,{AxiosError} from 'axios'

			export default function(){
			  let dogList = reactive<string[]>([])

			  // 方法
			  async function getDog(){
				try {
				  // 发请求
				  let {data} = await axios.get('https://dog.ceo/api/breed/pembroke/images/random')
				  // 维护数据
				  dogList.push(data.message)
				} catch (error) {
				  // 处理错误
				  const err = <AxiosError>error
				  console.log(err.message)
				}
			  }

			  // 挂载钩子
			  onMounted(()=>{
				getDog()
			  })
				
			  //向外部暴露数据
			  return {dogList,getDog}
			}

12.路由的使用vue-router
    1.配置路由文件
     router/index.js
	 import {createRouter,createWebHistory} from 'vue-router'
	 import Home from './views/Home.vue'
	 import About from './views/About.vue'
	 const router = createRouter({
			history:createWebHistory(),
			routes:[
				{
					path:'/home',
					component:Home
				},
				{
					path:'/about',
					component:About
				}
			]
		})
		export default router
       2.main.ts引用加载路由文件
	   import router from './router/index.js'
	   app.use(router)
	   app.mount('#app')
	   
	   3.路由跳转: to字符串,to对象(to前需加冒号:
	   <RouterLink to='/home' >Home</RouterLink>
	   <RouterLink to="{ path: '/about'}">About</RouterLink>
	      
       4.路由的工作模式
	      history模式:createWebHistory
		      优点:URL更加美观,不带有#,更接近传统的网站URL。
              缺点:后期项目上线,需要服务端配合处理路径问题,否则刷新会有404错误
			  	  const router = createRouter({
				  history:    history: createWebHistory(), //web模式
			})
	      hash模式:createWebHashHistory
		      优点:兼容性更好,因为不需要服务器端处理路径。
              缺点:URL带有#不太美观,且在SEO优化方面相对较差 
	
			const router = createRouter({
				history: createWebHashHistory(),
				routes:[
					
					{
						name: 'zhuye',    //命名路由 <router-link :to="{name:'zhuye'}">跳转</router-link>
						path: '/home',
						component: Home
					},
					{
						name: 'xinwen',
						path: '/news',
						component: News,
						children:[
							{
								name: 'xiang',   //  命名    <router-link :to="{path:'/news/detail'}">跳转</router-link> =<router-link to="/news/detail">xxxx</router-link>
								path: 'detail',
								component: Detail,  
							}
						]
					}
				]
			})
			export default router

		5.1 路由传参:
			<router-link to="/news/detail?a=1&b=2&content=欢迎你">
			<RouterLink 
							  :to="{
								//name:'xiang', //用name也可以跳转
								path:'/news/detail',
								query:{        //params参数
								  id:news.id,
								  title:news.title,
								  content:news.content
								}
							  }
			5.2 query
                5.2.1 query接收参数:
				import {useRoute} from 'vue-router'
				const route = useRoute()
				// 打印query参数
				console.log(route.query)
				
				5.2.2 params接收参数:
				<RouterLink 
					  :to="{
						name:'xiang', //params传参,必须使用用name跳转,不能使用path
						params:{
						  id:news.id,
						  title:news.title,
						  content:news.title
						}
					  }
					  
                console.log(route.params)
				
		6.路由的嵌套使用:children
		7.跳转导航:
		import {useRoute,useRouter} from 'vue-router'

		const route = useRoute()
		const router = useRouter()

		console.log(route.query)
		console.log(route.parmas)
		
		console.log(router.push)
		console.log(router.replace)
        8.重定向redirect
		{
			path:'/',
			redirect:'/about'
		}
		
13.pinia的使用:分布式缓存:读取数据的工具,不用重复读取,只读一遍
     第一步安装:npm install pinia
	 第二步:操作src/main.ts
	    /*引入createPinia,用于创建pinia */
		import { createPinia } from 'pinia'

		/* 创建pinia */
		const pinia = createPinia()
		const app = createApp(App)

		/* 使用插件 */{}
		app.use(pinia)
		app.mount('#app')
		
     1.存储+读取数据demo: storeCount.js
           // 引入defineStore用于创建store
				import {defineStore} from 'pinia'

				// 定义并暴露一个store
				export const useTalkStore = defineStore('talk',{
				  // 动作
				  actions:{},
				  // 状态
				  state(){
					return {
					  talkList:[
						{id:'yuysada01',content:'你今天有点怪,哪里怪?怪好看的!'},
							 {id:'yuysada02',content:'草莓、蓝莓、蔓越莓,你想我了没?'},
						{id:'yuysada03',content:'心里给你留了一块地,我的死心塌地'}
					  ]
					}
				  },
				  // 计算
				  getters:{}
				})
		 
14.生成唯一id:  nanoid

15.组件通信
     15.1 父传子:
	                  props
					  v-model
					  $refs
					  插槽
	  15.2 子传父:
	                   props
					   v-model
					   $parent
	  15.3 祖传孙,孙传组:
	                   $attrs
					   provide,inject
	 15.4 兄弟间,任意组件间:
	                  mitt
					  pinia

组件通信:props,mitt,v-model,$attrs,$parent,provide,inject,pinia,slot插槽

16. hook的使用
16.1 useDog.ts
import {reactive,onMounted} from 'vue'
import axios,{AxiosError} from 'axios'

export default function(){
  let dogList = reactive<string[]>([])

  // 方法
  async function getDog(){
    try {
      // 发请求
      let {data} = await axios.get('https://dog.ceo/api/breed/pembroke/images/random')
      // 维护数据
      dogList.push(data.message)
    } catch (error) {
      // 处理错误
      const err = <AxiosError>error
      console.log(err.message)
    }
  }

  // 挂载钩子
  onMounted(()=>{
    getDog()
  })
    
  //向外部暴露数据
  return {dogList,getDog}
}

16.2 组件中具体使用*.vue:
<template>
  <div>
    dog:<img v-for="(u,index) in dogList" :key="index" :src="(u as string)" > 
  </div>
</template>

<script setup lang="ts">
  import useDog from './stores/useDog'
    
  let {dogList,getDog} = useDog()
  console.log(dogList)
</script>

17.自动导入定制化样式文件进行样式覆盖
17.1 安装插件:  pnpm install -D sass  unplugin-vue-components unplugin-auto-import
17.2 添加src/css/index.scss 文件
// styles/element/index.scss
/* 只需要重写你需要的即可 */
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
  $colors: (
    'primary': (
      'base': green,
    ),
    'success': (
      'base': #67c23a,
    ),
    'warning': (
      'base': #e6a23c,
    ),
    'danger': (
      'base': #f56c6c,
    ),
    'error': (
      'base': #f56c6c,
    ),
    'info': (
      'base': #909399,
    )
  )
);
17.2 引入vite.config.ts
 
// elementPlus按需导入
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    vueDevTools(),
     // ...
     AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [
        // 1. 配置elementPlus采用sass样式配色系统
        ElementPlusResolver({ importStyle: "sass" }),
      ],
    }),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    },
  },
  css: {
    preprocessorOptions: {
      scss: {
        // 2. 自动导入定制化样式文件进行样式覆盖
        additionalData: `
          @use "@/styles/element/index.scss" as *;
          @use "@/styles/var.scss" as *;
        `,
      }
    }
  }
})

18.父组件使用子组件的数据:使用defineExpose传递	

18.1.Person.vue

<!-- 子组件Person.vue中要使用defineExpose暴露内容 -->
<script lang="ts" setup name="Person">
  import {ref,defineExpose} from 'vue'
    // 数据
  let name = ref('张三')
  let age = ref(18)
  // 使用defineExpose将组件中的数据交给外部
  defineExpose({name,age})
</script>

18.2.app.vue 父组件使用子组件的数据
<!-- 父组件App.vue -->
<template>
  <Person ref="ren"/>
  <button @click="test">测试</button>
</template>

<script lang="ts" setup name="App">
  import Person from './components/Person.vue'
  import {ref} from 'vue'

  let ren = ref()

  function test(){
    console.log(ren.value.name)
    console.log(ren.value.age)
  }
</script>

19.传参:query,params
   query
   params:name
   
   <script setup lang="ts">
	import {useRoute} from 'vue-router'
	const route = useRoute()
	// 打印query参数
	console.log(route.query)
	console.log(route.params)
	</script>

	<template>
	  <div>
		news page  
	  </div>
	  <router-link :to="{
	    name:'xiang',  //path:'/news/detail'=query,params必须用name跳转
	    params:{
				id:1,
				name:'zhangsan'
	            }
		}">detail</router-link>
	  <div>
		<RouterView></RouterView>
	  </div>
	</template>
	<style>
	</style>
   
   {
    path:'/',
    redirect:'/about'
   }

 20.pinia的使用:
   20.1定义:talk.ts
   // 引入defineStore用于创建store
		import {defineStore} from 'pinia'
		// 定义并暴露一个store
		export const useTalkStore = defineStore('talk',{  
		// 动作  
		actions:{},  
		// 状态  
		state(){    
		return {      
		talkList:[        
		{id:'yuysada01',content:'你今天有点怪,哪里怪?怪好看的!'},             
		{id:'yuysada02',content:'草莓、蓝莓、蔓越莓,你想我了没?'},        
		{id:'yuysada03',content:'心里给你留了一块地,我的死心塌地'}      
		]    
		}  
		},  
		// 计算  
		getters:{}
		})

   20.2 使用pinia定义的数据:   
		 <script setup lang="ts" name="Count">
		  import {useTalkStore} from '@/store/talk'

		  const talkStore = useTalkStore()
		  console.log(talkStore.talkList)
		</script>

21.Icon图标的使用:
0.安装插件:pnpm install @element-plus/icons-vue

1.main.ts 引入插件 
import * as ElementPlusIconsVue from '@element-plus/icons-vue'

const app = createApp(App)
//全局注册
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}

2.app.vue使用测试
  2.1 复制icon
    <el-icon size="35" color="red"><House /></el-icon>
  2.1 引入
   <script setup lang="ts">
import { Calendar, Search } from '@element-plus/icons-vue';

  <el-icon size="35" color="red"><House /></el-icon>
  <el-button type="primary" icon="Search">button</el-button>

  <el-input  placeholder="placeholder" :sufifix-icon="Calendar"></el-input>
  <el-input  placeholder="Please input" :suffix-icon="Calendar" :prefix-icon="Search"/>

二.常用插件:
pnpm install element-plus --save
pnpm i axios --save  https请求
pnpm install vue-router
pnpm install -D unplugin-vue-components unplugin-auto-import按需导入(自动导入)
pnpm install @element-plus/icons-vue     使用element-plus Icon图标 
npm install pinia
pnpm install sass
pnpm nanoid
极简插件

三.vue3 demovue
pnpm init vite@latest
pnpm create vue@latest
本地跨域配置
posted @ 2025-09-02 17:12  大树2  阅读(17)  评论(0)    收藏  举报