vite搭建vue3项目的相关知识点

vite:前端构建工具
相比vue-cli基于webpack搭建的项目,vite搭建的项目按需编译运行速度极速,能够显著提升前端开发效率
安装:

npm create vite@latest 项目名称 -- --template vue

下载依赖

npm install

启动项目

npm run dev

项目安装vue-router

npm install vue-router@4 -s

在vite.config.js文件配置

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.vue'],
    alias: {
      '@':'/src'
      // '@': Path.resolve(_dirname,'/src') 用于引用路径时@代替src
    }
  }
})

面试题:vue3中定义响应式数据ref,reactive的区别
ref可定义的任意类型数据,获取时需要.value获取,一般接口返回的数据用ref定义
reactive只能定义对象或数组,定义复杂多层次数据

面试题:vue2和vue3多数据拦截有什么不同点
vue2=>Object.defineProperty ,对于对象类型的数据,需要for in循环遍历+递归对象来获取一项
vue3=>new Proxy ,对于对象类型的数据,不循环+递归可以获取每一项,性能提升

setup语法糖插件
解决import { ref,reactive,…}每个文件都引入,比较繁琐的问题
安装

npm install unplugin-auto-import -D

配置vite.comfig.is文件

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
//引入自动导入插件
import AutoImport from 'unplugin-auto-import/vite'

export default defineConfig({
	  plugins: [
	    vue(),
	    AutoImport({
	      imports: ['vue','vue-router'],
	      dts: 'src/auto-imports.d.ts'
	    })
	  ]
  })

toRefs=>解构响应式数据

let obj = reactive({
  name:'luishu',
  id: 2
})
let {name,id} = toRefs(obj);

computed计算属性

//默认写法绑定v-model,不能实现双向数据绑定,有警告
const srcAdd = computed(() => {
  return count.value + 1
})
//get,set写法,绑定v-model,可以实现双向数据绑定
const add = computed({
  get() {
    return count.value + 1
  },
  set(value) {
    count.value = value
  }
})

watch监听

//监听一个
watch(add, (newValue, oldValue) => {
  console.log(newValue, oldValue)
})
// 监听多个数组包起来
watch([count, srt], (newValue, oldValue) => {
  console.log(newValue, oldValue)
})
//一进入就监听,加immediate:true
watch([count, srt], (newValue, oldValue) => {
  console.log(newValue, oldValue)
},{immediate:true})

//监听对象的某个属性,  层级深的属性并且深度监听
watch(() => obj.children, (newValue, oldValue) => {
  console.log(newValue, oldValue)
},{immediate:true,deep:true})

//vue3中useRouter=>this.$router,useRoute=>this.$route
//监听router
let router = useRouter()
watch(() => router.currentRoute.value,(newValue)=>{
  console.log(newValue)
},{ immediate: true })
//立即执行监听函数,默认监听全部
watchEffect(() => {
  console.log('home')
})

面试题:watch与watchEffect的区别?
watchEffect 适合用于自动追踪依赖并执行副作用,不需要手动指定要观察的状态。
watch 提供了更多的控制选项,适合需要显式指定观察状态源和访问状态变化前后值的场景。
生命周期

vue2vue3
beforeCreatesetup()
createdsetup()
beforeMountonBeforeMount(请问接口)
mountedonMounted (获取DOM)
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestroyonBeforeUnmount
destroyedonUnmounted
import { onBeforeMount, onMounted } from 'vue'
onBeforeMount(() => {
  console.log('接口请求')
})
onMounted(() => {
  console.log('获取DOM')
})

组件传值
父传子 defineProps

//父组件
<template>
  <div class="about">
    <h1>This is an about page</h1>
    <HelloWorld :msg="msg" />
  </div>
</template>
//js
import { ref } from 'vue'
import HelloWorld from '../components/HelloWorld.vue'
let msg = ref('Welcome to Your Vue.js')

//子组件
<template>
  <h1>{{ msg }}</h1>
</template>
//js
import { defineProps } from 'vue'
defineProps({
  msg: String,
})

子传父 defineEmits

//子组件
<button @click="emitChange">emit</button>
<script setup >
import { ref,defineEmits} from 'vue'

const count = ref(20)
const emit = defineEmits(['fu'])//js写法
const emit = defineEmits<{
  (e: 'change', id: number) : void
}>()//ts写法
const emitChange = (id: number) => {
  emit('change', count.value)
}
//父组件
<HelloWorld :msg="msg"  @change="change"/>
//js
import HelloWorld from '../components/HelloWorld.vue'
const change = (e) => {
  console.log(e)
}

</script>

新增内置组件teleport:是一个内置组件,它可以将一个组件内部的一部分模板“传送”到该组件的 DOM 结构外层的位置去。

<button @click="open = true">Open Modal</button>
//to:来指定传送的目标,可以是一个 CSS 选择器字符串,也可以是一个 DOM 元素对象(body,#idname,。classname)
<Teleport to="body">
  <div v-if="open" class="modal">
    <p>Hello from the modal!</p>
    <button @click="open = false">Close</button>
  </div>
</Teleport>

动态组件

<template>
  <div class="card">
    <ul>
      <li 
      v-for="(item,index) in componentsList" 
      :key="index"
      @click="emitChange(item)"
      >
       // <component :is="item.com"></component>
      </li>
    </ul>
  </div>
  // 动态组件的关键component :is="动态获取组件"
  <keep-alive>
      <component :is="DataTransferItemList.com"></component>
   </keep-alive>
