网博开发者社区

 找回密码
 立即注册
搜索
查看: 186|回复: 0

vue 笔记 part-one

[复制链接]

5

主题

6

帖子

64

积分

老师

积分
64
发表于 2018-9-12 16:04:17 | 显示全部楼层 |阅读模式
本帖最后由 陈华旺 于 2018-11-13 11:06 编辑

Vue-pratOne
1、设计模式1.1、SPA (设计思想)
  • SPA:single page application   单页应用程序
  • 单页:用户在访问页面时,浏览器不会发生跳转,且内容可以更新
    • 主体容器文件


1.2、MVVM(设计思想)
  • mvvm :mode view view-model  模型视图视图模型
    • 核心功能:简化 开发者 对于 DOM 的操作


2、vue简介
  • 框架不叫 vux ,读作 view,渐进式的 javascript框架,实现了大多数的 SPA设计
    • 渐进式:快速学习比较简单,容易入门,引入使用方式,框架使用方式
    • javascript 语法基础:JS基础语法和高级语法


3、页面使用
  • 获取vue的核心文件
  • npm | cnpm   install vue

  <!DOCTYPE html>
  <html lang="en">
  ​
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <script src="../js/vue.js"></script>
      <!--
          vue.js 提供一个全局的 对象构造器 Vue (V是大写的)
          Vue 就是框架的 开始代码
          Vue 实际上是一个方法
  ​
          语法要求:不遵循语法,会直接语法报错,程序无法运行
          约定要求:软件开发时统一遵循的规范,不遵守 程序一样可以运行
                   方法名以小写开通
                   对象构造器函数以大写字母开头
                   _开头的变量 被称之为 私有变量,不建议外部调用
                   options 参数名 取值 一定是 objects
                   arg 一个普通值
                   args... 方法不至一个参数
  ​
          ƒ Vue (options) {
              if ("development" !== 'production' &&
                  !(this instanceof Vue)
              ) {
                  warn('Vue is a constructor and should be called with the `new` keyword');
              }
              this._init(options);
          }
      -->
      <script>
          var info = "新数据"
          window.onload = function () {
              var opt = {
                  // el 表达式  ==> css 的元素选择器的统称
                  //  document.getElementById("app")
                  //  主体功能 就是用于获取 DOM 对象
                  //  主体功能 实际就是DOM的操作
  ​
                  el: "#app",
                  // 数据仓库
                  data: {
                      // 没有属性名称的限制
                      // 所有的属性 都可以在页面直接使用 {{ 属性名 }}获取
                      msg: "测试数据",
                  }
              }
              // 学习VUE使用时,基础语法的学习 只是 在理解和记忆 options可以完成的配置项
              new Vue(opt);
          }
      </script>
  </head>
  ​
  <body>
      <div id="app" class="a">
          <h1>{{ msg }}</h1>
      </div>
  </body>
  </html>3.1、插值表达式
  • 语法:“Mustache”语法 (双大括号)    {{ 变量名 }}
  • 单向数据流:内存中数据发生变化页面也会随之变化  (JS 对于DOM 的操作)
  • 对于VUE项目 ,插值表达式 获取的是 Vue 构建的对象 所提供的数据仓库中的变量
    • vue对象对应的DOM容器 中使用的变量 ,一定是该对象中数据仓库中的变量

  • 组件基础 - 数据仓库: data 对于JS代码而言只是 一个 对象中的属性
    • vue的语法设计中 data 属性具有仓库的特性
    • 在对应的容器中(DOM) 以 {{ }} 方式 直接可以获取 data中定义的属性


  var obj = {
      data
  }
  • 插值表达式带来的疑问
    • HTML也中 的标签可以 定义那些数据类型? 只能接收字符串数据
    • 插值表达式将 提供的 数据 进行 toString() 转换 输出到页面
    • vue 重写了toString 方法  stringify()
    • 如果 属性的值是 null,undefined  页面直接输出空字符串

  • Vue 的插值 允许直接调用 JS的 内置对象 Math;
    • 在vue仓库中定义的变量 一定 优先于 JS 内置对象和方法的
    • 定义属性 ,避免出现 JS内置对象名称或内置方法名

  • Vue 的插值 允许直接调用对应数据类型的内置方法;
    • 插值表达式 在向页面输出之前,会保留数据的类型

  • 插值表达式允许定义匿名变量
  • 匿名变量为插值表达式赋予 运算特性
    • 字符串拼接
    • 四则运算
    • 逻辑运算
    • 比较运算
    • 三元运算|三目运算

  • 插值表达式不会解析 HTML 的字符串代码
    • artTemplate 的插值表达式 如何解析标签


  <!DOCTYPE html>
  <html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <script src="../js/vue.js"></script>
      <script>
          var info = "新数据"
          window.onload = function () {
              var opt = {
                  // el 表达式  ==> css 的元素选择器的统称
                  //  document.getElementById("app")
                  //  主体功能 就是用于获取 DOM 对象
                  //  主体功能 实际就是DOM的操作
  ​
                  el: "#app",
                  // 数据仓库
                  data: {
                      // 没有属性名称的限制
                      // 所有的属性 都可以在页面直接使用 {{ 属性名 }}获取
                      msg: "测试数据",
                      arr: [1, 2, 3, 4, 5, 6],
                      num:1000,
                      flag:true,
                      user:{
                          name:"tom",
                          age:23
                      },
                      arg1:null,
                      arg2:undefined,
                      arg3:0,
                      arg4:"",
                      arg5:NaN
                  }
              }
              // 学习VUE使用时,基础语法的学习 只是 在理解和记忆 options可以完成的配置项
              new Vue(opt);
          }
      </script>
  </head>
  ​
  <body>
      <div id="app" class="a">
          <h1>{{ msg }}</h1>
          <h1>{{ num }}</h1>
          <h1>{{ flag }}</h1>
          <h1>{{ arr }}</h1>
          <h1>{{ user }}</h1>
          <h1>{{ arg1 }}</h1>
          <h1>{{ arg2 }}</h1>
          <h1>{{ arg3 }}</h1>
          <h1>{{ arg5 }}</h1>
          <input type="text">
          <!-- <h1>{{ info }}</h1> -->
          <!-- <input type="text" v-model="msg">
          <ul>
              <li v-for="(v,i) in arr">{{ v }}</li>
          </ul> -->
      </div>
  </body>
  </html>4、API的操作4.1、全局配置
  • 为当前vue项目 设置 全局的 环境配置 和vue对象没有关系
    • 禁用 调试工具
    • 禁止 输出调试信息
    • 设置常见错误提示

  • 语法:Vue.config.属性
    • 全局配置 一定是在 vue.js vue.min.js  引入后调用的
    • 全局配置一定是在 vue 对象 构成之前调用 new Vue()


