Skip to content

Front End: Vue3, Vite, Css...

Directus APP使用VUE 3, Typescript,用Vite构建。 本文记录在评估Directus APP过程中了解到的前端相关知识。

1. vite

构建工具,类似webpack。

1.1. 原理

使用了浏览器的ES6模块加载功能,所以前端可以按需加载JS模块。开发过程中不需要打包了。

html
\<script type="module" src="./foo.js">\</script>

以上 module类型加载的 foo.js 中可以再import其它的模块,也可以export。浏览器认识js中的import和export命令,会按需向后台发请求加载。

1.2. 应用

在vite.config.ts中配置开发服务器,例如下面监听8080端口,API请求发送到8055端口。

javascript
	server: {
		port: 8080,
		proxy: {
			'^/(?!admin)': {
				target: process.env.API_URL ? process.env.API_URL : 'http://localhost:8055/',
				changeOrigin: true,
			},
		},
		fs: {
			allow: [searchForWorkspaceRoot(process.cwd()), '/admin/'],
		},
	},

2. vue

把js/css/html组织起来的方式。 运行环境(js库)提供数据绑定,改状态就会更新显示,方便JS更新页面。

2.1. 基本概念

  • data 一个函数,返回组件实例的数据对象。
  • props 一个数组,或者对象。是父组件调用此组件时候的可配置参数。

data和props都可以在template中访问,区别是

  1. data不是通过父组件传递的,是子组件私有的,是可读可写的。
  2. props中的数据,都是通过父组件传递给子组件的,是只读的。 data存储组件的状态, 没有data的组件就是无状态组件。
  • mixin, 为了DRY,为了减少重复,把组建脚本部分相同的地方(data,props,method...) 抽离出来,单独放到一个对象里面。 然后在组件中mixin进去。
  • setup函数, 用来替代mixin,实现Composition API。 其输入为props, context,输出是一个对象。对象的所有属性都可以在组件中访问。

2.2. 组件生命周期

picture 10

3. html

3.1. data-自定义属性

在VUE生成的html中,看到很多data-v-xxxx 之类的 div, 这些是scoped css产生的。 相同的组件会产生相同的data-v数值。

picture 11

The data-* attribute adds custom information to a <div> element. The * part is replaced with a lowercase string, such as data-id, data-source, data-category, etc. An <div> element can have any number of data-* attributes, each with their own name.

html
\<div id='strawberry-plant' data-fruit='12'>\</div>

\<script>
// 'Getting' data-attributes using getAttribute
var plant = document.getElementById('strawberry-plant');
var fruitCount = plant.getAttribute('data-fruit'); // fruitCount = '12'

// 'Setting' data-attributes using setAttribute
plant.setAttribute('data-fruit','7'); // Pesky birds
\</script>

这种自定义属性是HTML5标准中定义的,可以在JS中访问。

4. Css

4.1. 基本概念

基本格式是

javascript
p {
  font-family: verdana;
  font-size: 20px;
}

其中p是选择器, 后面的大括号是一个属性和值的列表。

选择器通过一定的规则选择html元素。基本的有:

  • 所有元素: 星号
  • 标签名称: body,a,p,h2...
  • class 用点号
  • id 用井号

还有一些组合的:

  1. 多元素选择器: E, F 把多个选择器用逗号隔开
  2. 后代元素选择器: E F, 匹配选择器E里面所有的选择器F。 例如 .box h2, class box元素内部的所有h2
  3. 子元素选择器: E > F, 和上面区别是只匹配直接子元素。 只匹配一级。 后代匹配多级(所有后代)。
  4. 相邻元素选择器: E + F, E和F是兄弟关系, 并且紧挨着,这时候匹配F。

属性选择器:用中括号,根据元素的属性名/属性值选择。

继承性: 对外层元素的样式会自动继承给内层元素。 如果内层元素样式和外层冲突,则内层起作用。

定位:

  • fixed 固定,相对于浏览器窗口的位置。后面会跟着坐标。不占用标准文档流空间,压盖标准文档流。
  • relative 相对,相对于原来的位置
  • absolute 绝对,坐标是相对于设置过定位的祖先元素。如果祖先都没设置,就和fixed一样了。不占用标准文档流空间,会压盖标准文档流。

4.2. scss

sass的一个新版本, 是生成css的语言。类似css3,增加了变量,继承等。方便生成css。

参见 https://www.jianshu.com/p/6bb174c79172 其中英镑(and)符号是父元素选择器。

4.3. directus中的应用

以下是主屏幕左侧导航栏 的CSS, 在手机屏幕下,默认不显示,只有点左上角菜单才显示。在PC上,没有菜单按钮,默认显示。看实现,最左边的控件,向左挪动100%,就移除屏幕,实现了隐藏。 最右边的也一样,向右移动100%实现隐藏。

scss
#navigation {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 50;
    display: flex;
    height: 100%;
    font-size: 0;
    transform: translateX(-100%);   //默认不显示
    transition: transform var(--slow) var(--transition);

    &.is-open {
        transform: translateX(0);   //显示
    }

    &:not(.is-open) {
        .module-nav-resize-handle {
            display: none;
        }
    }

    .module-nav {
        position: relative;
        display: inline-block;
        width: 220px;
        height: 100%;
        font-size: 1rem;
        background-color: var(--background-normal);

        &-content {
            --v-list-item-background-color-hover: var(--background-normal-alt);
            --v-list-item-background-color-active: var(--background-normal-alt);

            height: calc(100% - 64px);
            overflow-x: hidden;
            overflow-y: auto;
        }
    }

    .module-nav-resize-handle {
        position: absolute;
        top: 0;
        right: -2px;
        bottom: 0;
        width: 4px;
        background-color: var(--primary);
        cursor: ew-resize;
        opacity: 0;
        transition: opacity var(--fast) var(--transition);
        transition-delay: 0;
        user-select: none;
        touch-action: none;

        &:hover,
        &:active {
            opacity: 1;
        }

        &.active {
            transition-delay: var(--slow);
        }
    }

    @media (min-width: 960px) {
        position: relative;
        transform: none;    //大于 960px时候就会显示

        &:not(.is-open) {
            .module-nav-resize-handle {
                display: block;
            }
        }
    }
}

5. 参考