vue学习笔记—vue基础(二)

vue学习笔记—vue基础(二)

参数设置

从一个Vue的实例开始的
使用Vue创建一个应用的时候,需要传入一些必要的配置参数
参考:api -> 选项
选项包含分类:

  • 1.数据
    如: data : 设置vue的数据(观察数据),vue应用中所需要使用的数据可以放置在该选项中,同时vue会监听和观察data中的变化;
      放置应用中所需要使用到的元数据,开始就能确定的数据
    methods: 保存vue应用中所需要使用到函数
    1. DOM
      如:el : 设置vue应用根节点
    1. 生命周期钩子函数
    1. 资源
    1. 组合
    1. 其他

相关概念

  • 视图
    我们看到的页面
  • 模板
  • 产生页面的结构
  • 模板语法:把实例中的数据和页面进行绑定的一种手段

    1. 插值表达式
      • {{表达式}} => 大胡子语法
      • 注意:该语法是解析安全的(因为会将数据做为纯文本解析,防止xss)

    XSS:

    xss:跨站脚本攻击(Cross Site Scripting)。。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。

(1) vue内部对大通过胡子语法使用的数据做文本解析,其内部实现原理:

<code>
    <textarea id="content" cols="30" rows="10"></textarea>
    <ul></ul>

<!--<p>
    &lt;span&gt;aaaa&lt;/span&gt;
    &nbsp;
    &copy;
</p>-->

<script>
    var content = document.querySelector('#content');
    var ul = document.querySelector('ul');

    content.onblur = function() {
        var li = document.createElement('li');
        <!--将用户提交的数据先进行处理,将HTML标签中的“<”和“>”替换成HTML实体字符,
        这样浏览器就不会误将它认为是HTML标签。处理完之后,再将用这些数据展示在页面。-->
        li.innerHTML = content.value.replace(/<|>/g, ($0) => {
            if ($0 == '<') {
                return '&lt;'
            }
            if ($0 == '>') {
                return '&gt;'
            }
        });
        ul.appendChild(li);

    }

</script>
</code>

HTML实体字符

以实体代替与HTML语法相同的字符,避免浏览解析错误。

(2) 差值表达式的纯文本解析与v-html。

<code>
    <div id="app">
        <div>{{content}}</div>
        <div v-html="content"></div>
        <img src="{{logo}}" />//报错
        <img v-bind:src="logo" />
        <img v-bind:src="'http://miaov.com/static/normal/images/index/mLogo.' + 'png'" alt="">
    </div>
    <script>
         var app = new Vue({
            el: '#app',
            data: {
                title: '打招呼',
                content: '<p>大家好!http://www.baidu.com</p>',
                logo: 'http://miaov.com/static/normal/images/index/mLogo.png'
            }
        });
    </script>
</code>

注意:

  • <div>{{content}}</div>渲染到页面是”<p大家好!http://www.baidu.com</p>“;而对于<div v-html="content"></div>来说,渲染到页面是 “大家好!http://www.baidu.com”,即p标签被解析了。

  • <img src="{{logo}}" />“这样写会报错,“src=”{{logo}}”: Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead. For example, instead of <div id="{{ val }}">, use

    .”


