Vue基础系列(二二)Vue基础--Vue模板语法-vue数据绑定原理-插值语法-指令语法-元素的显示隐藏

Posted 勇敢*牛牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue基础系列(二二)Vue基础--Vue模板语法-vue数据绑定原理-插值语法-指令语法-元素的显示隐藏相关的知识,希望对你有一定的参考价值。

和阿牛一起冲Vue


🌕写在前面
🍊博客主页勇敢link牛牛
🎉欢迎关注:🔎点赞👍收藏⭐️留言📝
🌟本文由 勇敢link牛牛 原创,CSDN首发!
📆首发时间:🌹2022年8月29日🌹
🆕最新更新时间:🎄2022年8月29日🎄
✉️愿你熬过万丈孤独,藏下星辰大海!
📠参考书籍:📚《Vue2》
🙏作者水平很有限,如果发现错误,请留言轰炸哦!万分感谢感谢感谢!

Vue基础--Vue模板语法-vue数据绑定原理-插值语法-指令语法

Vue基础

一、Vue基础

1.1、介绍

Vue.js是一套构建用户界面的渐进式框架。Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与单文件组件和 Vue 生态系统支持的库结合使用时,Vue 也完全能够为复杂的单页应用程序提供驱动。

  • 渐进式:一步一步,不是说你必须一次把所有的东西都用上
  • 自底向上设计:是一种设计程序的过程和方法,就是先编写出基础程序段,然后再逐步扩大规模、补充和升级某些功能,实际上是一种自底向上构造程序的过程。

Vue从设计角度来讲,虽然能够涵盖这张图上所有的东西,但是你并不需要一上手就把所有东西全用上,都是可选的。声明式渲染和组件系统是Vue的核心库所包含内容,而路由、状态管理、构建工具都有专门解决方案。这些解决方案相互独立,你可以在核心的基础上任意选用其他的部件,不一定要全部整合在一起。

1.2、声明式渲染和组件化

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

<div id="app">
  <!-- 渲染 Hello Vue -->
   message 
</div>
#js
var vm = new Vue(
  // 选择真实html中的 选择器
  el: '#app',
  // 数据源 -- 声明模板变量所在的位置
  data(): 
    // 返回一个对象
	return 
		// 声明一下变量
	    message: 'Hello Vue!'
	
  
)

💖 组件化应用构建
组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。几乎任意类型的应用界面都可以抽象为一个组件树。


	tag:div
	children:[
		
			tag:div
			children:[]
		
	]

1.3、MVVM模式
MVVM是Model-View-ViewModel的简写。它本质上就是MVP 的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开。当然这些事 ViewModel 已经帮我们做了,它可以取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑。
vue使用MVVM响应式编程模型,避免直接操作DOM , 降低DOM操作的复杂性。

  • MVVM:页面输入改变数据,数据改变影响页面数据展示与渲染
  • M(model):普通的javascript数据对象
  • V(view):前端展示页面
  • VM(ViewModel):用于双向绑定数据与页面,其实就是vue的实例

优点:

  • 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
  • 可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
  • 独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
  • 可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

二、vue基础使用

2.1、传统dom操作

使用js对html页面结构中的指定的区域输出数据

<div></div>
<input type="text" name="" id="">

<script>
	var input = document.querySelector("input");
	input.addEventListener("input",function(e)
	var div = document.querySelector("div");
		div.innerHTML = this.value.trim();
	);
</script>
<body>
    <div></div>
    <input type="text" name="" id="">

    <script>
        /* 数据源 */
        var data =
            message :"我爱你"
        

        var target = ;/* 做个代理中转 目标数据*/
        /* 做个属性侦听改变侦听 响应数据*/
        Object.defineProperty(target,"message",
            get()
                // return data.message;
                return Reflect.get(data,"message")
            ,
            set(newValue)
                data.message = newValue;
                document.querySelector("div").textContent = newValue;
            
        )

        /* 初步把数据源的值,分别传给div和input */
        var input = document.querySelector("input");
        input.value =target.message;
        document.querySelector("div").textContent = target.message;
        /* 间接代理服务 */
        input.addEventListener("input",function(e)
            target.message = this.value.trim();
        );

    </script>
</body>

2.2、使用vue实现

在html页面中使用好vue需要完成如下步骤即可

  • 引入vue.js文件
  • 定义给vue.js管理的dom元素(给div定义一个ID)
  • 创建一个 Vue 的实例,并声明要渲染的数据源
  • 在给定的dom元素容器内,绑定数据源中变量名称变量名

Vue参数对象属性

  • el:元素挂载的位置,值可以是CSS选择器或DOM元素
  • data:模型数据,值是一个对象

插值表达式

  • 将数据填充到HTML标签中

  • 支持基本的JavaScript计算操作,例如算术运算、字符串拼接等

下载vue.js

