《web前端全栈成长计划》Vue第一章学习笔记(下)
【摘要】 web前端全站成长计划第三阶段vue课程第一章的学习笔记(下)
10 vue List搜索和排序
10.1 代码和笔记
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>06_列表渲染_过滤与排序</title>
</head>
<body>
<!--
1. 列表过滤
2. 列表排序
-->
<div id="demo">
<input type="text" v-model="searchName">
<ul>
<!-- filterpersons是persons数组过滤后的结果,是根据person和searchName计算出来的,
所以需要使用计算属性 computed
-->
<li v-for="(p, index) in filterPersons" :key="index">
{{index}}--{{p.name}}--{{p.age}}
</li>
</ul>
<div>
<button @click="setOrderType(2)">年龄升序</button>
<button @click="setOrderType(1)">年龄降序</button>
<button @click="setOrderType(0)">原本顺序</button>
</div>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#demo',
data: {
searchName: '', //搜素栏的值
orderType: 0, // 0代表不排序, 1代表降序, 2代表升序
persons: [
{name: 'Tom', age:18},
{name: 'Jack', age:17},
{name: 'Bob', age:19},
{name: 'Mary', age:16}
]
},
computed: {
filterPersons () {
// debugger
// 取出相关数据,一旦以下三个内容发生变化,就会执行
const {searchName, persons, orderType} = this
//最终需要显示的数组
let arr = [...persons]
// 过滤数组
if(searchName.trim()) {
arr = persons.filter(p => p.name.indexOf(searchName)!==-1)
}
// 排序
if(orderType) {
//sort需要传递比较函数
arr.sort(function (p1, p2) { //如果返回负数代表P1在前,返回正数代表P2在前
if(orderType===1) { // 降序
return p2.age-p1.age
} else { // 升序
return p1.age-p2.age
}
})
}
return arr
}
},
methods: {
//定义设置顺序的方式,比jquery简单的多
setOrderType (orderType) {
this.orderType = orderType
}
}
})
</script>
</body>
</html>
10.2 执行效果
10.2.1 原始页面
10.2.2 搜索a
10.2.3 升序
10.2.4 降序
10.2.5 原本顺序
11 vue 事件处理
11.1 代码和笔记
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>07_事件处理</title>
</head>
<body>
<!--
1. 绑定监听:
v-on:xxx="fun"
@xxx="fun"
@xxx="fun(参数)"
默认事件形参: event
隐含属性对象: $event
2. 事件修饰符:
.prevent : 阻止事件的默认行为 event.preventDefault()
.stop : 停止事件冒泡 event.stopPropagation()
3. 按键修饰符
.keycode : 操作的是某个keycode值的健
.enter : 操作的是enter键
-->
<div id="example">
<h2>1. 绑定监听 <!-- 如果不传参数,默认传了event
-->
<button @click="test1">test1</button>
<button @click="test2('abc')">test2</button>
<!-- 得到button的文本
event 代表事件对象
既要传值,又要传event ...
-->
<button @click="test3('abcd', $event)">test3</button>
<h2>2. 事件修饰符 <!--
阻止事件的默认行为:.prevent
-->
<a href="http://www.baidu.com" @click.prevent="test4">百度一下</a>
<!--
事件冒泡
如何实现 点击inner仅显示inner。需要做到的是:停止事件冒泡 .stop
-->
<div style="width: 200px;height: 200px;background: red" @click="test5">
<div style="width: 100px;height: 100px;background: blue" @click.stop="test6"></div>
</div>
<h2>3. 按键修饰符 <!--
按键抬起时调用 keyup //enter,space...
-->
<input type="text" @keyup="test8">
<input type="text" @keyup.13="test7">
<input type="text" @keyup.enter="test7">
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#example',
data: {
},
methods: {
test1(event) {
alert(event.target.innerHTML)
},
test2 (msg) {
alert(msg)
},
test3 (msg, event) {
alert(msg+'---'+event.target.textContent)
},
test4 () {
alert('点击了链接')
},
test5 () {
alert('out')
},
test6 (event) {
// event.stopPropagation();
alert('inner')
},
test7 (event) {
console.log(event.keyCode)
alert(event.target.value)
},
test8 (event) {
// console.log(event.keyCode)
if(event.keyCode==13){
alert(event.target.value)
}
}
}
})
</script>
</body>
</html>
11.2 执行效果
11.2.1 点击绑定监听
11.2.2 点击prevent事件
11.2.3 点击防止事件冒泡
点击inner:
点击按键修饰1:
点击按键修饰2:
点击按键修饰3:
12 vue 表单数据的自动绑定
12.1 代码和笔记
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>08_表单输入绑定</title>
</head>
<body>
<!--
1. 使用v-model(双向数据绑定)自动收集数据
text/textarea 单行或多行文本
checkbox 单选
radio 复选
select 下拉框
-->
<div id="demo">
<!-- form通过 submit 取消自动提交 ——阻止默认行为
-->
<form action="/xxx" @submit.prevent="handleSubmit">
<span>用户名: <input type="text" v-model="username"><br>
<span>密码: <input type="password" v-model="pwd"><br>
<span>性别: <!-- value 值 跟 定义时对照
-->
<input type="radio" id="female" value="女" v-model="sex">
<label for="female">女</label>
<input type="radio" id="male" value="男" v-model="sex">
<label for="male">男</label><br>
<span>爱好: <!-- value 值 跟 定义时对照 应该定义时选择数组 []
-->
<input type="checkbox" id="basket" value="basket" v-model="likes">
<label for="basket">篮球</label>
<input type="checkbox" id="foot" value="foot" v-model="likes">
<label for="foot">足球</label>
<input type="checkbox" id="pingpang" value="pingpang" v-model="likes">
<label for="pingpang">乒乓</label><br>
<span>城市: <!-- value 值 跟 定义时对照 应该定义时选择数组 []
-->
<select v-model="cityId">
<option value="">未选择</option>
<!-- 记得value前有冒号 -->
<option :value="city.id" v-for="(city, index) in allCitys" :key="city.id">{{city.name}}</option>
</select><br>
<span>介绍: <textarea rows="10" v-model="info"></textarea><br><br>
<input type="submit" value="注册">
</form>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#demo',
data: {
username: '',
pwd: '',
sex: '男', //默认男
likes: ['foot'], //默认足球被选中
allCitys: [{id: 1, name: '北京'}, {id: 2, name: '南京'}, {id: 3, name: '深圳'}], //所有城市的列表数组
cityId: '2',
info: ''
},
methods: {
handleSubmit () {
console.log(this.username, this.pwd, this.sex, this.likes, this.cityId, this.info)
alert('提交注册的ajax请求')
}
}
})
</script>
</body>
</html>
12.2 执行效果
12.2.1 原始效果
12.2.2 点击注册
13 vue生命周期
13.1 代码和笔记
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>09_Vue实例_生命周期</title>
</head>
<body>
<!--
三个阶段:
初始化显示--》更新显示--》死亡
每个阶段都会对应声生命周期的回调函数(钩子)
案例:每隔一秒钟改变内容
1. vue对象的生命周期
1). 初始化显示
* beforeCreate() 创建前(其实是已经创建好后的准备工作)
observe data 监视观察 给属性增加set方法监视属性变化
* created() 已创建
判断是否有el,如果有,则继续,否则使用vm.$mount(el)
解析模板语法
先在内存中做解析替换,界面不变;解析好之后,一次性变化大括号表达式(批量) 这样可以减少更新的次数
* beforeMount() 挂载前
* mounted() 已挂载——一般会选择mounted 常用。
2). 更新状态 this.xxx = value
* beforeUpdate() 更新前
重新渲染
* updated() 已更新
3). 销毁vue实例: vm.$destory()被调用时
页面仍然显示,但是没有数据绑定了。
* beforeDestory() 销毁前 收尾工作 常用。
* destoryed() 已销毁
2. 常用的生命周期方法
created()/mounted(): 发送ajax请求, 启动定时器等异步任务
beforeDestory(): 做收尾工作, 如: 清除定时器
-->
<div id="test">
<!--当点击按钮时,调用destroyVue方法销毁vm
-->
<button @click="destroyVue">destory vue</button>
<p v-if="isShow">华为云Web前端学习</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#test',
data: {
isShow: true
},
//初始化阶段
beforeCreate() {
console.log("beforeCreate()")
},
created() {
console.log("created()")
},
beforeMount() {
console.log("beforeMount()")
},
mounted () { //初始化显示之后立即调用一次 用的最多
// 执行异步任务 只要是回调函数,就做成箭头函数
this.intervalId = setInterval(() => {
console.log('-----')
this.isShow = !this.isShow //更新数据
}, 1000)
},
//更新阶段,执行N次
beforeUpdate() {
console.log("beforeUpdate()")
},
updated() {
console.log("updated()")
},
//销毁阶段
beforeDestroy() { //销毁之前调用一次 用的最多
console.log('beforeDestroy()')
// 执行收尾的工作 如果不加则会内存泄露
//与上面的mounted时的定义一致
clearInterval(this.intervalId)
},
destroyed(){
console.log("destroyed()")
},
methods: {
destroyVue () {
this.$destroy()
}
}
})
</script>
</body>
</html>
13.2 执行效果
13.2.1 初始页面:每个一秒钟显示一次
显示:
不显示:
13.2.2 日志
反复在beforeUpdate和updated循环
13.2.3 点了destroy之后
14 vue动画
14.1 transition动画
14.1.1 代码和笔记
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>10_过渡&动画1</title>
<style>
/*指定过渡样式*/
.xxx-enter-active, .xxx-leave-active {
/* 持续时间1s opacity */
transition: opacity 1s
}
/*指定隐藏时的样式 进入前和离开后都看不到*/
.xxx-enter, .xxx-leave-to {
opacity: 0;
}
/* 显示过渡的效果 显示1秒*/
.move-enter-active {
transition: all 1s
}
/* 隐藏过渡的效果 隐藏3秒*/
.move-leave-active {
transition: all 3s
}
/* 隐藏时的样式 */
.move-enter, .move-leave-to {
opacity: 0;
/* 向右隐藏 */
transform: translateX(20px)
}
</style>
</head>
<body>
<!--
1. vue动画的理解
操作css的trasition或animation( vue本身并不生产动画)
vue会给目标元素添加/移除特定的class
2. 基本过渡动画的编码
1). 在目标元素外包裹<transition name="xxx">
2). 定义class样式
1>. 指定过渡样式: transition
2>. 指定隐藏时的样式: opacity/其它
3. 过渡的类名
xxx-enter-active: 指定显示的transition
xxx-leave-active: 指定隐藏的transition
xxx-enter: 指定隐藏时的样式
目标:移动效果,放大缩小的效果
案例一:渐变显示和消失
案例二:进入和离开时间不一样。还需要移动
-->
<div id="demo">
<button @click="isShow = !isShow">Toggle</button>
<!-- 在P标签的外围加了一个transition标签
vue会给加一些类名,
比如 xxx-enter(进入前),xxx-enter-to(进入后),xxx-enter-active(过程中)
比如 xxx-leave(离开前),xxx-leave-to(进入后),xxx-leave-active(过程中)
-->
<transition name="xxx">
<p v-show="isShow">显示及隐藏的效果 </transition>
</div>
<hr>
<div id="demo2">
<button @click="isShow = !isShow">Toggle2</button>
<transition name="move">
<p v-show="isShow">向右移动消失的效果 </transition>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#demo',
data: {
isShow: true
}
})
new Vue({
el: '#demo2',
data: {
isShow: true
}
})
</script>
</body>
</html>
14.1.2 显示效果
(注:动画无法演示)
点第一个toggle
可见已逐渐消失
点第二个toggle
难得截到了向右漂移的效果。。逐步消失:
14.2 animation动画
14.2.1 代码和笔记
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>10_过渡&动画2</title>
<style>
/* 进入时的动画 */
.bounce-enter-active {
animation: bounce-in 1s;
}
/* 离开时的动画 */
.bounce-leave-active {
animation: bounce-in 1s reverse;
}
/* 动画配置 */
@keyframes bounce-in {
0% { /* 0秒时看不见 */
transform: scale(0);
}
50% { /* 1秒时放大为 1.5倍 */
transform: scale(1.5);
}
100% { /* 最终还原回原始大小 */
transform: scale(1);
}
}
</style>
</head>
<body>
<div id="example-2">
<!--animation的动画效果
1.首先需要一个transition标签
2.定义过渡样式transition和隐藏时的样式
-->
<button @click="show = !show">放大并还原的动画效果</button>
<br>
<transition name="bounce">
<p v-if="show" style="display: inline-block">Lorem </transition>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script>
new Vue({
el: '#example-2',
data: {
show: true
}
})
</script>
</body>
</html>
14.2.2 显示效果
原始效果:
点击后的效果:
截到了缩小准备消失得小字效果。。
15 vue过滤器
15.1 代码和笔记
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>11_过滤器</title>
</head>
<body>
<!--
1. 理解过滤器
功能: 对要显示的数据进行“特定格式化”后再显示
注意: 并没有改变原本的数据, 可是产生新的对应的数据
2. 编码
1). 定义过滤器
Vue.filter(filterName, function(value[,arg1,arg2,...]){
// 进行一定的数据处理
return newValue
})
2). 使用过滤器 管道符
<div>{{myData | filterName}}</div>
<div>{{myData | filterName(arg)}}</div>
-->
<!--需求: 对当前时间进行指定格式显示-->
<div id="test">
显示格式化的日期时间 {{time}} 最完整的: {{time | dateString}} 年月日: {{time | dateString('YYYY-MM-DD')}} yeartoday {{ time | dateStr('YYYYMMDD')}} hourtosecond {{ time | dateStr('HHmmss')}} full {{ time | dateStr()}}</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript" src="https://cdn.bootcss.com/moment.js/2.22.1/moment.js"></script>
<script>
// 定义过滤器 作为函数对象使用。
Vue.filter('dateString', function (value, format='YYYY-MM-DD HH:mm:ss') {
//moment库 日期格式化 momentjs.cn
//使用cdn bootcdn.cn
return moment(value).format(format);
})
Vue.filter('dateStr', function (value,format) {
//moment库 日期格式化 momentjs.cn
//使用cdn bootcdn.cn
return moment(value).format(format || 'YYYY-MM-DD HH:mm:ss');
})
new Vue({
el: '#test',
data: {
time: new Date()
},
mounted () {
setInterval(() => {
this.time = new Date()
}, 1000)
}
})
</script>
</body>
</html>
15.2 执行效果
16 vue指令和自定义指令
16.1 内置指令
16.1.1 代码和笔记
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>12_指令_内置指令</title>
<style>
/* 属性选择器 */
[v-cloak] {
display: none
}
</style>
</head>
<body>
<!--
常用内置指令
v:text : 更新元素的 textContent
v-html : 更新元素的 innerHTML
v-if : 如果为true, 当前标签才会输出到页面
v-else: 如果为false, 当前标签才会输出到页面
v-show : 通过控制display样式来控制显示/隐藏
v-for : 遍历数组/对象
v-on : 绑定事件监听, 一般简写为@
v-bind : 强制绑定解析表达式, 可以省略v-bind,用冒号代替
v-model : 双向数据绑定
本次仅讲解这两个:
ref : 为某个元素注册一个唯一标识, vue对象通过$refs属性访问这个元素对象
v-cloak : 使用它防止闪现表达式, 与css配合: [v-cloak] { display: none }
-->
<div id="example">
<!-- <p v-text="content"> <!–p.textContent = content–>-->
<!-- <p v-html="content"> <!–p.innerHTML = content–>-->
<!--根据ref获得标签的内容 this.$refs.msg得到的是P标签
模板v-text在解析前有属性,但是在解析之后没有了
可以利用这点:指令属性在解析前没有,在解析后就能出来。
-->
<!-- <p ref="msg">abcd-->
<!-- <p ref="content">能显示吗?-->
<button @click="hint">提示</button>
<p v-cloak>{{msg}}</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
alert('在vue之前')
new Vue({
el: '#example',
data: {
msg: 'Zhanghui'
},
methods: {
hint () {
//如何做到没解析好之前不显示
alert(this.$refs.content.textContent)
// alert('innerHTML'+this.$refs.msg.innerHTML)
}
}
})
</script>
</body>
</html>
16.1.2 执行效果
点击前:
点击后:
16.2 自定义指令
16.2.1 代码和笔记
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>12_指令_自定义指令</title>
</head>
<body>
<!--
内置指令个数有限,需要特别功能时,可以复用
1. 注册全局指令 对所有对象适用 el是标签所在的element
Vue.directive('my-directive', function(el, binding){
el.innerHTML = binding.value.toupperCase()
})
2. 注册局部指令 仅对一个vue对象适用
directives : {
'my-directive' : {
bind (el, binding) {
el.innerHTML = binding.value.toupperCase()
}
}
}
3. 使用指令
v-my-directive='xxx'
-->
<!--
需求: 自定义2个指令
1. 功能类型于v-text, 但转换为全大写 v-upper-text 定义成全局
2. 功能类型于v-text, 但转换为全小写 v-lower-text 定义成局部
指令名:v-去掉之后的,比如v-upper-text的指令名为upper-text
指令是用来写成标签属性去操作标签的
-->
<div id="test1">
<p v-upper-text="msg1"> <p v-lower-text="msg1"></div>
<div id="test2">
<p v-upper-text="msg2"> <p v-lower-text="msg2"></div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
// 注册一个全局指令
// el: 指令所在的标签对象
// binding: 包含指令相关数据的容器对象-难点
Vue.directive('upper-text', function (el, binding) {
console.log(el, binding)
//指定el的内容为 相关的值
el.textContent = binding.value.toUpperCase()
})
new Vue({
el: '#test1',
data: {
msg1: "I Love You,Atlas"
},
// 注册局部指令,只在test1中有效
directives: {
'lower-text'(el, binding) { //ES6的简洁语法,等同于 'lower-text':function(el,binding)..
console.log(el, binding)
el.textContent = binding.value.toLowerCase()
}
}
})
new Vue({
el: '#test2',
data: {
msg2: "I Love You,HiLens"
}
})
</script>
</body>
</html>
16.2.2 执行效果
可见,全局指令全部有效,但是局部指令在test2中无效。
17 vue插件
17.1 代码和笔记
建一个插件js文件
(function (window) {
//需要向外暴露的一个插件对象
const MyPlugin = {}
//插件对象必须有一个install方法,被vue调用
MyPlugin.install = function (Vue, options) {
// 1. 添加全局方法或属性 定义一个函数 myGlobalMethod
Vue.myGlobalMethod = function () {
console.log('Vue函数对象的myGlobalMethod()')
}
// 2. 添加全局资源 自定义指令my-directive
Vue.directive('my-directive',function (el, binding) {
el.textContent = 'my-directive----'+binding.value.toUpperCase()
})
// 3. 添加实例方法 将实例方法myMethod放到原型上
Vue.prototype.$myMethod = function () {
console.log('VUE实例对象的方法 $myMethod()')
}
}
//向外暴露
window.MyPlugin = MyPlugin
})(window)
调用方式:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>17_插件</title>
</head>
<body>
<div id="test">
<!-- 使用插件定义的指令 -->
<p v-my-directive="msg"></div>
<script type="text/javascript" src="../js/vue.js"></script>
<!-- 在进入vue.js后引入自定义插件 -->
<script type="text/javascript" src="vue-myPlugin.js"></script>
<script type="text/javascript">
// 声明使用插件(安装插件: 调用插件的install())
Vue.use(MyPlugin) // 内部会调用MyPlugin.install(Vue) 将插件安装上去
const vm = new Vue({
el: '#test',
data: {
msg: 'Self Def Plugin...'
}
})
//调用全局方法
Vue.myGlobalMethod()
//调用实例方法
vm.$myMethod()
// new Object()
</script>
</body>
</html>
17.2 执行效果
可见:插件的全局方法,自定义指令和vue实例vm的方法,都被调用到了。
(全文完,谢谢阅读)
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
张辉2020/09/23 10:48:201楼编辑删除举报
《web前端全栈成长计划》Vue第一章学习笔记(上)https://bbs.huaweicloud.com/blogs/196720
《web前端全栈成长计划》Vue第一章学习笔记(下)https://bbs.huaweicloud.com/blogs/196719
《web前端全栈成长计划》Vue第二章学习笔记(上)https://bbs.huaweicloud.com/blogs/196721
《web前端全栈成长计划》Vue第二章学习笔记(下)https://bbs.huaweicloud.com/blogs/196722
《web前端全栈成长计划》Vue第三章学习笔记(上)https://bbs.huaweicloud.com/blogs/196803
(第三章暂时没下,下应该是vue源码分析)
《web前端全栈成长计划》Vue第四章学习笔记(上)https://bbs.huaweicloud.com/blogs/197138
《web前端全栈成长计划》Vue第四章学习笔记(下)https://bbs.huaweicloud.com/blogs/197139
前端小白历险记(一)链接的斜杠怎么没有了?https://bbs.huaweicloud.com/blogs/181124
前端小白历险记(二)原来是你腾讯搞的鬼!https://bbs.huaweicloud.com/blogs/191671
前端小白历险记(三)歪歪扭扭学vue——谈点vue学习时那些不大懂的东西 https://bbs.huaweicloud.com/blogs/197137
前端小白历险记(四)拼死拼活过考核——思想与方法 https://bbs.huaweicloud.com/blogs/197790