指令

  • 概念:
    • 是一个 v- 前缀的特殊属性,指令的使用方式是以html标签属性形式存在的
    • 指令有对应的值,值是以表达式的形式存在的
    • 指令的作用:根据指令的值动态的影响指令所在的html标签的表现与行为
    • vue中所有内置指令: api-指令
  • 指令:

    • v-text:更新元素的文本内容(数据解析出来是纯文本),相当于差值表达式的作用
      <h2 v-text="'标题是:' + title"></h2>,相当于{{title}}。
    • v-html:更新元素的 innerHTML。
      关于v-text,差值表达式与v-html的区别,上文中的例子可以说明。
    • v-show:
      <h2 v-show="false">大家好</h2>

      根据表达式之真假值,切换元素的 display CSS 属性。

    • v-if:如果表达式的值为false,该元素就不存在(HTML结构不存在)
      <h2 v-if="true">大家好2</h2>

      根据表达式的值的真假条件渲染元素。

    • v-for
      列表渲染:

      • (1) 数组或字符串的v-for:
        • 第一个参数:item 是数组元素迭代的别名;
        • 第二个参数:当前项的索引。
          <li v-for="v,k in 'miaov'">{{v}} - {{k}}</li>
      • (2) 对象的v-for:
        • 第一个参数:item是对象键值迭代的别名;
        • 第二个参数:当前键值对应的键名;
        • 第三个参数:当前项的索引。
          <li v-for="v,k,i in {left:100,top:200}">{{v}} - {{k}} - {{i}}</li>
      • (3) key

      当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。
      为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有的且唯一的 id。
      建议尽可能在使用 v-for 时提供 key,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。

      <code>
          <button @click="sort">排序</button>
          <ul id="list">
              //用 v-bind 来绑定key动态值 (在这里使用简写)
              <li :class="v" v-for="v,k in arr" :key="k">{{v}} -- {{k}}</li>
          </ul>
      </code>
      
    • (4) 数组更新检测

      由于 JavaScript 的限制,Vue 不能检测以下变动的数组:
      (1) 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
        解决方案:
        // Vue.set
        Vue.set(example1.items, indexOfItem, newValue)
        // Array.prototype.splice
        example1.items.splice(indexOfItem, 1, newValue)
      (2) 当你修改数组的长度时,例如:vm.items.length = newLength
        解决方案:
        example1.items.splice(newLength);

  • v-on:

    • 参数:event,事件名;
    • 修饰符:

      • 写法:
        (1) 指令.修饰符;
        (2) 指令:参数.修饰符
      • 修饰符举例:
        .stop - 调用 event.stopPropagation()。
        .prevent - 调用 event.preventDefault()。
        .self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
        .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
        (1) <button @click.stop="fn2" @contextmenu.prevent>按钮</button>
        (2)

        <code>
            <div @click.self="fn1"> 
            <!--阻止所有子元素冒泡到父级,不用为每个子元素阻止冒泡,
                而可用修饰符“.self”,让该事件绑定父元素本身  -->     
                <!--<button @click.stop>按钮</button>-->
                <!--<button @click.stop>按钮</button>-->
                <!--<button @click.stop>按钮</button>-->
                <!--<button @click.stop>按钮</button>-->
                <!--<button @click.stop>按钮</button>-->
        
                <button>按钮</button>
                <button>按钮</button>
                <button>按钮</button>
                <button>按钮</button>
                <button>按钮</button>
                <!--串联修饰符,".enter" ,回车键的别名-->
                <input type="text" @keydown.enter.32="input">
            </div>  
        </code>
        
    • 缩写:
      在vue中,有且仅有两种指令可缩写:
      (1)<button v-on:click="sort">排序</button>
      ==> <button @click="sort">排序</button>
      (2) <li v-bind:class="v">
      ==> <li :class="v">

    • 事件函数的参数

      • 不带括号,默认为传入event(事件对象);
      • 带括号,那么就表示当前函数需要接收event以外的参数,那这个时候需要手动传入event:$event.

        <code>
            <!--不带括号,默认为传入event-->
            <button @click="fn">按钮</button>
            <!--带括号,那么就表示当前函数需要接收event以外的参数,
                那这个时候需要手动传入event:$event-->
            <button @click="fn($event, 1, 2)">按钮</button>
            var app = new Vue({
                el: '#app',
                data: {...},
                methods: {               
                    fn(e, a, b) {
                        console.log(e);
                    },
                }
            })
        </code>
        
  • v-model:
    • 在表单控件元素上创建双向数据绑定;
    • 它会根据控件类型自动选取正确的方法来更新元素。
    • 会忽略所有表单元素的 value、checked、selected 特性的初始值。
    • 修饰符:
      • .lazy - 取代 input 监听 change 事件;(默认是onInput事件)
      • .number - 输入字符串转为数字
      • .trim - 输入首尾空格过滤
        <input type="text" v-model.number="product.num" />

