Vite创建的项目中使用less
- 直接安装less
npm install less -D
- 在组件style节点这样声明即可:
<style lang="less">
····样式
</style>
注册全局组件
import { createApp } from 'vue'
import App from './App.vue'
import './index.css'
import Swiper from './components/globalComponents/Swiper.vue'
const app = createApp(App)
// 此处Swiper的name 就是定义组件时的name属性
app.component(Swiper.name, Swiper)
app.mount('#app')
绑定class
以对象语法绑定class
<div>
<h3 :class="{ italic: italicVariable, delete: deleteVariable }">
我是一个测试class绑定的元素!
</h3>
<button @click="italicVariable = !italicVariable">切换斜体</button>
<button @click="deleteVariable = !deleteVariable">切换删除</button>
</div>
以对象语法绑定style
// fontSize的值也可以使用data中的变量
<h3 :style="{ fontSize: '23px' }">我是一个测试style绑定的元素!</h3>
props的自定义用法
- 自定义验证的方法
props: {
status: {
//自定义验证方法, 返回true表示验证通过
validator(val) {
console.log(val)
return ['success', 'warning', 'error'].indexOf(val) > -1
},
},
}
- 用ts验证,并且设置默认值
import { defineProps, withDefaults } from 'vue'
import type { PersionsList } from '@/types/index'
const prosp = withDefaults(defineProps<{ list?: PersionsList }>(), {
list: () => [{
id: '123',
name: 'def',
age: 90
}]
})
自定义组件实现v-model
实现方式1
父组件
<fnts-swiper v-model:number="count"></fnts-swiper>
setup() {
const count = ref(0)
return {
count,
}
}
子组件
<button @click="addCount">count++</button>
props: {
number: {
type: Number,
required: true,
},
},
setup(props, context) {
const addCount = () => {
context.emit('update:number', props.number + 1)
}
}
实现方式2
父组件中
<TodoButton v-model="val"></TodoButton>
子组件中
props: {
modelValue: {
type: Number,
required: true,
default() {
return 0
},
},
},
setup(props, context) {
const inputVal = (val) => {
context.emit('update:modelValue', val)
}
},
vue中组件的名字
如果在组件中默认导出了name,则根据导出的name定义名字
<script lang="ts">
export default {
name: 'HelloWorld'
}
</script>
如果没有导出则根据文件名定义组件名
为了不用写冗余的代码定义组件的名字,
- 可以安装一个插件
npm i vite-plugin-vue-setup-extend -D - 在vite.config.ts引入插件
import VueSetupExtend from 'vite-plugin-vue-setup-extend' - 在plugins中调用插件
plugins: [
vue(),
VueSetupExtend()
],
问题:在使用vite-plugin-vue-setup-extend 0.4.0及以前版本时,会有个问题:如果script标签没内容,即使给script标签添加上name属性,其在vue-devtools内也不会生效。
解决办法:不要让script标签内空着,例如:加行注释
<script lang="ts" setup name="Ceshi">
// 注释
</script>
toRefs作用
由reactive定义的对象可以使用toRefs进行解构赋值操作,并且解构后的属性和reactive声明的对象有关联,当改变解构后属性的值时,原reactive声明的对象属性也会同时发生改变
toRef作用
toRefs可以同时将多个reactive定义的对象的属性进行解构为RefImpl对象,但是toRef一次只能将一个属性变为RefImpl对象
watch 函数
watch监视ref定义的基本类型数据,以及解除监视
watch监视ref定义的引用类型数据
watch:监视【reactive】定义的【引用类型】数据,且默认开启深度监视
watch:监视【ref】或【reactive】定义的【对象类型】数据中的某个属性
- 若该属性值不是【对象类型】,需要写成函数形式。
- 若该属性值是【对象类型】,建议写成getter函数并配置deep:true. 因为如果不写成getter函数,则无法监听整个对象的改变。如果不写deep:true则无法监听【基本类型】数据的改变
watch:同时监视多个属性
vue3 父子组件生命周期狗子的执行顺序
创建时:
- 父组件 -- setup
- 父组件 -- onBeforeMount
- 子组件 -- setup
- 子组件 -- onBeforeMount
- 子组件 -- onMounted
- 父组件 -- onMounted
卸载时
- 父组件 -- onBeforeUnmount
- 子组件 -- onBeforeUnmount
- 子组件 -- onUnmounted
- 父组件 -- onUnmounted
vue-router
- 路由切换时,视觉效果上“消失”了的路由组件,默认是被卸载掉的,需要的时候再去挂载
路由的工作模式
- history 模式
优点: URL更加美观,不带有#,更接近传统网站的URL。 缺点:后期项目上线,需要服务端配合处理路径问题,否则刷新会有404错误。
const router = createRouter({
history:createWebHistory(),
/*******/
})
- hash模式
优点:兼容性更好,因为不需要服务器端处理路径。 缺点:URL带有#不太美观,且在SEO优化方面相对较差
const router = createRouter({
history:createWebHashHistory(),
/*******/
})
路由的传参方式
第一种传参以及如何接收参数 query
// 传递的参数
<template>
<RouterLink :to="`/news/detail?id=${item.id}&title=${item.title}&content=${item.content}`">{{ item.title }}
</RouterLink>
</template>
路由配置不用改变
// 接收参数
import { useRoute } from 'vue-router';
const route = useRoute();
第二种传参以及如何接收参数 query
// 传递的参数
<RouterLink :to="{
path: '/news/detail',
query: {
id: item.id,
title: item.title,
content: item.content
}
}">{{ item.title }}
</RouterLink>
路由配置不用改变
接收参数参考第一种(与第一种一样)
第三种传参以及如何接收参数 params
- 传递参数
<RouterLink :to="`/news/detail/${item.id}/${item.title}/${item.content}`">{{ item.title }}
</RouterLink>
- 配置路由
{
path: '/news',
component: News,
redirect: '/news/detail/default/default/default',
children: [
{
path: 'detail/:id/:title/:content',
component: Detail
}
]
}
- 接收参数
import { useRoute } from 'vue-router';
const route = useRoute();
console.log(route.params)
第四种传参以及如何接收参数 params
- 传递参数
to使用对象形式传递params参数时只能使用name, 不可使用path
<RouterLink :to="{
name:'detail',
params:{
id:item.id,
title:item.title,
content:item.content
}
}">{{ item.title }}
</RouterLink>
- 配置路由
{
path: '/news',
component: News,
redirect: '/news/detail',
children: [
{
name: 'detail',
// 问号可以限制必要性
path: 'detail/:id?/:title?/:content?',
component: Detail
}
]
},
- 接收参数
import { useRoute } from 'vue-router';
const route = useRoute();
console.log(route.params)
路由的props配置
第一种 props:true; 处理params参数为props
- 传递参数
<RouterLink :to="{
name:'detail',
params:{
id:item.id,
title:item.title,
content:item.content
}
}">{{ item.title }}
</RouterLink>
- 配置路由
{
path: '/news',
component: News,
redirect: '/news/detail',
children: [
{
name: 'detail',
// 问号可以限制必要性
path: 'detail/:id?/:title?/:content?',
component: Detail,
props:true
}
]
},
- 接收参数
defineProps(['id', 'title', 'content'])
第二种 处理query 参数为props
- 传递参数
<RouterLink :to="{
path: '/news/detail',
query: {
id: item.id,
title: item.title,
content: item.content
}
}">{{ item.title }}
</RouterLink>
- 配置路由
{
path: '/news',
component: News,
redirect: '/news/detail',
children: [
{
name: 'detail',
path: 'detail',
component: Detail,
props(route) {
return route.query
}
}
]
},
- 接收参数
defineProps(['id', 'title', 'content'])
编程式路由导航
push的参数同RouterLInk标签的to
import { useRouter } from 'vue-router'
const router = useRouter();
router.push({
path: '/news/detail',
})
Pinia
- 在main.js中
import {createPinia} from 'pinia'
const pinia = createPinia();
app.use(pinia);
- 创建store文件夹,以及新建对应文件 ··· import { defineStore } from 'pinia' import { ref } from 'vue'
export const useCountStore = defineStore('count', () => { const sum = ref(0); return { sum } }) ··· 3. 使用store
import { useCountStore } from '@/store/count'
const countStore = useCountStore();
const { sum } = toRefs(countStore);
mitt
- 创建mitt
import mitt from 'mitt';
const emitter = mitt();
export default emitter
- 订阅事件
import emitter from '@/utils/mitt';
const toy = ref();
emitter.on('send-toy', (val) => {
console.log('val',val)
toy.value = val
})
onUnmounted(() => {
emitter.off('send-toy')
})
- 发布事件
import emitter from '@/utils/mitt';
const toy = ref('奥特曼')
onMounted(() => {
emitter.emit('send-toy', toy.value)
})
customRef
import { customRef } from 'vue'
export const useCustomerRef = (val: string | number, duration?: number) => {
let timer: any;
const refVal = customRef((track, tigger) => {
return {
get() {
track();
return val;
},
set(newVal) {
//此处写要处理的逻辑
clearInterval(timer);
timer = setTimeout(() => {
val = newVal;
tigger();
}, duration)
}
}
})
return refVal
}