4.2、指令
  • 为开发者 在页面提供 功能性描述属性,指令被应用于HTML标签上
    • 功能:通过JS 对于DOM的相关操作
    • 描述:对指令功能的解释( v-text 使用DOM的 innerText 属性)
    • 属性:是HTML的 可以被vue解析的 自定义属性

  • 语法:<h1  指令属性  v-text  ></h1>
  • 完整语法:v-指令名 [:参数] [.修饰符.修饰符……]  [ =变量|简单表达式|匿名变量|函数 ]
    • 指令后的 :表示 该指令需要一个 相关参数符号,用于限制指令的触发时机
    • 参数后面的  .  表示的是为指令增加相关修饰符,修饰 指令的功能

  • 特性:(个人总结)
    • 无痕迹


4.2.1、v-text
  • 文本写入指令,通过调用对应DOM的 innerText 属性将变量值写入到属性中
    • 就是 {{  }} 另外一种写法


4.2.2、v-html
  • 文本写入并解析,通过调用对应DOM的 innerHTML 属性将变量值写入到属性中

4.2.3、v-pre
  • 保留vue的语法格式,让指定标签 的内部的 所有的 vue语法全部失效
  • boolean类型指令,不用定义值,写为true 不写为false

  <!DOCTYPE html>
  <html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <script src="../js/vue.js"></script>
  </head>
  <body>
      <h1 class="aa aa" id=1>测试标签</h1>
      <pre>
          asdasd
      </pre>
      <input type="text" disabled>
      <div id="app">
          <h3>{{ msg }}</h3>
          <h3 class="aa" v-text=" msg+'aaa'+10000 " ></h3>
          <h3>{{ strDom }}</h3>
          <h3 v-html=" strDom "></h3>
          <h3 v-pre>{{ msg }}是vue通过插值表达时方式获取msg的值
              <p v-html="strDom"></p>
          </h3>
      </div>
      <script>
          new Vue({
              el:"#app",
              data:{
                  msg:"数据",
                  strDom:"<a >百度</a>"
              }
          })
      </script>
  </body>
  </html>4.2.4、v-once
  • Boolean类型指令,对指定的标签内部 的所有 vue语法 做一次性渲染
    • vue语法只会被执行一次


