组件、动画、脚手架
一、v-if和v-for的优先级
- v-for优先级高于v-if
例:
<div id="app">
<ul>
<!--
v-for和v-if一起使用的时候,v-for的优先级高
这个代码会先执行v-for,循环生成10个li标签
然后再执行v-if,删除后面的6个不满足条件的标签,性能不好
所有vue不建议v-for和v-if一起使用,如果真有这种业务需求,建议使用计算属性
-->
<!-- <li v-for="(item,index) in arr" :key="item" v-if="index < 4">{{item}}</li> -->
<li v-for="(item,index) in showArr" :key="item">{{item}}</li>
</ul>
</div>
<script>
new Vue({
el:"#app",
data:{
arr:[1,2,3,4,5,6,7,8,9,10]
},
methods:{},
computed:{
//通过计算属性,获取到想要的数据
showArr(){
return this.arr.slice(0,4)
}
}
})
</script>
二、动画
2、1 动画介绍
- 使用场景
1、v-if
2、v-show
3、路由切换
4、动态组件
- 动画的六个状态
进来之前:enter
进来过程:enter-active
进来完成:enter-to
离开之前:leave
离开过程:leave-active
离开完成:leave-to
2、2 内部动画
- 模板语法
<button @click=' isshow = !isshow '>切换</button>
<!-- 添加动画步骤
1.带添加动画的元素,在外面嵌套transition标签
2.在transition标签起名 name='名字' name='a'
3.定义6个状态
a-enter a-enter-active a-enter-to
-->
<transition name="a">
<div class="box" v-if="isshow"></div>
</transitio
- 定义六个状态
/* -------------进来的状态---------------- */
/* 进来之前:enter */
.a-enter {
left: -200px;
transform: scale(0.1, 0.1);
opacity: 0;
}
/* 进来过程:enter-active */
.a-enter-active {
transition: all 1s;
}
/* 进来完成:enter-to */
.a-enter-to {
left: 500px;
transform: scale(1, 1);
opacity: 1;
}
/* -----------------离开的状态------------- */
/* 离开之前:leave */
.a-leave {
left:500px;
transform: rotate(0deg);
opacity: 1;
}
/* 离开过程:leave-active */
.a-leave-active {
transition: all 1s;
}
/* 离开完成:leave-to */
.a-leave-to {
left: 1000px;
transform: rotate(720deg);
opacity: 0
}
2、3 第三方库
- 第三方库:animate.css
- 官方地址:https://animate.style/
- 下载
npm install animate.css --save
- 使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./vue.js"></script>
<link rel="stylesheet" href="./node_modules/animate.css/animate.css">
<style>
.box {
width: 200px;
height: 200px;
background: red;
/* position: absolute; */
/* left: 500px;
top: 100px; */
}
</style>
</head>
<body>
<div id="app">
<!--
1.下载 npm install animate.css --save
2.引入
<link rel="stylesheet" href="./node_modules/animate.css/animate.css">
3.给需要添加标签的元素,嵌套transition标签
4.设置属性
enter-active-class='进入的样式'
leave-active-class='离开的样式'
-->
<button @click=' isshow = !isshow '>切换</button>
<transition
enter-active-class="animate__animated animate__bounceIn"
leave-active-class="animate__animated animate__fadeOutLeft"
>
<div class="box" v-if="isshow"></div>
</transition>
</div>
<script>
new Vue({
el: "#app",
data: {
isshow: false
},
methods: {}
})
</script>
</body>
</html>
- 注意:不会同时使用进入和离开的状态,一般使用进入的那个状态
三、组件
- 组件:可复用的vue实例
3、1 注册组件
3.1.1局部注册
- 语法
new Vue({
components:{ //复数,可以创建多个组件
组件名称:{
template:"" //模板,
}
}
})
- 实例-局部注册组件
new Vue({
el:"#app",
data:{},
methods:{},
//1.注册组件-局部组件--只能在当前vue实例中使用
components:{
//组件名:{template:""}
navweb:{
template:"<div><h1>你好,我是网站导航</h1><h1>你好</h1></div>"
},
one:{
template:"<div>我是one组件</div>"
}
}
})
- 使用组件
<div id="app">
<!-- 2.使用组件 -->
<navweb></navweb>
<navweb></navweb>
<one></one>
<one></one>
</div>
3.1.2全局组件
- 语法
//一次只能注册一个,要放在实例前面
Vue.component("组件名称",{
template:""
})
- 实例
//80%局部组件,20%全局组件
//3.注册全局组件--所有的vue实例都可以使用
Vue.component('com',{
template:`
<ul>
<li>特色主题</li>
<li>行业频道</li>
<li>生活服务</li>
</ul>
`
})
- 使用全局组件
<div id="app2">
<h1>我是app2</h1>
<!-- 局部组件只能在对应的vue实例中使用 -->
<!-- <navweb></navweb> -->
<!-- 4.使用全局组件 -->
<com></com>
</div>
3.1.2组件的命名规则
- 命名规则
1.不能使用已经存在的标签命名,eg:div、p、span 、a、b....
2.不能使用已经存在的标签的大写命名,eg:DIV、P,SPAN ...
3.如果组件名中间包含了大写字母,调用的时候需要变成 【-小写】 烤串写法
第一个字母就是大写可以不写-
4.组件名称中包含一个大写字母,方便调用
3、2 template
- template 只能有一个根节点
vTwo:{
// 报错:Component template should contain exactly one root element
// 1.template只能有一个根节点
template:`<div><h1>this is two</h1></div>
<p>我是two组件的内容</p>
`
},
- 可以借助template标签书写template属性
<template id="three">
<div>
<h2>我是一个标题</h2>
<ul>
<li>列表</li>
<li>列表</li>
<li>列表</li>
</ul>
</div>
</template>
//2.可以借助template标签来书写template选项
vThree:{template:"#three"
}
3、3 data
- 组件中的data必须是一个函数
data(){
return {name:"妲己"}
}
- data为什么是一个函数
1、组件是复用,希望组件长一样,但是数据相互隔离的
2、如果data是一个对象的话,对象一个引用数据类型,那么所有的组件共用一套数据,就会出现一改全改的现象
3、如果data是一个函数返回一个对象的话,函数是一个作用域空间,每调用一次,就会生成一个新的作用空间,
里面有一个对象,这样的话数据都是隔离的
3、4 组件是可复用的vue实例
- 验证
1、组件没有el
2、data必须是一个函数,返回一个对象
3、其他的和vue实例一样
4、每调用一次组件,会是一个新的生命周期
v-if和v-show在组件上使用:v-if会引起生命周期的创建和销毁,v-show不会
5、一个组件只能使用自己的data,自己的子组件,自己的methods,computed,watch,filters
6、全局组件,所有vue实例都可以使用
- 代码案例一
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./vue.js"></script>
<style>
.box{
padding: 20px;
margin: 20px;
border: 1px solid red;
}
</style>
</head>
<body>
<div id="app">
<v-one></v-one>
<v-one></v-one>
<button @click="isshow = !isshow">开关</button>
<!--3. v-if和v-show作用在组件上的时候,v-if切换引起生命周期的重新执行,v-show不会 -->
<v-one v-if="isshow"></v-one>
</div>
<!-- 定义组件模板 -->
<template id="one">
<div class="box">
<p>姓名:{{name}}</p>
<button @click="change">修改名字</button>
</div>
</template>
<script>
new Vue({
el:"#app",
data:{
isshow:true
},
methods:{},
components:{
//1.组件是可复用的vue实例
//组件没有el,data必须是函数返回一个对象,其他的都和vue实例一样
vOne:{
template:"#one",
data(){
return {
name:"杨洋"
}
},
methods:{
change(){
this.name = "王楚然";
}
},
//2.生命周期,每调用一次组件,都会产生一个新的vue实例,都会走生命周期
mounted(){
console.log("挂载完成");
},
destroyed(){
console.log("卸载完成");
}
}
}
})
</script>
</body>
</html>
- 代码案例二:使用了组件嵌套
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./vue.js"></script>
<style>
.box{
padding: 20px;
margin: 20px;
border: 1px solid red;
}
</style>
</head>
<body>
<div id="app">
<v-one></v-one>
<v-two></v-two>
<web-nav></web-nav>
</div>
<!-- one组件-->
<template id="one">
<div class="box">
<p>this is one</p>
<p>姓名:{{name}}</p>
<!-- 使用嵌套组件 -->
<v-child></v-child>
<web-nav></web-nav>
</div>
</template>
<!-- two组件-->
<template id="two">
<div class="box">
<p>this is two</p>
<p>姓名:{{name}}</p>
<v-child></v-child>
<web-nav></web-nav>
</div>
</template>
<!-- 嵌套组件 -->
<template id="child">
<div class="box">
<h1>this is child</h1>
<web-nav></web-nav>
</div>
</template>
<!-- 全局组件 -->
<template id="nav">
<div class="box">
<ul>
<li>首页</li>
<li>列表页</li>
<li>详情页</li>
</ul>
</div>
</template>
<script>
// 2.定义全局组件--全局组件可以在所有vue实例中使用
Vue.component("webNav",{
template:"#nav"
})
new Vue({
el:"#app",
data:{
isshow:true
},
methods:{},
components:{
//讨论组件关系的时候,只有父子,非父子组件
//1.一个组件只能用自己东西(data,methods,computed,filters,components.....)
vOne:{
template:"#one",
data(){
return {
name:"杨洋"
}
},
components:{
vChild:{
template:"#child"
}
}
},
vTwo:{
template:"#two",
}
}
})
</script>
</body>
</html>
3、5 组件嵌套
- 嵌套
//注册
vOne:{
template: "#one",
components: {
vTwo: {
template: "#two"
}
}
}
- this的指向
四、脚手架
4、1 脚手架创建项目
- 脚手架------vue-cli
vue-cli是vue核心工具之一,通过命令快速搭建项目的基本骨架
- 官网地址 https://cli.vuejs.org/zh/
- 安装
npm i webpack -g :全局安装webpack
webpack -v: 查看webpack安装版本
npm install @vue/cli -g :全局安装vue脚手架
vue -v或者 vue --version:脚手架版本
- 脚手架创建项目
注意:创建项目的地方不有vue.js文件
vue create 项目名称(不要有中文,不要用驼峰,不要使用关键字)
- 启动
cd 项目目录
npm run serve
- 浏览器查看 http://localhost:8080/
4、2 项目目录
- 目录
vue.config.js (跨域代理)
README.md 阅读指南,有那些指令
package.json 依赖管理
package-lock.json 依赖管理
babel.config.js es6转es5配置文件
.gitignore 定义git的忽略文件
src 前端写代码的地方
--assets 静态资源文件 img css js font
--components 组件文件夹,一个.vue文件就是一个组件,一个组件包含三个部分
1.视图template html部分
2.逻辑代码script js部分
3.样式style css部分
--app.vue 根组件
--main.js 入口js文件,实例化vue的地方
public 共有文件
--favicon.ico 图标
--index.html 主html文件
node_modules 第三方包文件夹
4、3 初始化项目
- 删除assets,components文件夹中的文件
- 重置app.vue文件的内容
<template>
</template>
<script>
export default {
}
</script>
<style>
</style>