vue

(1)双向数据绑定必须在表单里面使用,如input、select

双向绑定原理:

 采用数据劫持结合发布者-订阅者模式的方法,通过Object.defineProperity()来劫持各个属性的set,get,在数据变动时发布消息给订阅者,触发相应的监听回调。

数据劫持通过Object.defineProperity(obj,prop,descriptor)方法来实现,当我们访问或设置对象属性时都会触发该方法,当触发方法时,做一些其他操作,就是“劫持”操作。

其中参数obj表示目标对象;props需要定义的属性或方法名称;descriptor表示目标属性所拥有的特性。

var obj={
    text:123,
    name:"an"
}
Object.defineProperty(obj,"text",{
    configurable:false,
    //configurable是否可以删除目标属性或是否可以再次修改属性的特性,设置为true可以被删除或可以重新设置特性;设置为false,不能被可以被删除或不可以重新设置特性。默认为false。
    value:4,
    writable:false,//是否可以被重写
    enumerable:false
    //enumerable是否可以被枚举(使用for...in或者Object.keys())
})
console.log(obj.text);//4
obj.text=5;
console.log(obj.text);//4
for(var i in obj){
    console.log(i);//只显示name
}
delete obj.text;
console.log(obj.text);//不可删除仍然可以打印出4

 

//手写一个简单的双向绑定
<input type='text' id='model'/>
<p id='text'></p>
<script>
    var user={};
    var model=document.getElementById('model');
    var val=document.getElementById('text');
                
    //数据劫持
    Object.defineProperty(user,"name",{
        get:function(){
        console.log('获取输入值');
        return model.value;
        },
        set:function(newValue){
        model.value=newValue;
        val.textContent=newValue;
        }
    })
    //发布订阅模式
    model.addEventListener('keyup',function(){
        console.log("从视图->数据");
        user.name=this.value;
    })
    setTimeout(function(){
        console.log('从数据——>视图');
        user.name="修改后的新值";
    },3000)
</script>

 

当在输入框输入数据时,首先触发input事件,在相应的事件处理程序中,将获得的value值赋值给vm实例的text属性,我们会利用defineProperity将data中的text设置为value值,就会触发set方法。

text属性变化了,set方法触发了,但是文本节点的内容没有变化。如何才能绑定到text文本节点也同步变化呢?这里用到订阅发布模式

订阅发布模式又称为观察者模式,定义了一种一对多的关系,让多个观察者同时监听某一个主题对象,一旦这个主题对象的状态发生改变时就会通知所有的观察者对象。

 

发布订阅模式的优点:

  • 实现时间上的解耦(组件,模块之间的异步通讯);
  • 对象之间的解耦。

发布订阅模式的缺点:

  • 创建订阅者本身会消耗内存,订阅消息后,也许永远不会有发布,而订阅者始终存在内存中;
  • 对象之间解耦的同时,他们的关系也会被深埋在代码背后,这会造成一定的维护成本。

(2)ref用来获取dom节点,如

<input type="text" ref='sexValue'/>

<div  ref='boxValue'></div>

<button v-on:click="getInputValue()">获取dom的内容</button>

methods:{
     getInputValue(){
      console.log(this.$refs.sexValue);
      alert(this.$refs.sexValue.value);
     }
   }

(3)绑定属性 v-bind:

<img v-bind:src='url'/>
 <img :src='url'/>

绑定方法 v-on:click:

  <button v-on:click="getname()">获取表单内容</button>
  <button @click="setname()">设置表单内容</button>

(4)v-if与v-show的区别

v-if是条件渲染,在初始条件为假时不会被渲染;v-show无论初始条件是什么都会被渲染,只是控制显示与隐藏。

v-if有更高的切换开销,而v-show有更高的初始渲染开销,如果需要频繁切换,则使用v-show,如果在运行条件很少时用v-if

(5)<keep-alive>

<keep-alive>是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染dom。

我们之前曾经在一个多标签的界面中使用 is 特性来切换不同的组件,

<component v-bind:is="currentTabComponent"></component>

当这些组件之间切换时,有时想保持这些组件的状态,以避免反复重渲染导致的性能问题。

如上图page1、page2、page3按钮为组件之间的切换,正常情况下,当在组件page1中选择其它tab时,下次再回到该组件则会重新渲染,默认选中的是“php”,如果使用<keep-alive>将这些动态组件包裹住,则下次再点击page1时,还是上次选中的“javascript”

(6)计算属性vs方法

对于任何复杂逻辑,都应当使用计算属性

computed: {
   // 计算属性的 getter
   reversedMessage: function () {
        return this.message.split('').reverse().join('')
   }
}

通过{{reversedMessage}}获取计算结果。

也可以将一个函数定义为一个方法而不是计算属性,两种最终结果是完全相同的,但是

计算属性是基于它们的依赖进行缓存的,只有在相关依赖发生变化时才会重新求值,这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

methods: {
     reversedMessage: function () {
        return this.message.split('').reverse().join('')
    }
}

通过{{reversedMessage()}}获取计算结果。相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

(7)计算属性computed  VS  侦听器watch

computed计算属性是用来声明式的描述一个值依赖了其他的值。当你把模板里的数据绑定到一个计算属性上时,vue会在其依赖的任何值导致该计算属性改变时更新DOM。

watch监听的是你定义变量,当定义的变量的值发生变化时,调用对应的方法。

 

而计算属性计算的是fullName依赖的值,他不能计算在data中已经定义过的变量。

(8)v-bind与v-on的区别

v-bind用于设置属性,如v-bind:href,缩写为 :href

v-on用于绑定事件   如v-on:click,缩写为 @click

(9)插槽slot

通过插槽分发内容

单个插槽:

父组件

子组件testSlot.vue

具名插槽:就是将某个名字的内容插到子组件对应名字里面去

父组件:

子组件:

运行结果:

我们还是可以保留一个未命名插槽,这个插槽是默认插槽,也就是说它会作为所有未匹配到插槽内容的统一出口。

posted @ 2019-01-11 17:32  安xiao曦  阅读(253)  评论(0编辑  收藏  举报