4.2.5、v-cloak
  • 隐藏没有被编译的DOM元素
  • css 选择器指令,需要配合css属性选择器使用

  [v-cloak]{
      dispaly:none;
  }4.2.6、v-on
  • vue事件绑定,为vue指定的 容器中的 DOM元素绑定 JS事件
    • html的绑定方式 :<span><span>
      • 为click事件注入属性值

    • vue事件绑定使用的 是 JS 方式:addEventListener(**事件名**)
      • 事件名:JS 对于dom的内置监听事件的名称定义
        • click change input keyup ……



  • 语法:v-on:事件名.修饰符= 事件方法调用|事件命名
    • 绑定事件指向的方法 一定是 vue实例中 方法仓库所定义的函数
    • 方法仓库:vue对象构建时  methods 属性


  <span v-on:click="方法名()"></span>
  • vue事件绑定时的 this
    • 页面中使用 v-on方式绑定的事件    传入的this执向与window对象,调用的方法内部是 当前vue实例

  • vue事件绑定的事件源
    • vue v-on指定事件时,事件调用的括号中具有和插值表达式相同的特性
    • vue 内置一个对事件源封装的对象  $event


  <!DOCTYPE html>
  <html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <script src="../js/vue.js"></script>
      <script>
          function show() {
              console.log("show方法");
          }
          var fun = function () {
              console.log(this);
          }
          function printValue(arg,e) {
              console.log(this,arg,e);
          }
          function pren(e){
              // 停止默认事件调用
              e.preventDefault();
          }
      </script>
  </head>
  <body>
      <hr>
      <input type="button" value="事件绑定" onclick="show()">
      <!-- event:事件源对象 -->
      <input type="text" onkeyup="printValue(this.value,event)">
      <a  >百度</a>
      <a href="" onclick="return false">百度</a>
      <a href="" onclick="pren(event)">百度</a>
      <!-- <input type="reset">
      <input type="submit"> -->
      <hr>
      <div id="app">
          普通事件:<input type="button" value="事件绑定" v-on:click="show()"><br>
          事件传值<input type="button" value="事件绑定" v-on:click="print( 'tom' )"><br>
          事件名<input type="button" value="事件绑定" v-on:click="print"><br>
          this对象<input type="text" v-on:keyup="printValue(this)"><br>
          <hr>
          <h3>vue v-on指定事件时,事件调用的括号中具有和插值表达式相同的特性</h3>
          <h3> vue 内置一个对事件源封装的对象  $event  </h3>
          事件源<input type="text" v-on:keyup="printEvent(event)"><br>
          事件源<input type="text" v-on:keyup="printEvent($event)"><br>
          <hr>
          <h3>阻止默认事件</h3>
          <a  v-on:click="pre($event)">百度</a>
      </div>
  </body>
  <script>
      new Vue({
          el: "#app",
          data:{
              event:"自定义变量"
          },
          methods: {
              // key:value
              // key 自定义方法名称
              // value 方法的值(函数)
              print: function (name) {
                  console.log("print:", name);
              },
              // ES6 语法中 允许 简化 方法参数定义
              // printValue:function(){},
              printValue(arg) {
                  console.log("printValue方法",this,arg);
              },
              printEvent(e){
                  console.log(e);
                  console.log(e.target.value);
              },
              pre(e){
                  e.preventDefault();
              }
          }
      })
  </script>
  </html>
  • v-on的高级用法
  • 1、指令修饰符vue提供的功能限制符
    链式操作特性
    链式修饰符中 后续的修饰功能,只有在前一个功能被触发后触发
    • .stop - 调用 event.stopPropagation()。 阻止冒泡事件
    • .prevent - 调用 event.preventDefault()。  阻止默认事件触发
    • .self - 只当事件是从 v-on 绑定的元素本身触发时才触发回调。
    • .once - 只触发一次回调。(修饰的事件触发一次后直接被销毁)

    监听是触发的按键
    按键的监听 不受 链式先后影响
    • .left - (2.2.0) 只当点击鼠标左键时触发|键盘的左键。
    • .right - (2.2.0) 只当点击鼠标右键时触发|键盘的右键。
    • .middle - (2.2.0) 只当点击鼠标中键时触发。
    • .up - 键盘的上键
    • .down - 键盘的下键
    • .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。

    模块化相关
    • .native - 监听组件根元素的原生事件=将组件标签上定义的事件透传给 子组件的根标签
    • .passive - (2.3.0) 以 { passive: true } 模式添加侦听器
    • .capture - 添加事件侦听器时使用 capture 模式。

  • 简写方式:以 @ 代替 v-on  ==>  @事件名.修饰符.…… = 方法

  • 事件绑定取值,可以直接通过 简单 JS 操作数据仓库中的变量
  • 多事件统一绑定:可以以对象的方式完成多事件绑定
    • 在定义匿名对象时,需要前后加空格
    • 定义事件方法不能带有()

  • 多方法统一绑定:可以在对象绑定固定事件时,为该事件赋值多个方法
    • 以匿名数组的方式,为同一个事件 绑定多个函数
    • 数组中的函数 需要携带 ()