</template>
<script setup lang="ts">
import HelloWorld from "../components/HelloWorld.vue";
import Herder from "../components/Herder.vue";
import Footer from "../components/Footer.vue";
import { ref,reactive,  markRaw } from "vue";
const count = ref(0);
const componentsList = reactive([
//reactive定义的是响应式数据,markRaw是去除控制台警告引入的组件不需要是响应式数据
  {
    name: "HelloWorld",
    id:123,
    com: markRaw(HelloWorld),
  },
  {
    name: "Herder",
    id:123,
    com: markRaw(Herder),
  },
  {
    name: "Footer",
    id:123,
    com: markRaw(Footer),
  }
]);
const DataTransferItemList = reactive({
  com: componentsList[0].com,
});
const emitChange = (item: any) => {
  DataTransferItemList.com = item.com;
}
</script>

异步组件=》提高性能
需要下载插件vueues
官网:https://vueuse.org/core/useIntersectionObserver/
使用场景一:按需加载组件,当用户访问到组件时在加载此组件
安装:

npm install @vueuse/core

组件应用:

<template>
  <Herder></Herder> 
  <Footer></Footer>
  <div ref="target">
    <HelloWorld v-if="targetIsVisible"></HelloWorld>
  </div>
</template>
<script setup>
import { ref,defineAsyncComponent} from 'vue';
import Herder from '../components/Herder.vue'
import Footer from '../components/Footer.vue'
//defineAsyncComponent 定义异步组件
const HelloWorld = defineAsyncComponent(() => import('../components/HelloWorld.vue'))
// import HelloWorld from '../components/HelloWorld.vue'

//引入vueuse插件
import { useIntersectionObserver } from '@vueuse/core'

const target = ref(null)
const targetIsVisible = ref(false)

const { stop } = useIntersectionObserver(
  target,
  ([{ isIntersecting }], observerElement) => {
    console.log(isIntersecting)//false
    targetIsVisible.value = isIntersecting
  },
)
</script>

使用场景二:分包处理
新增内置组件Suspense:用来在组件树中协调对异步依赖的处理。它让我们可以在组件树上层等待下层的多个嵌套异步依赖项解析完成,并可以在等待时渲染一个加载状态。
打包完成后,异步组件有单独的js文件,从主体js分包出来的

<template>
  <Suspense>
    <template #default>
      <Herder></Herder> 
    </template>
    <template #fallback>
      <div>Loading...</div>
    </template>
  </Suspense>
  
  <Footer></Footer>
  <div ref="target">
    <Suspense v-if="targetIsVisible">
      <template #default>
        <HelloWorld msg="Welcome to Your Vue.js App"></HelloWorld>
      </template>
      <template #fallback>
        <div>Loading...</div>
      </template>
    </Suspense>
  </div>
</template>
<script setup>
import { defineAsyncComponent} from 'vue';
import Footer from '../components/Footer.vue'
//defineAsyncComponent 定义异步组件
const Herder = defineAsyncComponent(() => import('../components/Herder.vue'))
const HelloWorld = defineAsyncComponent(() => import('../components/HelloWorld.vue'))

依赖注入provide()和inject()

//父组件
provide('state',state)
//子组件
<template>
  <div class="heder">
   <button @click="onClick">修改provide数据</button> 
  </div>
</template>
<script setup>
import { ref,inject } from "vue"
let count = inject('state')
console.log(count)
//修改provide依赖的数据
const onClick = () => {
  count.value = 20 + 1
}
</script>

pinia和vuex的区别

  1. pinia没有mutations,只有State,getters,actions
  2. pinia分模块不需要modules,vuex分模块需要modules
  3. pinia体积更小,性格更好
  4. pinia可以直接修改state数据,需要用storeToRefs(store)包裹后可以修改store数据
  5. 自动化代码拆分
  6. TypeScript更好的支持

官网:https://pinia.vuejs.org/
安装:

npm ininstall pinia
//main.js文件引入pinia
import { createPinia } from 'pinia'
createApp(App).use(router).use(createPinia()).mount('#app')

//文件src/store/index.js
import { defineStore } from "pinia";
export const useStore = defineStore("store", {
  state: () => ({
    count1: 0,
    count2: 10,
    count3: 100
  }),
  getters: {
//有缓存机制
    doubleCount: (state) => state.count * 2,
  },
  actions: {
  //actions支持同步和异步
    increment() {
      this.count++;
    },
  },
});
//组件应用pinia
template>
  <div>
    <span>{{ count1 }}</span>
    <p>{{ count2 }}</p>
    <span>{{ count3 }}</span>
     <button @click="storeChang">修改Store</button>
  </div>
</template>
<script setup>
import { useStore } from  '@/store/index.js'
//storeToRefs解构
import { storeToRefs } from 'pinia'
const store = useStore();
const {count1,count2,count3} = storeToRefs(store);
const storeChang = () => {
  //单个修改
  store.count1 = 100;
  store.count2 = 200;
  store.count3 = 300;
  //批量修改
  store.$patch(state=>{
    state.count1 ++,
    state.count2 = 200
  })

}

pinia的持久化存储
插件:pinia-plugin-persist
安装

npm install pinia-plugin-persist -save
//src/store/index.js
import { createPinia } from "pinia";
import piniaPersist from 'pinia-plugin-persist'

const store = createPinia()
store.use(piniaPersist)
export default store

//src/store/模块name.js
import { defineStore } from "pinia";


export const useStore = defineStore("store", {
  state: () => ({
    count1: 0,
    count2: 10,
    count3: 100
  }),
  getters: {
    doubleCount: (state) => state.count * 2,
  },
  actions: {
    increment() {
      this.count++;
    },
  },
  // 持久化配置
  persist: {
    enabled: true,
    stratgies: [
      {
        key: "user",
        storage: localStorage,
        paths: ["count1","count2"],
      }
    ],
    storage: localStorage,
    paths: ["count1", "count2"],
  },
});
  • 18
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值