Vue核心 mvvm模式 v-for key template标签 vue中数组 v-on v-model v-bind

Vue核心

Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:

<div id="app">
  {{ message }}
</div>

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
    //在浏览器中通过vm.message=“Hello Vue”发现视图改变了,内部是通过mvvm模式
  }
})

mvvm模式

vue中采用mvvm模式
m:model  数据模型层
v:view      视图层
vm:viewModel   vue的实例
view <===> vm <===> model
  注意:model层与view层没有必然的联系了,都是靠vm将两者进行双向数据绑定
  当model层数据改变了,viewmodel就知道数据发生变化了,更新view层,反之亦然。

列表渲染v-for

	v-for 指令基于一个数组来渲染一个列表。
	v-for 指令需要使用 item in items 形式的特殊语法,
	其中 items 是源数据数组,
	而 item 则是被迭代的数组元素的别名。

<div id="app">
    <ul>
        <li v-for="item in arr">{{item}}</li>
        <li v-for="it of arr">{{it}}</li>
    </ul>
</div>
<script src="./base/vue.js"></script>
<script>
    new Vue({
        el:"#app",
        data:{
            arr:["苹果","机子","你好","不好"]
        }
    })
</script>

同样v-for不仅更可以遍历数组还可以遍历json对象

	// v-for = "(value,key,index) in object"  
    // value:代表所遍历的value
    // key : 代表所遍历的键
    // index:代表下标
    // object:代表源json对象
    
	<div id="app">
        <ul>
            <li v-for="item,key in water">{{key}}:{{item}}</li>
        </ul>
    </div>
    <script src="./base/vue.js"></script>
    <script>
        new Vue({
            el:"#app",
            data:{
                water:{
                    name:"老三矿泉水",
                    age:"百年历史",
                    money:"2元"
                }
            }
        })
    </script>

v-for中的key
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key attribute

为什么v-for指令当中添加key? (key值是唯一的,尽量不要用index下标,除非你知道下标是不变的)
//虚拟dom对比的时候,添加元素、删除元素的时候 key 提高对比效率
//因为如果没有加key,内部插入新的元素,后面的元素都会经历卸载与重新装载的过程,效率太低了
//添加key之后,内部本着key值相同,dom节点复用原则。
同样关于key

key

key 的特殊 attribute 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。

有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误
最常见的用例是结合 v-for:

<ul>
  <li v-for="item in items" :key="item.id">...</li>
</ul>

它也可以用于强制替换元素/组件而不是重复使用它。当你遇到如下场景时它可能会很有用:
1.完整地触发组件的生命周期钩子
2.触发过渡
例如:

	<transition>
	  <span :key="text">{{ text }}</span>
	</transition>

当 text 发生改变时, 总是会被替换而不是被修改,因此会触发过渡。

template标签

  • 一、html5中的template标签

html中的template标签中的内容在页面中不会显示。但是在后台查看页面DOM结构存在template标签。这是因为template标签天生不可见,它设置了display:none;属性

<!--当前页面只显示"我是自定义表现abc"这个内容,不显示"我是template",这是因为template标签天生不可见-->
<template><div>我是template</div></template>
<abc>我是自定义表现abc</abc>
  • 二、template标签操作的属性和方法

content属性:在js中template标签对应的dom对象存在content属性,对应的属性值是一个dom节点节点的nodeName是#document-fragment。通过该属性可以获取template标签中的内容,template对象.content可以调用getElementById、querySelector、querySelectorAll方法来获取里面的子节点
innerHTML:可以获取template标签中的html。

<template id="tem">
    <div id="div1">我是template</div>
    <div>我是template</div>
</template>
<script>
    let o = document.getElementById("tem");
    console.log(o.content.nodeName);//#document-fragment
    console.log(o.content.querySelectorAll("div"));//NodeList(2) [div#div1, div]。得到一个类数组
    console.log(o.content.getElementById("div1"));//<div id="div1">我是template</div>
    console.log(o.innerHTML);//'<div id="div1">我是template</div><div>我是template</div>'
</script>
  • 三、vue中的template

1、template标签在vue实例绑定的元素内部
它是可以显示template标签中的内容,但是查看后台的dom结构不存在template标签。如果template标签不放在vue实例绑定的元素内部默认里面的内容不能显示在页面上,但是查看后台dom结构存在template标签

<div id="app">
<!--此处的template标签中的内容显示并且在dom中不存在template标签-->
<template>
    <div>我是template</div>
    <div>我是template</div>
</template>
</div>
<!--此处的template标签中的内容在页面中不显示,但是在dom结构存在该标签及内部结构-->
<template id="tem">
<div id="div1">我是template</div>
<div>我是template</div>
</template>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
    el: "#app",
});
</script>

注意: vue实例绑定的元素内部的template标签不支持v-show指令,即v-show="false"对template标签来说不起作用。但是此时的template标签支持v-if、v-else-if、v-else、v-for这些指令。

<div id="app">
    <template v-if="true">
    <!--此时template标签中的内容显示在页面上,但是看dom结构没有template标签-->
        <div>我是template</div>
        <div>我是template</div>
    </template>
    <div v-if="true">
    <!--此时页面上显示div标签中的内容,并且看dom结构存在最外面的div标签-->
        <div>我是template</div>
        <div>我是template</div>
    </div>
    <!--此处会输出6个‘我是template’并且dom结构中不存在template标签-->
    <template v-for="a in 3">
        <div>我是template</div>
        <div>我是template</div>
    </template>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el: "#app",
    });