4.2.7、v-if v-else v-else-if
  • 组合指令:存在一两个指令 在没有前置指令的情况下无法使用
  • 分支语法 : 控制标签的渲染(页面应该   创建删除    那个标签)走向
  • 语法:v-if="可以用作判断的 变量|表达式 " ==> js中几乎所有的变量都可以用作判断

  if(){
      
  }else{
      
  }4.2.8、v-show
  • 分支语法:控制标签的渲染( 页面应该   显示或隐藏   那个标签    )走向
    • 通过控制 CSS 的 display 完成切换的

  • 语法:v-show="可以用作判断的 变量|表达式 " ==> js中几乎所有的变量都可以用作判断

  <!DOCTYPE html>
  <html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <script src="../js/vue.js"></script>
  </head>
  <body>
      <div id="app">
          <h3 id="a" v-if=" flag ">首页</h3>
          <h3 id="b" v-if=" !flag ">分类页</h3>
          <hr>
          <h3 id="c" v-show=" flag ">首页</h3>
          <h3 id="d" v-show=" !flag ">分类页</h3>
          <input type="button" value="切换页面" @click=" flag = !flag ">
          <hr>
          <input type="button" value="-" @click=" num-=1 ">
          <input type="button" value="+" @click=" num+=1 ">
          <h3>
              {{ num }}:
              <!--
                  组合指令一定是连续性定义
               -->
              <!-- <span v-if=" num < 0 ">小于0</span> -->
              <!-- <span style="display:none"></span> -->
              <!-- <span v-else-if=" num==0 ">等于0</span>
              <span v-else>大于0</span> -->
  ​
              <span v-if=" num < 0 ">小于0</span>
              <span v-if=" num==0 ">等于0</span>
              <span v-if=" num > 0 ">大于0</span>
          </h3>
      </div>
  </body>
  <script>
      new Vue({
          el:"#app",
          data:{
              flag:true,
              num:0
          }
      })
  </script>
  </html>4.2.9、v-for
  • 实现页面中元素的循环,根据可以被循环的数据的数量 创建对应的 元素标签
  • 语法:v-for="临时变量 in 可循环值"
    • 临时变量 只循环到的值

  • 语法:v-for=" ( 临时变量1,临时变量2,临时变量3  )  in 可循环值"
    • 临时变量1 :循环到的值;数值-累加值
    • 临时变量2: 数组|数值-循环的下标;对象-循环的key(属性名)
    • 临时变量3 :当循环的值是对象类型时,该变量才生效,循环计数器 从0开始

  • 临时变量:具有Vue data 中定义属性的 所有基本特点
      <!--
          例子
          临时变量的作用域 在 整个标签范围上  (标签的属性范围,标签的正文范围)
      -->
      <span v-for=" v in arr " v-text=" v ">
          {{ v }}
      </span>
  // js for in 循环
  for(var i in arr){
      
  }4.2.10、v-bind
  • 属性绑定
    • HTML 属性绑定:W3C规范在 标签上具有一定意义属性
    • DOM 属性绑定:元素被JS转换为DOM对象后,所包含的所有属性

  • v-bind 指令只能直接完成对 HTML 和 自定属性的绑定操作
  • 语法:v-bind:属性= 值
  • 修饰符:.prop 描述该属性为dom属性绑定
    • 当绑定的dom属性为 驼峰命名法时,需要转换为 连字符命名法
    • innerHTEM  ==>  inner-html     className ==>  class-name
    • 不是所有的DOM属性都可以绑定,存在一些只读的DOM属性

  • 简写方式:v-bind:属性=值  ==>  :属性=值

  <!DOCTYPE html>
  <html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <style>
          table{
              border-collapse: collapse;
          }
          td{
              border: 1px solid black;
              width: 20px;
              height: 20px;
          }
      </style>
      <script src="../js/vue.js"></script>
  </head>
  <body>
      <input href type="text" value="">
      <div value="" ></div>
      <a href=""></a>
      <H1>测试</H1>
      <hr>
      <div id="app">
          <table>
              <tr>
                  <!-- <td v-bind:colspan=" colspan "></td> -->
                  <td v-bind:colSpan=" colspan "></td>
  ​
              </tr>
              <tr>
                  <td></td>
                  <td></td>
                  <td></td>
                  <td></td>
                  <td></td>
                  <td></td>
              </tr>
          </table>
          <input type="button" value="-" @click=" colspan-=1 ">
          <input type="button" value="+" @click=" colspan+=1 ">
          <hr>
          <h3 v-bind:innerHTML=" msg "></h3>
          <h3 v-bind:innerHTML.prop=" msg "></h3>
          <h3 v-bind:inner-html.prop=" msg "></h3>
      </div>
  </body>
  <script>
      new Vue({
          el:"#app",
          data:{
              colspan:2,
              msg:"测试数据"
          }
      })
  </script>
  </html>
