目录
5.计算属性有哪些特点 和methods的区别是什么 请写出案例
6.Watch的使用场景有哪些 并写出watch的用法 请写出案例 可在脚手架写出演示代码并说明
7.遍历为什么要使用key值,用index可以吗?原理是什么?
8.v-on可以监听多个方法吗?请举例 v-on 常用修饰符有哪些请举例说明请写出案例 可在写出演示代码并说明
10.Vue单页面应用 单页面应用和多页面应用区别及优缺点?
11.Vue中的双向数据绑定是如何实现的,原理是什么 请举例说明
相同点:v-show和v-if都能控制元素的显示和隐藏。
不同点:
(1)实现本质方法不同。
v-show本质就是通过设置css中的display设置为none,控制隐藏。
v-if是动态的向DOM树内添加或者删除DOM元素。
(2)编译的区别
v-show其实就是在控制css。
v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件。
(3)编译的条件
v-show都会编译,初始值为false,只是将display设为none,但它也编译了
v-if初始值为false,就不会编译了
(4)性能
v-show只编译一次,后面其实就是控制css,而v-if不停的销毁和创建,故v-show性能更好一点。因为v-show实际是操作display:" "或者none,当css本身有display:none时,v-show无法让显示。
总结:如果要频繁切换某节点时,使用v-show(无论true或者false初始都会进行渲染,此后通过css来控制显示隐藏,因此切换开销比较小,初始开销较大),如果不需要频繁切换某节点时,使用v-if(因为懒加载,初始为false时,不会渲染,但是因为它是通过添加和删除dom元素来控制显示和隐藏的,因此初始渲染开销较小,切换开销比较大)。
所谓MVVM模型包含如下几个部分:Model、View、ViewModel 分别对应 模型 - 视图 - 视图模型。所以,通常在定义 vue 对象时,我们将 变量名 设置为 vm 。
(1)轻量级,体积小是一个重要指标。Vue.js 压缩后有只有 30多kb (Angular 压缩后 56kb+,React 压缩后 44kb+)
(2)移动优先。更适合移动端,比如移动端的 Touch 事件
(3)易上手,学习曲线平稳,文档齐全
(4)吸取了 Angular( 模块化 )和 React( 虚拟 DOM )的长处,并拥有自己独特的功能,如: 计算属性
(5)开源,社区活跃度高
将修改公共组建的样式放在< style>中,组件里根元素样式用id选择器定义,在style里用id选择器包起来,其余的样式放在< style scoped>中。
特点:
(1)计算属性中任意一个实例数据发生变化。计算属性就会重新计算,视图也会更新。
(2)每一个计算属性都包含一个getter和setter。
(3)计算属性可以依赖多个Vue实例中的数据。
区别:
(1)计算属性和methods的执行结果都是相同的
(2)当计算属性没有依赖data中的数据时,第一次使用计算属性时,会把第一次的结果进行缓存,后面再次使用计算属性,都会去第一次的结果中进行查找
(3)methods方法,每调用一次,就会触发一次
(4)计算属性的用法与data中的数据用法一样,因此计算属性在使用时,不加 ( )
(5)methods方法在调用时,( ) 可加可不加
(6)计算属性具有缓存功能,methods方法没有
案例:
- <div id="root">
-
- <h2>您的fullname是从计算属性中得到:{{fullName()}}h2>
- <h2>您的fullname是从计算属性中得到:{{fullName()}}h2>
- <h2>您的fullname是从计算属性中得到:{{fullName()}}h2>
- <h2>您的fullname是从计算属性中得到:{{fullName()}}h2>
- <h2>您的fullname是从方法中得到:{{getFullName}}h2>
- <h2>您的fullname是从方法中得到:{{getFullName}}h2>
- <h2>您的fullname是从方法中得到:{{getFullName}}h2>
- <h2>您的fullname是从方法中得到:{{getFullName}}h2>
- div>
-
- <script>
- const vm = new Vue({
- el: '#root',
- data() {
- return {
- fistName :'zhang',
- listName :'san'
- }
- },
- //方法
- methods: {
- fullName() {
- return this.fistName+this.listName
- }
- },
- //计算属性
- computed: {
- getFullName(){
- return this.fistName+this.listName
- }
- }
- })
- script>
使用场景是:当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。例如ajax请求,复杂的业务逻辑处理等。
案例一:
- <div id="root">
- <h3>{{fistName}}h3>
- div>
- <script>
- const vm = new Vue({
- el: '#root',
- data() {
- return {
- //存储一些数据
- fistName: "zhang",
- lastName: "san",
- watchFullName: "zhangsan",
- age: 18,
- }
- },
- watch: {
- /* firstName(newval,oldval){//监听器中有两个参数 一个是newval新的值
- 一个是oldval是老值
- console.log(newval);
- console.log(oldval);
- } */
- fistName: 'change'
- },
- methods: {
- change(newval, oldval){
- console.log(newval)
- console.log(oldval)
- }
- }
- })
- script>
案例二:
- <div id="root">
- <p>fullName:{{preson.fullName}}p>
- <p>fistName:{{fistName}}p>
- div>
- <script type="text/javascript">
- const vm = new Vue({
- el: '#root',
- data() {
- return {
- person: {
- fistName: 'zhang',
- listName: 'san',
- fullName: '',
- }
- }
- },
- watch: {
- // 以下注释的两种均是错误的使用方法
- // fullname(newval,oldval){
- // console.log(newval);
- // console.log(oldval);
- // }
- // person(newval,oldval){
- // console.log(newval);
- // console.log(oldval);
- // }
- person: {
- //固定写法 第一个是新值 第二个是旧值
- handler(n, o) {
- console.log(n);
- console.log(o);
- //将获取的值给当前person中的fullname n.firstname是传入的新值
- //this.person.lastname是获取preson里面的值
- this.person.fullname = n.firstname + this.person.lastname
- },
- immediate: true, //刷新即加载
- deep: true //深度监听
- }
- }
- })
- script>
(1)在beforeUpdata生命周期时,在内存中通过diff算法将虚拟DOM与真实DOM进行比较。此时的key的作用是,作为虚拟DOM对象的标识,将虚拟DOM与保存的上一次渲染的真实DOM建立联系一一比较。如果key值一样,直接渲染之前的真实DOM到页面;不一样或者未找到则重新转换成新的真实DOM,再渲染到页面。
(2)可以用index,但是不太好。如果对数据进行逆序添加、逆序删除等破坏顺序的操作,会产生没必要的真实DOM更新,并且如果结构是可输入元素,会产生错误。
可以。
v-on 常用修饰符:
.stop 该修饰符将阻止事件向上冒泡。同理于调用 event.stopPropagation() 方法
.prevent 该修饰符会阻止当前事件的默认行为。同理于调用 event.preventDefault() 方法
.self 该指令只当事件是从事件绑定的元素本身触发时才触发回调
.once 该修饰符表示绑定的事件只会被触发一次
案例:
- <div id="app">
-
- <div @click="divClick" class="div">
- <button type="button" @click.stop="btnClick">点击button>
- div>
-
- <a href="http://www.baidu.com" @click.prevent="change">去百度a>
-
- <div @click="divClick" class="div">
- <a href="http://www.baidu.com" @click.stop.prevent="change2">去百度a>
- div>
-
-
- <div class="box1" @click.capture="show(111)">
- div1外面
- <div class="box2" @click="show(222)">
- div2里面
- div>
- div>
-
-
- <div class="div" @click.self.prevent="showself">
- <button @click.self.prevent="showself">点我button>
- div>
-
-
- <a @click.once="doThis">点击触发a>
-
-
-
- <div class="div" @wheel.passive="onScroll">滚动事件的默认行为 (即滚动行为) 将会立即触发滚动事件的默认行为 (即滚动行为) 将会立即触发滚动事件的默认行为 (即滚动行为) 将会立即触发滚动事件的默认行为 (即滚动行为) 将会立即触发div>
- <div @scroll="onScroll" class="div">滚动事件的默认行为 (即滚动行为) 将会立即触发滚动事件的默认行为 (即滚动行为) 将会立即触发滚动事件的默认行为 (即滚动行为) 将会立即触发滚动事件的默认行为 (即滚动行为) 将会立即触发div>
- div>
- <script>
- const vm = new Vue({
- el: '#app',
- data() {
- return {
- }
- },
- methods: {
- divClick() {
- console.log('点击了div');
- },
- btnClick() {
- console.log('点击了btn');
- },
- change() {
- console.log('阻止了默认行为');
- },
- change2() {
- console.log('阻止了默认行为也阻止了冒泡');
- },
- show(msg) {
- console.log(msg);
- },
- showself() {
- console.log('我是点击自身才触发');
- },
- doThis() {
- console.log('点击了a');
- },
- onScroll(){
- for(let i = 0;i<5000;i++){
- console.log('@');
- }
- console.log('333333');
- }
- /* onScroll(){
- for (let i = 0; i < 10000; i++) {
- console.log('@');
- }
- console.log('333333');
- } */
- }
- })
- script>
v-for的优先级比v-if高,每循环一次就会去v-if一次,而v-if是通过创建和销毁dom元素来控制元素的显示与隐藏,所以就会不停的去创建和销毁元素,造成页面卡顿,性能下降。
区别:单页面应用(spa):只有一个html页面,所以跳转的方式是组件之间的切换
多页面应用(mpa):有多个页面,跳转方式是页面之间的跳转
单页面应用
优点:
1、用户体验好,快,内容的改变不需要重新加载整个页面,对服务器压力较小。
2、前后端分离,比如vue项目
3、完全的前端组件化,前端开发不再以页面为单位,更多地采用组件化的思想,代码结构和组织方式更加规范化,便于修改和调整。
缺点:
1、首次加载页面的时候需要加载大量的静态资源,这个加载时间相对比较长。
2、不利于 SEO优化,单页页面,数据在前端渲染,就意味着没有 SEO。
3、页面导航不可用,如果一定要导航需要自行实现前进、后退。(由于是单页面不能用浏览器的前进后退功能,所以需要自己建立堆栈管理)
vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的.
1)数据劫持、vue是通过Object.defineProperty()来实现数据劫持,其中会有getter()和setter方法;当读取属性值时,就会触发getter()方法,在view中如果数据发生了变化,就会通过Object.defineProperty( )对属性设置一个setter函数,当数据改变了就会来触发这个函数。
- <div id="box">div>
-
- <script>
- var obj={
-
- }
- var obox=document.querySelector("#box")
- Object.defineProperty(obj,'myname',{
- get(){
- console.log('get');//有人访问get就会收到
- return obox.innerHTML
- },
- set(value){
- console.log('set',value);//有人修改set会收到 value会收到修改后的值
- obox.innerHTML=value ;
- }
- })
改变myname的值后,get会知道有人修改,set会得到修改后的值 然后传到页面
组件化开发即是对某些可以进行复用的功能进行封装的标准化工作。组件一般会内含他的内部UI元素、样式和JS逻辑代码,它可以很方便的在应用的任何地方进行快速的嵌入。组件内部可以使用其他组件来构成更复杂的组件。组件化开发是一种好用的解决方案。
组件化开发极大提高工程编译速度,有利于多人团队协作开发,组件化是功能重用的基石。