知识点
1.全局样式 在vue中想使用一些全局样式,只需要在main.js导入的文件就可以了。
main.js导入global.less 就可以了
// 入口文件
import Vue from "vue";
import App from "./App.vue";
import "./styles/global.less";
new Vue({
render: (h) => h(App),
}).$mount("#app");
var.less
@import "./var.less";
html {
color: @words;
font-family: "-apple-system", "BlinkMacSystemFont", "Roboto", "Helvetica Neue",
"微软雅黑", sans-serif;
overflow: hidden;
}
body {
overflow: hidden;
margin: 0;
}
a {
color: inherit;
text-decoration: none;
&:hover {
color: @primary;
}
}
var.less
@danger: #cc3600; // 危险、错误
@primary: #6b9eee; // 主色调、链接
@words: #373737; // 大部分文字、深色文字
@lightWords: #999; // 少部分文字、浅色文字
@warn: #dc6a12; // 警告
@success: #7ebf50; // 成功
@gray: #b4b8bc; // 灰色
@dark: #202020; // 深色
2.v-if 和 v-show
面试题:v-if 和 v-show 有什么区别?
1.v-if能够控制是否生成vnode,也就间接控制了是否生成对应的dom。当v-if为true时,会生成对应的vnode,并生成对应的dom元素;当其为false时,不会生成对应的vnode,自然不会生成任何的dom元素。
2.v-show始终会生成vnode,也就间接导致了始终生成dom。它只是控制dom的display属性,当v-show为true时,不做任何处理;当其为false时,生成的dom的display属性为none。
3.使用v-if可以有效的减少树的节点和渲染量,但也会导致树的不稳定;而使用v-show可以保持树的稳定,但不能减少树的节点和渲染量。
因此,在实际开发中,显示状态变化频繁的情况下应该使用v-show,以保持树的稳定;显示状态变化较少时应该使用v-if,以减少树的节点和渲染量。
变化频繁用v-show,变化少用v-if.
APP.vue Pager传入total,current两个属性,注册了
@事件 = "js表达式"。vue 中子组件不能改变从外部传入的数据,要想改变,需要先通过事件传入到父组件,在数据的源头进行更改,或其他操作。iOS可以从Block,或者代理把事件传递出去,vue是通过子组件的事件传递出来。
<template>
<div>
<h1>App组件</h1>
<Pager
:total="total"
:current="current"
@pageChange="handlePageChange($event)"
/>
</div>
</template>
<script>
import Pager from "./components/Pager";
export default {
components: {
Pager,
},
data() {
return {
current: 1,
total: 302,
};
},
methods: {
handlePageChange(newPage) {
this.current = newPage;
console.log("加载当前页数据");
},
},
};
</script>
<style scoped></style>
Pager.vue
<template>
<!-- 只有总页数大于1时才显示 -->
<div class="pager-container" v-if="pageNumber > 1">
<a @click="handleClick(1)" :class="{ disabled: current === 1 }">
|<<
</a>
<a @click="handleClick(current - 1)" :class="{ disabled: current === 1 }">
<<
</a>
<a
@click="handleClick(n)"
v-for="(n, i) in numbers"
:key="i"
:class="{ active: n === current }"
>
{{ n }}
</a>
<a
@click="handleClick(current + 1)"
:class="{ disabled: current === pageNumber }"
>
>>
</a>
<a
@click="handleClick(pageNumber)"
:class="{ disabled: current === pageNumber }"
>
>>|
</a>
</div>
</template>
<style lang="less" scoped>
@import "~@/styles/var.less";
.pager-container {
display: flex;
justify-content: center;
margin: 20px 0;
a {
color: @primary;
margin: 0 6px;
cursor: pointer;
&.disabled {
color: @lightWords;
cursor: not-allowed;
}
&.active {
color: @words;
font-weight: bold;
cursor: text;
}
}
}
</style>
<script>
export default {
props: {
current: {
type: Number,
default: 1,
},
total: {
type: Number,
default: 0,
},
limit: {
type: Number,
default: 10,
},
visibleNumber: {
type: Number,
default: 10,
},
},
computed: {
// 总页数
pageNumber() {
return Math.ceil(this.total / this.limit);
},
// 得到显示的最小数字
visibleMin() {
let min = this.current - Math.floor(this.visibleNumber / 2);
if (min < 1) {
min = 1;
}
return min;
},
visibleMax() {
let max = this.visibleMin + this.visibleNumber - 1;
if (max > this.pageNumber) {
max = this.pageNumber;
}
return max;
},
numbers() {
let nums = [];
for (let i = this.visibleMin; i <= this.visibleMax; i++) {
nums.push(i);
}
return nums;
},
},
methods: {
handleClick(newPage) {
if (newPage < 1) {
newPage = 1;
}
if (newPage > this.pageNumber) {
newPage = this.pageNumber;
}
if (newPage === this.current) {
return;
}
// 抛出一个事件
this.$emit("pageChange", newPage);
},
},
};
</script>
1.在组件开发的时候,一般是在组件内部放一个容器div,div的类名一般是 "组件名-container",这是习惯做法
2.v-if,这里只在开始的时候判断pageNumber是否有,更改不频繁,用v-if,< 代表是左箭头
3.class绑定的是一个对象类型,对象类型里面可以按 {a样式:true,b样式:true, c样式:flase}就代表 a样式,b样式生效,c样式不生效。 :class="{ disabled: current === 1 } 代表current 为1的时候disabled生效。
- 分析一下这一句,v-for 中n,和序号i不轮写前写后,当前这一句都能用,key这里不能绑定i序号来提高效率,:class="{ active: n === current } 仍然是如果当前的n===current的时候active样式生效。 {{ n }} 是大胡子语法。
<a
@click="handleClick(n)"
v-for="(n, i) in numbers"
:key="i"
:class="{ active: n === current }"
>
{{ n }}
</a>
-
<style lang="less" scoped>lang="less代表里面写的是less代码,less里面可以定义变量。 -
script里面的代码 props代表父组件传进来的属性,type定义类型,default 代表默认值。
7.computed里面是计算属性, pageNumber()在computed是带括号写的,但是在用的时候是直接用pageNumber就可以了。、
8.methods 里面定义的是方法, this.$emit("pageChange", newPage);就是为了因为数据是单项数据流,不能直接修改,需要抛出事件,让父组件去修改。
v-if 多个组件
<template>
<div class="user-name">
<span v-if="status === 'loading'">loading...</span>
<template v-else-if="status === 'login'">
<router-link to="/user">{{ user.name }}</router-link>
<a href="" @click.prevent="handleLoginOut">退出</a>
</template>
<router-link v-else to="/login" exact-path>Login</router-link>
</div>
</template>
由于v-if 只能包一个组件,如果两个组件都在一个逻辑判断里面,可以使用template 来包一下。
3.组件事件
抛出事件:子组件在某个时候发生了一件事,但自身无法处理,于是通过事件的方式通知父组件处理
事件参数:子组件抛出事件时,传递给父组件的数据
注册事件:父组件申明,当子组件发生某件事的时候,自身将做出一些处理
4.组件文档说明
属性
| 属性名 | 含义 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
| current | 当前页码 | Number | 否 | 1 |
| total | 总数据量 | Number | 否 | 0 |
| limit | 页容量 | Number | 否 | 10 |
| visibleNumber | 可见页码数 | Number | 否 | 10 |
事件
| 事件名 | 含义 | 事件参数 | 参数类型 |
|---|---|---|---|
| pageChange | 页码变化 | 新的页码 | Number |
如何使用组件?
编写组件说明文档
./src/components/README.md
如何测试组件效果?
1.新建一个和组件同名的文件夹,然后在文件夹里面放一个index.vue,然后在vue中放组件的代码.再新建一个test.vue,然后像app.vue中使用这个组件。
test.vue中的代码
<template>
<div>
<Pager
:total="total"
:current="current"
@pageChange="handlePageChange($event)"
/>
</div>
</template>
<script>
import Pager from "./";
export default {
components: {
Pager,
},
data() {
return {
current: 1,
total: 302,
};
},
methods: {
handlePageChange(newPage) {
this.current = newPage;
console.log("加载当前页数据");
},
},
};
2.在使用导入的时候只需要按下面的方式就可以,webpack会自动导入的。
3.在 cli.vuejs.org/zh/guide/pr… 文档下安装
npm install -g @vue/cli-service-global
然后执行 vue serve ./src/test.vue 就可以测试某个组件。
4.如果觉得上面的命令长度太长,可以在package.json中加上下面的代码,测试的时候就可以直接使用 npm run test:Pager来代替上面长的命令。
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"test:Pager": "vue serve ./src/components/Pager/test.vue",
"test:Avatar": "vue serve ./src/components/Avatar/test.vue",
"test:Icon": "vue serve ./src/components/Icon/test.vue"
},