在html中引入vue.js文件

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue学习使用</title>
    <!-- 第1步: 引入vue库文件 -->
    <script src="./js/vue.js"></script>
</head>

<body>

    <!-- 第2步:根容器,js对象转为真实的html后,在放在网页的什么位置中  挂载点 -->
    <!-- 挂载点可以写多个,但是在工作中一般只有一个 -->
    <div id="app">

        <!-- 第4步:使用 -->
        <!-- 模板语法 插值表达式 mustcache模板名称[小胡子语法] -->
        <!-- title它就是在vue实例化配置data属性中的数据 -->
        <h3> title </h3>
        <!-- <input type="text" id="setTitle"> -->
        <!-- v-model,语法糖 -->
        <input type="text" v-model="title">

    </div>

    <!-- 第3步:实例化vue -->
    <script>
        const vm = new Vue(
            // vue处理完成数据展示在页面中的挂载点dom
            el: '#app',
            // vue2中,唯一一个地方可以把data写成对象地方,就是在实例化vue类时
            // 声明vue要渲染的数据
            data: 
                title: 'hello vue'
            
        )

        console.log(vm.title)

        // document.getElementById('setTitle').value = vm.$data.title
        // document.getElementById('setTitle').oninput = e => vm.$data.title = e.target.value.trim()
    </script>

</body>

</html>
<div id="app">
    <div class="div1">message</div>
    <input type="text" v-model="message">
</div>

<script>
    var vm = new Vue(
        el:"#app",
        data:()=>   
            return
                message:"我爱你" 
               
        
    )
</script>


2.3、为什么要使用虚拟Dom

用传统的开发模式,原生JS或JQ操作DOM时,浏览器会从构建DOM树开始从头到尾执行一遍流程。在一次操作中,我需要更新10个DOM节点,浏览器收到第一个DOM请求后并不知道还有9次更新操作,因此会马上执行流程,最终执行10次。
例如,第一次计算完,紧接着下一个DOM更新请求,这个节点的坐标值就变了,前一次计算为无用功。计算DOM节点坐标值等都是白白浪费的性能。即使计算机硬件一直在迭代更新,操作DOM的代价仍旧是昂贵的,频繁操作还是会出现页面卡顿,影响用户体验。

Web界面由DOM树(树的意思是数据结构)来构建,当其中一部分发生变化时,其实就是对应某个DOM节点发生了变化,虚拟DOM就是为了解决浏览器性能问题而被设计出来的。之前,若一次操作中有10次更新DOM的动作,虚拟DOM不会立即操作DOM,而是将这10次更新的diff内容保存到本地一个JS对象中,最终将这个JS对象一次性attch到DOM树上,再进行后续操作,避免大量无谓的计算量。所以,用JS对象操作虚拟DOM节点的好处:页面的更新可以先全部反映在JS对象(虚拟DOM)上,操作内存中的JS对象的速度显然要更快,等更新完成后,再将最终的JS对象映射成真实的DOM,交由浏览器去绘制,从而提高性能。

2.4、vue devtools工具安装

通过chrome中的谷歌插件商店安装Vue Devtools工具,此工具帮助我们进行vue数据调试所用,一定要安装。
https://chrome.google.com/webstore?utm_source=chrome-ntp-icon
https://chrome.zzzmh.cn/

在vscode中安装插件

2.5、Vue是如何实现数据绑定的原理

当把一个普通的JavaScript对象传给Vue实例的data选项,Vue将遍历此对象所有的属性,使用Object.defineProperty(vue2.x),vue3.x中使用了Proxy类把这些属性全部转为getter/setter(数据劫持)。在属性被访问和修改时通知变化。每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。

模拟vue实现数据响应式

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  <div id="root">
    <h3 v-text="title"></h3>
    <hr>
    <input type="text" v-model='title'>
  </div>

  <script>
    // 数据劫持
    let data = 
      title: '我是一个标题',
    ;
    // 观察数据
    observe(data)

    // 给input绑定事件
    document.querySelector('[v-model]').addEventListener('input', function () 
      let key = this.getAttribute('v-model')
      data[key] = this.value.trim()
    )

    function observe(target) 
      if (!isObject(target)) return;
      for (let key in target) 
        defineReactive(target, key, target[key])
      
    

    // 数据劫持
    function defineReactive(target, key, value) 

      Object.defineProperty(target, key, 
        get() 
          console.log('get')
          return value
        ,
        set(v) 
          if (v != value) 
            value = v
            console.log('set')
            // 更新视图
            updateView(value, key)
          
        
      )
    

    function updateView(value, key) 
      document.querySelectorAll('[v-text]').forEach(node => 
        let attrValue = node.getAttribute('v-text')
        if (key === attrValue) 
          if (node.nodeName === 'INPUT') 
            node.value = value;
           else 
            node.innerHTML = value;
          
        
      )
    

    function isObject(target) 
      return .toString.call(target) === '[object Object]'
	  return .toString.call(target) === '[object Array]'
    
  </script>