v-bind的 三种特殊属性操作
  • boolean属性
    • v-bind主要完成是 boolean属性在标签上 定义 与否
    • v-bind绑定boolean类型 时 vue 对数值 是直接使用 true
    • 出数值类型以外,其它类型以JS的 转换规则 转换为 boolean类型进行判断操作


  <!DOCTYPE html>
  <html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <script src="../js/vue.js"></script>
  </head>
  <body>
      <div id="app">
          <!--
              boolean属性的操作
                  - v-bind主要完成是 boolean属性在标签上 定义 与否
          -->
          <input type="text"><br>
          <input type="text" v-bind:disabled=" flag "><br>
          <input type="button" value="文本框的启用和禁用" @click=" flag=!flag">
          <hr>
          <input type="text" @input="setMsg($event)">
          <input type="text" v-bind:disabled=" !msg ">
          <input type="text" v-bind:disabled=" num==0?false:true ">
      </div>
  </body>
  <script>
      new Vue({
          el:"#app",
          data:{
              // true表示disabled 写入  ==> 文本框的禁用
              // flase表示 disabled 不写入 ==> 文本框的启用
              flag:true,
              // “”字符串 JS 会转换为 false
              // 非“”字符串 JS 会转换为 true
              msg:"",
              // v-bind绑定boolean类型 时 vue 对数值 是直接使用 true
              num:0
          },
          methods:{
              setMsg(e){
                  this.msg = e.target.value;
              }
          }
      })
  </script>
  </html>
  • class属性的操作
    • 1、字符串拼接,不会删除原有的样式,直接在后面进行拼接操作
    • 2、取值为 对象 时,可以通过boolean类型数据进行 类样式的操作
    • 3、取值为数组时,循环数组中的元素 自动完成 样式补充


  <!DOCTYPE html>
  <html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <style>
          .fc{
              color: red;
          }
          .fs{
              font-size: 20px;
          }
          .bc{
              background-color: #cccccc;
          }
          .border{
              border: 1px solid blue;
          }
      </style>
      <script src="../js/vue.js"></script>
  </head>
  <body>
      <div id="app">
          <p class="fc fs bc border">测试数据</p>
          <!--
              v-bind:class
                  1、字符串拼接,不会删除原有的样式,直接在后面进行拼接操作
                  2、取值为 对象时,可以通过boolean类型数据进行 类样式的操作
                  3、取值为数组时,循环数组中的元素 自动完成 样式补充
           -->
          <p class="bc" v-bind:class=" strClass ">测试数据</p>
          <input type="button" value="添加背景颜色" @click=" strClass += ' bc' ">
          <p v-bind:class=" objClass ">测试数据</p>
          <input type="button" value="color" @click=" objClass.fc = !objClass.fc ">
          <input type="button" value="fontSize" @click=" objClass.fs = !objClass.fs  ">
          <input type="button" value="backgroundColor" @click=" objClass.bc = !objClass.bc  ">
          <input type="button" value="border" @click=" objClass.border = !objClass.border  ">
          <p v-bind:class="arrClass">测试数据</p>
           <input type="button" value="添加背景" @click=" addBc() ">
          <p>测试数据</p>
         
      </div>
  </body>
  <script>
      new Vue({
          el:"#app",
          data:{
              strClass:"fc",
              objClass:{
                  // key 为 css类样式名称
                  // value 当前样式的应用方式 boolean  true样式加载 false 样式删除
                  fc:true,
                  fs:true,
                  bc:false,
                  border:false
              },
              arrClass:["fc","fs"]
          },
          methods:{
              addBc(){
                  this.arrClass.push("bc");
              }
          }
      })
  </script>
  </html>
  • style 属性的操作
    • 取值为string() 绑定的是HTML的属性
    • 取值Object() 直接完成对于DOM的实际赋值
    • 取值 对象数组 Array(object)


  <!DOCTYPE html>
  <html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <script src="../js/vue.js"></script>
  </head>
  <body>
      <div id="app">
          <!--
              {
                  color:'red',
                  background-color: '#cccccc'
              }
              js style 对象的 属性 赋值
           -->
           <!--
              v-bind:style
                  - 取值为string(*) 绑定的是HTML的属性
                  - 取值Object(*) 直接完成对于DOM的实际赋值
                  - 取值 对象数组 Array(object)
              json 数据
              1、对象数组 :json数据根节点为数组类型,内部的数据为 对象类型 [{},{}……]
              2、数组对象 :json数据的根节点为对象类型,内部属性以数组元素构成 {data:[]}
              3、混合类型 :{data:[{},{}],status:{}}
            -->
          <h3 style="color:red;background-color: #cccccc">原生style</h3>
          <h3 v-bind:style=" strStyle ">vue属性绑定方式</h3>
          <h3 v-bind:style=" objStyle ">vue属性绑定方式</h3>
          <input type="color" @change=" objStyle.color=$event.target.value ">
          <input type="color" @change=" objStyle.backgroundColor=$event.target.value ">
          <h3 v-bind:style=" arrStyle ">vue属性绑定方式</h3>
      </div>
  </body>
  <script>
      new Vue({
          el:"#app",
          data:{
              strStyle:"color:red;background-color: #cccccc",
              objStyle:{
                  // key 内置的 css样式名称 - DOM的样式名称
                  // value 当前样式的 合法 值
                  color:"red",
                  backgroundColor:"#cccccc"
              },
              arrStyle:[
                  // 数据类型的变化,主要是为了可以使用当前类型的方法
                  {
                      // key 内置的 css样式名称 - DOM的样式名称
                      // value 当前样式的 合法 值
                      color:"red"
                  },
                  {
                      backgroundColor:"#cccccc"
                  },
              ]
          }
      })
  </script>
  </html>