</script>

2、vue实例中的template属性
将实例中template属性值进行编译,并将编译后的dom替换掉vue实例绑定的元素,如果该vue实例绑定的元素中存在内容,这些内容会直接被覆盖。
特点:

1)如果vue实例中有template属性,会将该属性值进行编译,将编译后的虚拟dom直接替换掉vue实例绑定的元素(即el绑定的那个元素);
2)template属性中的dom结构只能有一个根元素,如果有多个根元素需要使用v-if、v-else、v-else-if设置成只显示其中一个根元素
3)在该属性对应的属性值中可以使用vue实例data、methods中定义的数据

<!--此处页面显示hello-->
<div id="app"></div>
<!--此处template标签必须在vue绑定的元素外面定义,并且在页面中不显示下面的template标签中的内容-->
<template id="first">
    <div v-if="flag">{{msg}}<div>
    <div v-else>111<div>
</template>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el:"#app",
        data:{
            msg:"hello",
            flag:true
        },
        template:"#first"//通过该属性可以将自定义的template属性中的内容全部替换app的内容,并且会覆盖里面原有的内容,并且在查看dom结构时没有template标签
    });
</script>

上面的例子中html中的template标签可以变成自定的标签,如下。但是下面这种方式也可以将<abc></abc>标签中的内容替换掉app元素,但是<abc></abc>标签中的内容也会显示在页面上。所以此处利用template标签来定义vue实例中需要设置的template属性。

<abc id="first">
    <div v-if="flag">{{msg}}<div>
    <div v-else>111<div>
</abc>

上面的实例还可以写成下面的形式

<!--此处页面显示hello-->
<div id="app"></div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el:"#app",
        data:{
            msg:"hello",
            flag:true
        },
    template:"<div v-if='flag'>{{msg}}</div><div v-else>123</div>"//模板中只能有一个根元素,如果有多个需要使用v-if、v-else、v-else-if来选择显示哪一个
});
</script>

vue中的数组

 Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。
 这些被包裹过的方法包括:
                push()         数组的后面插入元素
                pop()          从数组的后面删除一个元素
                shift()        从数组的前面删除一个元素
                unshift()      从数组的前面插入一个元素
                splice()       数组的剪贴、插入、删除等操作
                sort()         数组的排序
                reverse()      数组的反转
    **注意**:
            由于 JavaScript 的限制,Vue 不能检测数组和对象的变化 
            1. vm.arr[0] = 10 发现数据改变了,但是视图却没有发生变化!
               1)vm.arr.splice(0,1,10)
               2) Vue.set(vm.arr,0,10)
            2. vm.arr.length = 2
               vm.arr.splice(2)
            3. vm.user.age = 18  发现视图没有任何改变
               Vue.set(vm.user,"age",18) 

  之前的name被vue实例进行挂载了,所以会动态的为其添加get与set方法,数据劫持。数据改变 ==> set ==> watcher ==> 视图更新
  但是后续vm.user.age = 18 这个属性,只是简单的数据改变,
  
  没有进行内部的数据劫持,去进行动态的添加get与set,数据改变了,但是视图不会更新。
 怎么让其变成响应式的呢? vue当中提供了一个全局的api方法 Vue.set() 
 就可以为动态添加的数据也会被vue管理,双向数据绑定了。

v-on

缩写:@
预期:Function | Inline Statement | Object
参数:event
修饰符:(vue中提供事件修饰符)
.stop - 调用 event.stopPropagation()。阻止事件冒泡
.prevent - 调用 event.preventDefault()。阻止事件默认行为
.capture - 添加事件侦听器时使用 capture 模式。
.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
.{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
.native - 监听组件根元素的原生事件。
.once - 只触发一次回调。
.enter 提供了键盘修饰符
.left - (2.2.0) 只当点击鼠标左键时触发。
.right - (2.2.0) 只当点击鼠标右键时触发。
.middle - (2.2.0) 只当点击鼠标中键时触发。
.passive - (2.3.0) 以 { passive: true } 模式添加侦听器

v-model

	//请你说一下 v-model底层原理实现? 
    //绑定了value属性与监听了input事件 
    //详细来说是通过v-bind绑定value属性 通过v-on绑定input属性

    //v-model常用修饰符有哪些?
    //1.v-model.lazy    默认是实时更新,如果加了lazy修饰符,只有失去焦点的时候,内部才会更新
    //2.v-model.number  这个值无法被parseFloat解析的时候原样输出,否则转换
    //3.v-model.trim    去掉前后空格

    //注意: v-model指令只能用在组件或者表单控件中
    // 你可以用 v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定

案例

  <div id="app">
    <p>{{mgs}}</p>
    <p><input type="text" v-model="mgs"></p>
</div>
<script src="./base/vue.js"></script>
<script>
     new Vue({
        el:"#app",
        data:{
            mgs:"<h1>你好烦哈回复哈</h1>"
        }
    })
</script>

v-bind

动态地绑定一个或多个 attribute,或一个组件 prop 到表达式。

v-bind
缩写::
预期:any (with argument) | Object (without argument)
参数:attrOrProp (optional)
修饰符:
.prop - 作为一个 DOM property 绑定而不是作为 attribute 绑定。(差别在哪里?)
.camel - (2.1.0+) 将 kebab-case attribute 名转换为 camelCase。(从 2.1.0 开始支持)
.sync (2.3.0+) 语法糖,会扩展成一个更新父组件绑定值的 v-on 侦听器。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值