</body>

</html>

2.6、Diff比对

Vue中当数据发生改变的时候,对应监听的set方法会执行,调用数据中的Dep.notify方法通知所有的订阅者,订阅者就会通过patch函数对比新旧虚拟节点是否一样,如果用新的虚拟节点则整个替换老节点,如果不是使用新节点,则根据子节点情况来进行同层比较。

patch主要做4个判断
①、没有新节点,直接触发旧节点的destory钩子,进行销毁。
②、没有旧节点,此时根本不需要比较了,直接全部都是新建
③、旧节点和新节点一样时,直接调用 patchVnode 去处理这两个节点
④、旧节点和新节点自身不一样,当两个节点不一样的时候,直接创建新节点,删除旧节点

没有key的比较

比对时有key值标识

key值的作用:在使用diff算法比较新旧dom树的时候,可以更准确更快得找到oldDom树中对应的节点。(利用key的唯一性生成map对象来获取对应节点,比遍历方式更快)
patchVnode的位置

三、模板语法

3.1、插值表达式

插值表达式是vue框架提供的一种在html模板中绑定数据的方式,使用变量名方式绑定Vue实例中data中的数据变量。会将绑定的数据实时的显示出来。

3.2、支持写法

变量、js表达式、三目运算符、方法调用等

    <div id="app">
        vue模板的表达式为  变量 
        表达式中不能定义变量或函数,也不可以写if条件或循环
        <!-- 绑定变量 -->
        <div> title </div>
        进行计算 vue模板中不太建议在里面写运算
        <div> 1+1 </div>
        调用函数或方法
        <div>sum()</div>
        调用js内置方法  不太推荐
        <div> '电饭锅是'.substr(0,3) </div>
        三目运算
        <div> age<20?'未成年':'成年' </div>
    </div>

<script src="./vue.js"></script>
<script>
 const vm = new Vue(
	    el: '#app',
	        data: 
	            age: 18,
	            title: 'hello vue',
	            函数可以写在data中的,但是不太建议
	            data中的数据都会被劫持,但是函数是没有必须劫持的
	            vue为了提升性能,新增一个配置选项,用于定义函数方法method,它不会被劫持
	        ,
	        methods: 
	            sum() 
	                return 1 + 2
	            
	        
	    )

</script>

注:括起来的区域,就是一个就是js语法区域,在里面可以写部份的js语法。不能写 var a = 10; 分支语句 循环语句

3.3、指令

指令(Directives)就是vue给html标签提供的一些自定义属性,这样属性都是带有 v- 前缀的特殊属性。指令特性的值预期是单个JS表达式(v-for是例外情况)。
指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于DOM。
vue中的指令可以操作真实的dom的

指令作用:

  • 操作dom(权限限制)
  • 表单验证

v-html :解析html指令 注:尽量避免使用,容易造成危险 (XSS跨站脚本攻击)

  • 解析字符串中的html标签,解析输出,一般用于在后台添加的富文本内容,在前台显示所用

v-text :输出文本信息二者都有消除闪白、闪动的能力

  • 转义输出,为了解决早期没有使用工程化时,直接script引入vue,进行使用时有花括号闪现问

<div id="app">
	<!-- 转义html -->
	<h3>html</h3>
	<!-- 解析 html -->
	<div v-html="html"></div>
	<!-- 转义html -->
	<div v-text="html"></div>

</div>

<script src="./vue.js"></script>
<script>
  new Vue(
    el: '#app',
    data: 
      html:'<a href="http://www.baidu.com/">百度一下</a>'
    
  )
</script>

四、常用指令

指令扩展了html标签的功能、大部分的指令的值是js的表达式,取代了DOM操作。

4.1、v-cloak指令

解决浏览器在加载页面时因存在时间差而产生的“闪动”问题
v-html或v-text它们能够解决闪现,但是有的时候,一些项目在前期没有用它,这时候如果全部去修改,工程量有点大,可以用此指令

# css中设置
[v-cloak] 
  display: none;



# html
<div v-cloak>
   message 
</div>

4.2、v-pre指令

此指令一个性能优化的指令,使用它,可以提升性能。
跳过这个元素和它的子元素的编译过程,跳过大量没有指令的节点会加快编译。以上是关于Vue基础系列(二二)Vue基础--Vue模板语法-vue数据绑定原理-插值语法-指令语法-元素的显示隐藏的主要内容,如果未能解决你的问题,请参考以下文章

Vue基础系列Vue模板语法-插值语法-指令语法

VUE学习-基础(基础语法 & 模板语法)

Vue基础入门讲义-语法基础

Vue架构基础篇-第04章:模板语法

Vue基础(上):MVVM模板语法数据绑定

Vue3基础-模板语法