上述的所有指令和插值表达式==> 单向数据操作
  • 当发现 内存中数据发生变动 ,会直接影响页面中的 显示结果

4.2.11、v-model
  • 双向数据指令:数据的双向绑定
    • 当发现 内存中数据发生变动 ,会直接影响页面中的 显示结果
    • 页面数据被用户更改时,内存中的数据也会随之变化

  • 修饰符
    • .lazy   懒触发  将 input事件 转换为 change事件
    • .trim  调用文本工具的  trim 方法
    • .number     将输入的字符串  尝试转换为   数值  

  • v-model的功能只能适用于表单标签
    • 单行输入文本
    • 多行输入文本域
    • 单选按钮
    • 复选按钮
    • 下拉列表

  • 双向数据操作的 基本原理
    • v-model指令实际上就是简化后的属性绑定和事件绑定


  <!-- 属性绑定和事件的绑定  -->
  <input type="text" :value=" msg " @input=" msg=$event.target.value ">  <!DOCTYPE html>
  <html lang="en">
  ​
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <script src="../js/vue.js"></script>
  </head>
  ​
  <body>
      <!-- <input type="text" value="aa"> -->
      <div id="app">
          <h3>{{ msg }}</h3>
          <input type="text" :value=" msg " @input=" msg=$event.target.value ">
          <br>
          <input type="text" :value=" msg " @input=" msg=$event.target.value ">
          <hr>
          lazy:<input type="text" v-model.lazy=" msg ">
          <hr>
          <!--
              1、单行文本框 的双向数据绑定
                  a、为当前单行文本框绑定 value属性
                  b、为当前单行文本框绑定 对应事件
              分类:
                  + 对于所有基于单行文本功能的  标签 均采用相关特性
              警告
                  + v-model 在单行文本上不能和 v-bind:value 同时出现
          -->
          trim:<input type="text" v-model.trim=" msg "><br>
          number:<input type="text" v-model.number=" msg "><br>
  ​
          <p :style="{ color:color }">测试</p>
          <input type="color" v-model=" color "><br>
          <p>{{ num }}</p>
          <input type="range" max="10" min="0" v-model=" num "><br>
          <p>{{ time }}</p>
          <input type="date" v-model=" time "><br>
          <hr>
          <!--
              2、多行文本域
                  多行文本域的操作方式和 单行文本框的操作方式一致
                  + js <===> html
                  - js转换 第一回主动以 innerHTML的值作为 DOM的value属性值
                  - textarea HTML 没有value属性
           -->
          <p>{{ info }}</p>
          <textarea cols="10" rows="3">asdasdasd</textarea>
          <textarea cols="10" rows="3" :value=" info " @input=" info=$event.target.value"></textarea>
          <textarea cols="10" rows="3" v-model="info"></textarea>
          <hr>
          <!--
              3、单选按钮
                  a、获取当前DOM是否绑定 value属性 ,如果没有绑定 赋值 null
                  b、绑定 checked 属性 控制 当前的单选按钮的选择状态
                      + 以当前DOM的value值和 变量值 == 比较
                  c、绑定了 change 事件,用于监听 当前 选择框的操作,同时修改 绑定的 变量
           -->
          <!-- <form action="#" method="get">
               <input type="radio" name="sex">
               <input type="submit" value="提交">
           </form> -->
          <!-- <input type="radio"
              :value=" el.getBindingAttr('value')?el.value:null "
              :checked=" el.getBindingAttr('value')?el.value:null "
              @change=" radioData=$event.target.value "
          > -->
          <input type="radio" v-model=" radioData ">
          <input type="radio" value="m" v-model=" radioData ">
          <hr>
          <p>技能选择</p>
          <div v-for="(item, index) in skill">
              <label>{{ item.text }}</label>
              <input type="radio" :value=" item.value " v-model="skillUse">
          </div>
          <hr>
          <!--
              4、复选按钮
                  完成数据绑定时
                  绑定的变量为 非数组类型:记录的是 true-value=true 和 false-value=false 的属性
                  绑定的变量为 数组类型时:在数组内增加或删除操作的 复选按钮的 value值,是无序操作记录
                      没有提供value属性,默认记录的值为 null
          -->
          <input type="checkbox" true-value="aaa" false-value="bbb" v-model="checkData1">
          <input type="checkbox" value="b" v-model="checkData2">
          <hr>
          <input type="checkbox" v-model="flag">
          <input type="button" value="提交" :disabled=" !flag ">
          <hr>
          <div v-for="(item, index) in skill">
              <label>{{ item.text }}</label>
              <input type="checkbox" :value=" item.value " v-model="skillCheck">
          </div>
          <hr>
          <div v-for="(item, index) in skill">
              <label>{{ item.text }}</label>
              <input type="checkbox" v-model="skillCheck">
          </div>
          <hr>
          <div v-for="(item, index) in skill">
              <label>{{ item.text }}</label>
              <input type="checkbox" v-model=" item.state ">
          </div>
          <hr>
          <div>
              <input type="checkbox"><br>
              <input type="checkbox">
              <input type="checkbox">
              <input type="checkbox">
              <input type="checkbox">
          </div>
          <hr>
          <!--
          下拉列表
              html select 标签 不存在 value属性
          v-model 对于下拉列表只被用于 select 标签上
          a、绑定 selectIndex属性用于控制选择
          b、绑定change事件 用于切换操作
          c、绑定value属性用于获取值
      -->
          <!--
          <select :select-index="selectData" @change>
       -->
          <select v-model="selectData">
              <option value="">请选择</option>
              <option value="a">aa</option>
              <option value="b">bb</option>
              <option>cc</option>
              <option>dd</option>
          </select>
  ​
      </div>
   
  </body>
  <script>
      new Vue({
          el: "#app",
          data: {
              msg: "测试数据",
              color: "#cccccc",
              num: 2,
              time: "2017-01-01",
              info: "aaaaa",
              radioData: "",
              skillUse: "",
              skill: [
                  { text: "HTML", value: "html", state: false },
                  { text: "JS", value: "javascript", state: false },
                  { text: "VUE", value: "vue", state: false }
              ],
              checkData1: "",
              checkData2: [],
              flag: false,
              skillCheck: [],
              test: null,
              selectData: ""
          }
      })
  ​
  ​
  </script>
  ​
  </html>源码解析    if (el.component) {
      genComponentModel(el, value, modifiers);
      // 判断运行时该标签是否存在指令 v-model
      return false
    } else if (tag === 'select') {
      genSelect(el, value, modifiers);
    } else if (tag === 'input' && type === 'checkbox') {
      genCheckboxModel(el, value, modifiers);
    } else if (tag === 'input' && type === 'radio') {
      genRadioModel(el, value, modifiers);
    } else if (tag === 'input' || tag === 'textarea') {
      genDefaultModel(el, value, modifiers);
        // 完成 普通文本框和多行文本域的操作
    } else if (!config.isReservedTag(tag)) {
      genComponentModel(el, value, modifiers);
      // component v-model doesn't need extra runtime
      return false
    } else {
      warn$1(
        "<" + (el.tag) + " v-model=\"" + value + "\">: " +
        "v-model is not supported on this element type. " +
        'If you are working with contenteditable, it\'s recommended to ' +
        'wrap a library dedicated for that purpose inside a custom component.'
      );
    }  ​
  function genDefaultModel (el,value, modifiers) {
      // el 被绑定的 DOM元素
      // value 输入的值
      // modifiers 指令携带的修饰符
    var type = el.attrsMap.type;
  ​
     // 单行文本框 完成 v-model 是否同样定义了 v-bind:value
    // warn if v-bind:value conflicts with v-model
    // except for inputs with v-bind:type
    {
      var value$1 = el.attrsMap['v-bind:value'] || el.attrsMap[':value'];
      var typeBinding = el.attrsMap['v-bind:type'] || el.attrsMap[':type'];
      if (value$1 && !typeBinding) {
        var binding = el.attrsMap['v-bind:value'] ? 'v-bind:value' : ':value';
        warn$1(
          binding + "=\"" + value$1 + "\" conflicts with v-model on the same element " +
          'because the latter already expands to a value binding internally'
        );
      }
    }
      // <--------
    var ref = modifiers || {};
    var lazy = ref.lazy;
    var number = ref.number;
    var trim = ref.trim;
    var needCompositionGuard = !lazy && type !== 'range';
    var event = lazy
      ? 'change'
      : type === 'range'
        ? RANGE_TOKEN
        : 'input';
  ​
    var valueExpression = '$event.target.value';  // dom的页面输入值
    if (trim) {
      valueExpression = "$event.target.value.trim()";
    }
    if (number) {
      valueExpression = "_n(" + valueExpression + ")";
    }
  ​
    var code = genAssignmentCode(value, valueExpression); // 根据参数动态生成 VUE 执行 源码
    if (needCompositionGuard) {
      code = "if($event.target.composing)return;" + code; // 拦截多余的操作
    }
  ​
    addProp(el, 'value', ("(" + value + ")")); // 添加相关 DOM 属性值
    addHandler(el, event, code, null, true);  // 添加事件关联  input 事件
    if (trim || number) {
      addHandler(el, 'blur', '$forceUpdate()');
    }
  }  function genRadioModel (el,value,modifiers) {
    var number = modifiers && modifiers.number;
      
    var valueBinding = getBindingAttr(el, 'value') || 'null';
      // 判断dom是否绑定了value属性,如果没有默认设置为null
      
    valueBinding = number ? ("_n(" + valueBinding + ")") : valueBinding;
      
    addProp(el, 'checked', ("_q(" + value + "," + valueBinding + ")"));
      // 更加value绑定 checked属性
    addHandler(el, 'change', genAssignmentCode(value, valueBinding), null, true);
      // 单选按钮变更时,修改对应内存值
  }  function genCheckboxModel (el,value,modifiers) {
    var number = modifiers && modifiers.number;
      
    var valueBinding = getBindingAttr(el, 'value') || 'null';
    var trueValueBinding = getBindingAttr(el, 'true-value') || 'true';
    var falseValueBinding = getBindingAttr(el, 'false-value') || 'false';
      
      // 完成属性绑定操作
     // 被绑定的数据变量 是数组类型或不是数组类型 在处理方式上不一样
    addProp(el, 'checked',
      "Array.isArray(" + value + ")" +
      "?_i(" + value + "," + valueBinding + ")>-1" + (
        trueValueBinding === 'true'
          ? ("" + value + ")")
          : (":_q(" + value + "," + trueValueBinding + ")")
      )
    );
    addHandler(el, 'change',
      "var $$a=" + value + "," +
          '$$el=$event.target,' +
          "$$c=$$el.checked?(" + trueValueBinding + ")" + falseValueBinding + ");" +
      'if(Array.isArray($$a)){' +
        "var $$v=" + (number ? '_n(' + valueBinding + ')' : valueBinding) + "," +
            '$$i=_i($$a,$$v);' +
        "if($$el.checked){$$i<0&&(" + (genAssignmentCode(value, '$$a.concat([$$v])')) + ")}" +
        "else{$$i>-1&&(" + (genAssignmentCode(value, '$$a.slice(0,$$i).concat($$a.slice($$i+1))')) + ")}" +
      "}else{" + (genAssignmentCode(value, '$$c')) + "}",
      null, true
    );
  }   "Array.isArray(" + value + ")?" +   // Array.isArray(变量)?   == 变量是不是一个数组
       // 如果是数组
   "_i(" + value + "," + valueBinding + ")>-1"  // value,valueBinding 是不是绑定了
   + (trueValueBinding === 'true'?   
  ("" + value + ")")
  // 当  Array.isArray(变量) 不成立时 返回 DOM绑定 value  邦定的 true-value
  : (":_q(" + value + "," + trueValueBinding + ")")   function genSelect (
    el,
    value,
    modifiers
  ) {
    var number = modifiers && modifiers.number;
    var selectedVal = "Array.prototype.filter" +
      ".call($event.target.options,function(o){return o.selected})" +
      ".map(function(o){var val = \"_value\" in o ? o._value : o.value;" +
      "return " + (number ? '_n(val)' : 'val') + "})";
  ​
    var assignment = '$event.target.multiple ? $$selectedVal : $$selectedVal[0]';
    var code = "var $$selectedVal = " + selectedVal + ";";
    code = code + " " + (genAssignmentCode(value, assignment));
    addHandler(el, 'change', code, null, true);
  }


23b8f90594de489f87851c9e382cb3d5_th.jpeg
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|网博开发者社区 ( 苏ICP备05021715号-1 )

GMT+8, 2018-11-16 15:43 , Processed in 0.087656 second(s), 29 queries .

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表