通过看小满zs学习Vue3知识点,将知识点记录下来。
更新中,未学完
方便开发者快速开发
# NPM
$ npm install element-plus --save
# Yarn
$ yarn add element-plus
# pnpm
$ pnpm install element-plus
import { createApp } from 'vue'
import './assets/css/reset.less'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')
vue中的Scoped是通过在DOM结构以及css样式上加唯一不重复的标记:data-v-hash
,以保证唯一(由PostCSS转移实现),达到样式私有模块化。
Vue3推荐使用:deep(.el-input-inner){...}
来修改组件库的样式
默认情况下,作用域样式不会影响到渲染出来的内容,他们被认为是父组件所持有并传递进来的。解决方案::slotted(.a){...}
解决方案:global(.a){...}
<script setup lang="ts">
let valChangeStyle = ref({
color: "red",
background: "blue",
});
</script>
<template>
<div class="val">动态修改样式</div>
</template>
<style lang="less" scoped>
.val {
color: v-bind("valChangeStyle.color");
background-color: v-bind("valChangeStyle.background");
}
</style>
<script setup lang="ts">
const appCss = useCssModule("app");
// useCssModule可以帮助我们把样式名转为哈希值以保证样式的唯一性,在写render、ts的时候会好用一些。
console.log(appCss);
// { app: "_app_15pag_1", color: "_color_15pag_7", background: "_background_15pag_10" }
</script>
<template>
<div :class="[app.color, app.background]">动态修改样式</div>
</template>
<style lang="less" module="app">
.color {
color: green;
}
.background {
background-color: pink;
}
</style>
Tailwind Css是一个由Js编写的css框架,基于 PostCss 解析的。
目前我安装的tailwind是3.x版本
$ npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
$ npx tailwindcss init -p
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
theme: {
extend: {},
},
plugins: [],
};
/* index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
import './index.css'
简单来说,就是以视觉效果命名,一眼看上去就知道这个样式代表什么。
$ npm i -D unocss
在vite.config.ts中配置如下:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx';
import unoCss from 'unocss/vite'
import { presetIcons, presetAttributify, presetUno } from 'unocss'
export default defineConfig({
plugins: [unoCss({
// rules为二维数组,在rules中自定义规则,全局可用
rules: [
['flex', { display: 'flex' }],
['bg-black', { background: 'black' }],
// 动态原子化
[/^m-(\d+)$/, ([, d]) => ({ margin: `${Number(d) * 10}px` })], // m-1即margin: 10px
],
shortcuts: {
// 组合样式
block: ['flex', 'bg-black']
},
// presetIcons 预设图标
// presetAttributify 预设class 引入这个写样式可以写成
// presetUno 插件自带的预设类像使用tailwind一样 如bg-red-500
presets: [presetIcons(), presetAttributify(), presetUno()]
})],
})
在main.ts中配置如下:
import 'uno.css'
代码从上到下按顺序执行
所有的同步任务都是在主进程执行的形成一个执行栈,主线程之外,还存在一个"任务队列”,异步任务执行队列中先执行宏任务,然后清空当次宏任务中的所有微任务,然后进行下一个tick,如此形成循环。nextTick就是创建一个异步任务,等到同步任务执行完成后才执行。
同步进程有任务,先宏后微。同步完成到异步。
目前我安装的postcss-px-to-viewport是1.1.1版本
$ npm install postcss-px-to-viewport -D
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx';
import px2ViewPort from 'postcss-px-to-viewport'
import { fileURLToPath, URL } from 'url';
// https://vitejs.dev/config/
export default defineConfig({
css: {
postcss: {
plugins: [
px2ViewPort({
unitToConvert: 'px',//要转化的单位
viewportwidth: 750,//UI设计為的宽度
// 通常配置上面那两行就够了
unitPrecision: 6,//转换后的精度,即小数点位数
propList: ['*'], //指定转换的css属性的单位,*代表全部css属性的单位都进行转换
viewportUnit: 'vw',//指定需要传换成的视窗单位,默认vw
fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw
selectorBlackList: ['ignore-'],//指定不转换为视窗单位的英名,
minPixelValue: 1,//默认值1,小于或等于1px则不进行转换
mediaQuery: true,//是否在媒体查询的css代码中进行转换,默认false
replace: true, // 是否转换后直接更换属性值
landscape: false // 是否处理横屏情况
})
]
}
},
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
我先跳过。
$ npm install pinia
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
const app = createApp(App)
const store = createPinia()
app.use(store)
app.mount('#app')
Pinia抛弃了mutations状态,
// 命名空间枚举值
export const enum Names {
USERSTORE = 'USERSTORE'
}
import { defineStore } from "pinia";
// 导入命名空间
import { Names } from "./name-space";
// 定义初始化的值
export const userStore = defineStore(Names.USERSTORE, {
// state、getters 和 actions 并且可以安全地假设这些概念等同于组件中的“数据”、“计算”和“方法”。
state: () => {
return {
username: 'van'
}
}
})
<script setup lang="ts">
import { userStore } from "./store/index";
const user = userStore();
</script>
<template>
<div>状态:{{ user.username }}</div>
</template>
在Pinia中允许直接修改值,在Vuex不被允许。
<script setup lang="ts">
import { userStore } from "./store/index";
const user = userStore();
// 如何使用state?
// 1. 直接修改
// user.username + '123'
// 2. 通过patch+对象修改
// user.$patch({})
// 3. 通过patch+工厂函数修改,好处是在里面写逻辑
// user.$patch((state) => {
// state.username = "哥哥最爱穿丝袜啦";
// });
// 4. 使用user.$state修改会修改到整个对象
// user.$state = {
// username: "66666666666",
// };
// 5. 调用actions方法修改
// store/index.ts
// actions: {
// setUserName() {
// this.username = '9999999'
// }
// }
// 页面调用 user.setUserName()
</script>
<template>
<div>状态:{{ user.username }}</div>
</template>
<style lang="less" module="app">
html,
body,
#app {
height: 100%;
overflow: hidden;
}
</style>
和Vue3的toRefs用法差不多。
源码观看:
/**
* Creates an object of references with all the state, getters, and plugin-added
* state properties of the store. Similar to `toRefs()` but specifically
* designed for Pinia stores so methods and non reactive properties are
* completely ignored.
*
* @param store - store to extract the refs from
*/
function storeToRefs(store) {
// See https://github.com/vuejs/pinia/issues/852
// It's easier to just use toRefs() even if it includes more stuff
if (isVue2) {
// @ts-expect-error: toRefs include methods and others
return toRefs(store);
}
else {
store = toRaw(store);
const refs = {};
for (const key in store) {
const value = store[key];
if (isRef(value) || isReactive(value)) {
// @ts-expect-error: the key is state or getter
refs[key] =
// ---
toRef(store, key);
}
}
return refs;
}
}
原理:
store=toRaw(store)
toRef(store,key)
import { userStore } from "./store/index";
import { storeToRefs } from "pinia";
const user = userStore();
const { username } = storeToRefs(user);
在Pinia中的actions可以同步、异步修改state,而Vuex需要通过mutations。