观察者和计算属性

  • watch: 监听的数据变化,改变其他数据;
  • computed:计算属性,一般这里设置的值是根据某种条件获取到的数据,这里属性都是通过函数来描述的,

    • 完整写法,类似Object.defineProperty方法:

      <code>
          computed:{
              属性名:{
                  get(){},
                  set(){}
              }
          }
      </code>
      

      在实际使用过程中,get比set要多很多,所以为了简化书写,可以不写对象形式的get和set
      由于set(){}可能没有,就可简写成“属性名:function(){}”,再精简就变成:属性名(){}
      (1)get方法:根据其他数据变化,得到当前数据
      (2) set方法:相当于watch方法,监听当前的数据变化,改变其他数据;

      <code>
          <body>
              <div id="app">      
                  <table border="1" width="100%">
                      <thead>
                          <tr>
                              <th>
                                  <input type="checkbox" v-                                       model="isCheckedAll">全选
                              </th>
                              <th>名称</th>
                              <th>单价</th>
                              <th>数量</th>
                              <th>小计</th>
                              <th>操作</th>
                          </tr>
                      </thead>
                      <tbody>
                          <tr v-for="product in products">
                              <td>
                                  <input type="checkbox" v-                                   model="product.checked">
                              </td>
                              <td>{{product.name}}</td>
                              <td>¥{{product.price.toFixed(2)}}</td>
                              <td>
                                  <button @click="sub(product)">-</button>
                                  <input style="width: 50px;text-align:                       center" type="text" v-model.number="product.number">
                                  <button @click="plus(product)">+</button>
                              </td>
                              <td>¥{{product.number * product.price}}</td>
                              <td>操作</td>
                          </tr>
                      </tbody>
                  </table>        
                  <h2>您一共购买了 {{totalSum}} 件商品,总价是:¥{{totalPrice}}</h2>    
                  <button v-bind:disabled="totalSum<=0">支付</button>       
              </div>
      
              <script src="js/vue.js"></script>
              <script>        
                  var app = new Vue({
                      el: '#app',
                      data: {
                          products: [
                              {
                                  name: 'iphone8',
                                  price: 8888.00,
                                  number: 0,
                                  checked: false
                              },
                              {
                                  name: 'imac',
                                  price: 18666.00,
                                  number: 0,
                                  checked: false
                              }
                          ]
                      },
      
                      methods: {      
                          plus(product) {
                              product.number++;
                          },
                          sub(product) {
                              if (product.number >0 ) {
                                  product.number--;
                              }
                          }
                      },      
                      // watch: { //监听的数据变化改变其他数据
                      //     isCheckedAll() {
                      //         console.log(1);
                      //         // this.products.forEach( (product) => {
                      //         //     product.checked = this.checkedAll;
                      //         // } );
                      //     }
                      // },
      
                      // 计算属性,一般这里设置的值是根据某种条件获取到的数据,
                      //这里属性都是通过函数来描述的,
                      computed: {
                          isCheckedAll: { //监听其他数据的变化,修改当前属性
                              get() {
                                  return this.products.filter( product => {
                                      return product.checked;
                                  } ).length == this.products.length;
                              },
                              set(newValue) {
                                  this.products.forEach( (product) => {
                                      product.checked = newValue;
                                  } );
                              }
                          },
                          totalSum() {
                              var sum = 0;
                              this.products.forEach( product => {
                                  if (product.checked) {
                                      sum += product.number;
                                  }
                              } );
                              return sum;
                          },
                          totalPrice() {
                              var price = 0;
                              this.products.forEach( product => {
                                  if (product.checked) {
                                      price += product.price *                                                                product.number;
                                  }
                              } );
                              return price;
                          }
                      }
                  })
      
              </script>
          </body>
      </code>     
      
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值