大家好,从今天开始,会每天分享vue学习的知识点,一起加油~
Vue选项(会继续更新...)
- el 模板
- data数据
- methods方法
- directives指令
- filters过滤
- watch监听
- computed计算
- props属性
- created 创建完毕
- template 模板
- components组件
自定义指令(directives)
作用:操作dom,实例化第三方基于dom的插件
- 当被插入时候inserted
- 只绑定一次 bind
- 更新时候运行 update
课堂案例
<body>
<div id="app">
<h1>自定义指令</h1>
<input type="text" v-focus="flag">
<button @click.prevent.stop="flag=!flag">改变</button>
</div>
<script src="../js/vue.js"></script>
<script>
new Vue({
el: "#app",
data() {
return {
flag: true
}
},
directives: {
//自己定义v-focus 指令
"focus": {
//当被插入时候inserted
//只绑定一次 bind
//更新时候运行 updatee
update(el, binding) {
//el 指令对应的节点
//binding.value 指令的值
console.log(el, binding);
if (binding.value) {
//让指令对应的节点获取焦点
el.focus()
}
}
}
}
//01操作dom
//02执行第三方基于dom操作的插件
})
</script>
</body>
代码运行结果
过滤(管道)filters
vue过滤器就是用来过滤模型数据,在显示之前进行数据处理和筛选。
语法:{{ data | filter1(参数) | filter2(参数) }}
课堂小案例
<body>
<div id="app">
<h1>过滤或管道 </h1>
<p>{{100}}--{{100.00}}</p>
<p>{{3.1415926}}--{{3.14}}</p>
<p>{{3.1415926|fix}}</p>
<p>{{3.15926927|fix(5)}}</p>
<p>{{1000|fix(5)}}</p>
<hr>
<p>{{'2022-09-20'}}-->{{'2天前'}}</p>
<p>{{'2021-09-20'|date}}</p>
<p>{{'2020-09-20'|date}}</p>
<p>{{'2021-12-30'|date}}</p>
</div>
<script src="../js/vue.js"></script>
<script>
new Vue({
el: "#app",
filters: {
//val是| 左边的值
fix(val, len = 2) {
//返回要显示的内容
return Number(val).toFixed(len)
},
date(val) {
//获取1970.1.1到当前的毫秒数
var time1 = new Date(val).getTime()
var time2 = new Date().getTime()
//获取毫秒差
var dis = time2 - time1
//转换为天数
var day = Math.round(dis/1000/60/60/24)
//返回
return day+"天前"
}
}
})
</script>
</body>
运行结果
组件components
01组件概念
组件的组织:通常一个应用会以一棵嵌套的组件树的形式来组织
组件就是定义好的一功能模块
建议:多用props,少在组件中使用data(降低组件的耦合性)
02组件作用:
- 组件是vue的一个重要的特点
- 实现多个写作开发
- 通过组件划分降低开发的难度
- 实现复用,降低重复劳动
03定义与使用
1.定义
注意:template有且只有一个根节点
const steper = {
`
<span></span>
`
}
2.在父组件中注册
components:{steper:steper}
3.在组件的模板中使用
<steper></steper>
04传参
父传子
父:<model :visible="visible"></model>
子 props:{visible:{type:Boolean,default:false}}
子使用
注意:vue是单向数据流,父组件传递给子组件的props是只读(不能修改)this.value
子传父
子 this.$emit("update:visible",false)
父 监听事件,修改值
<model @update:visible="visible=$event"></model>
05 课堂案例
注意:(以下代码是组件.html 的 代码)
<body>
<div id="app">
<h1>组件传参</h1>
<p>父传子</p>
<step v-model="r"></step> <br>
<step :value="r" @input="r=$event" :min="100" :max="500" :step="10"></step><br>
<input type="range" min="100" max="500" v-model.lazy.number="r">
<div :style="{'border':'2px solid #ccc','borderRadius':r+'px',width:r+'px',height:r+'px'}"></div>
</div>
<script src="../js/vue.js"></script>
<script src="./components/step.js"></script>
<script>
new Vue({
el: "#app",
//02 注册组件
components: { step },
data() {
return {
r: 100,
}
}
})
//父传子props
//value min max step
//子传父 事件emit
//input事件
</script>
</body>
以下代码是文件夹compontents 的 step.js 的代码
//01 定义组件
var step = {
template: `
<span>
<input type="text" v-model.lazy.number="count">
<button @click="count+=step" :disabled="count>=max">+</button>
<button @click="count-=step" :disabled="count<=min">-</button>
</span>`,
props: {
//props 接收父组件传递过来的参数
value: {
// 参数名称value
type: Number,
default: 1, //默认值是1 如果不传value的值是1
},
//接收父组件传递过来参数最大值,最小值,步进值
min: {
type: Number,
default: 1,
},
max: {
type: Number,
default: 999,
},
step: {
type: Number,
default: 1,
},
},
data() {
return {
count: this.value, //count的默认值是父组件传过来的参数value
};
},
watch: {
count: {
//子传父,通过emit 发送事件
handler() {
//限定最大值,最小值
if (this.count >= this.max) {
this.count = this.max;
}
if (this.count <= this.min) {
this.count = this.min;
}
this.$emit("input", this.count);
},
deep: true,
},
value: {
handler() {
//监听value值得变化更新count(可选)
this.count = this.value;
},
},
},
};
//为什么不直接使用this.value 和input框绑定
//答:父组件传到子组件的参数必须是只读
//当count 的数据发生变化的时候通知父组件更新数据
运行结果
插槽
组件的嵌套内容
//父组件
<model>
<input>
<button>确定</button>
</model>
//子组件在模板中使用
template:`
<div>
<slot></slot>
</div>
`
课堂案例
01 组件.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="../js/vue.js"></script>
<script src="./model/index.js"></script>
<link rel="stylesheet" href="./model/index.css" />
<style>
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="app">
<h1>组件的插槽</h1>
<button @click="visible=true">显示弹框</button>
<!-- 使用组件 -->
<!-- 父组件监听update:visble事件 修改visible的值为事件的参数$event(false) -->
<!-- <model :visible.sync="visible"> -->
<model :visible="visible" @update:visible="visible=$event">
<div>
俺们是弹框的内容插槽
<p>其他内容也可以</p>
</div>
</model>
</div>
<script>
//思路与目标
//1.把model 单独成为一个js文件
//2.model的css(弹框样式)
//3.控制弹框显示与隐藏(父传子,关闭:子传父)
new Vue({
el: "#app",
components: {
model,
},
data() {
return {
visible:false,//控制组件是否显示
};
},
});
</script>
</body>
</html>
02 index.js 文件
//01定义组件
var model = {
template: `
<div class="model" v-if="visible">
<div class="model-content">
<h3 class="model-title">我是弹框标题
<button class="close" @click="$emit('update:visible',false)">x</button></h3>
<div class="model-body">
<slot></slot>
</div>
</div>
</div>
`,
props: {
visible: {
type: Boolean,
default: false,
},
},
};
代码运行
具名插槽
当一个组件中有很多地方要使用插槽时,就用具名插槽来区分
子组件 <slot name="插槽内容"></slot>
父组件 <组件名><template v-slot:插槽名字></template></组件名>
简写<template #插槽名字></template>
案例代码
<!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="../js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>具名插槽(起名字的多个插槽)</h1>
<p>$100🔪</p>
<p>¥100⚪</p>
<hr />
<price>
<template v-slot:pre>¥</template>
<template v-slot:next>元</template>
</price>
<hr>
<price>
<template #next>🔪</template>
<template #pre>$</template>
</price>
</div>
<script>
const price = {
template: `
<span>
<slot name="pre"></slot>
100
<slot name="next"></slot>
</span>
`,
};
new Vue({
el: "#app",
components: {
price,
},
data() {
return {};
},
});
</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="../js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>插槽的作用域(父组件自定义渲染子组件局部内容)</h1>
<p>scope就是作用域包含的数据</p>
<lis :list="list">
<template v-slot:default="scope">
💖<span>{{scope.item}}</span> <button>x</button>
</template>
</lis>
<lis :list="list">
<template v-slot="scope">
<!-- 默认插槽可以省略default -->
😊<span>{{scope.item}}</span> <button>x</button>
</template>
</lis>
<lis :list="list">
<template slot-scope="scope">
💎<span>{{scope.item}}</span> <button>x</button>
</template>
</lis>
</div>
<script>
/* 目标:定义一个列表自己list */
const lis = {
template: `
<div>
<div v-for="item in list" :key="item">
<slot :item="item"></slot>
</div>
</div>
`,
props: {
list: { type: Array },
},
};
new Vue({
el: "#app",
components: {
lis,
},
data() {
return {
list: ["vue", "react", "angular"],
};
},
});
</script>
</body>
</html>
运行结果
动画
两个状态的过渡
transition 单个动画元素
- v-enter-active进入整个状态
- v-enter 进入开始
- v-enter-to 进入结束
- v-leave-active离开整个状态
- v-leave 离开开始
- v-leave-to 离开结束
方法1
方法2
方法3
今天的分享就结束了~