初识Vue.js02

192 阅读7分钟

Vue 模板语法的插值操作

  • v-html ---> 可以解析标签
  • v-text ---> 不可以解析标签,只可以解析纯文本内容
  • v-pre ---> 屏蔽 {{ }}(胡子语法) 的功能(跳过该标签的及其子元素的编译),标签里面的内容是什么就打印什么
  • v-cloak ---> 将数据请求到的时候才将视图显示出来(当数据量足够庞大的时候,请求和渲染都需要时间,这个时候可能会出现延迟)

    <!-- v-html 如果文本中包含标签,会将标签一起解析出来 -->
    <div v-html="txtHtml"></div>  
    
    <!-- v-text 如果文本中没有包含标签,那么既可以使用 v-html 也可以使用 v-text -->
    <div v-text="txt"></div>
    
    <!-- v-pre 会屏蔽掉胡子语法的功能,直接打印出 "{{txt}}" -->
    <div v-pre>{{txt}}</div>  
    
    <!-- 因为数据请求和渲染需要时间,所以可能会出现延迟,这时候视图上就会直接渲染
    出 "{{txt}}" 这个文本内容 -->
    <!-- v-cloak 可以让数据成功渲染到视图上再让视图显示出来 -->
    <!-- 需要在 style 里面添加一个样式 <style> [v-cloak]{ display:none; }</style> -->
    <div v-cloak>{{txt}}</div>
    
    <script>
        setTimeout(function () {
            var vm = new Vue({
                el: "#app",
                data: {
                    txtHtml: "<p><strong>KoBe Bryant</strong> is very play basketball</p>",
                    txt: "Vue",
                }
            })
        },2000)
    </script>
    

v-for 中的key属性(了解)

  • 为什么需要这个 key 属性呢?

    • 其实这个和 Vue 的虚拟DOM的Diff算法有关

      • 什么是 Diff 算法呢?

        • Diff算法的作用是用来计算出 Virtual DOM 中被改变的部分,然后针对该部分进行原生DOM操作,而不用重新渲染整个页面。
    • 不使用 key 属性的情况下:

      • 当某一个层有很多个相同的节点的时候(例如列表),我们想在列表中添加一个新的节点时,如果是使用 push 往最后一个添加,不会出现什么情况,但是如果使用 unshift 往第一个列表添加的时候,默认新增加的节点会占据原先的第一个节点元素,原先的第一个节点元素会占据第二个节点元素,第三个节点元素会占据第四个节点元素...以此类推,最后一个节点元素的位置被上一个节点元素占据,这时浏览器会重新给它渲染一个节点,这样子的效率太低了,也大大损耗了服务器的性能(当数据量足够大的时候) ---> 由此引出了下面的 key 属性。
    • 使用 key 属性的情况下:

      • 当我们使用 key 来为每一个节点做唯一标识的,Diff算法会以 key 作为标识来识别此节点,下一次添加新的节点的时候,会找到正确的位置插入新的节点,这样子大大节省了浏览器的性能损耗问题(当数据量足够大的时候)。
      • 但是这里 key 的值只能使用每一次循环的 元素,而不能使用 下标 来做标识,因为使用 下标 的话,下标是从0开始的,如果往第一个列表添加新的节点,新增加的节点的下标就会变成0,原先的节点 下标 依次往后面退一位,这样子又出现了跟上面一样的情况。

数组的 reduce 方法

  • reduce 是数组里面的一个方法,可以用来遍历数组中的每一个元素,reduce()调用结果最后返回一个最终值(就是最后一次 return 的值)

    <script>
        var arr = [
            {name: 'Vuejs入门', price: 99, count: 3},
            {name: 'Vuejs底层', price: 89, count: 1},
            {name: 'Vuejs从入门到放弃', price: 19, count: 5},
        ];

        // reduce(参数1,参数2) 有两个参数
        // 参数1:回调函数,回调函数里面还有两个参数
        //      参数1:pre 上一个遍历的返回值
        //      参数2:current 当前遍历的这个元素
        // 参数2:pre 的默认初始值
        var ret = arr.reduce(function(pre,current){
            console.log(pre, current);

            var total = pre + (current.price * current.count);
            return total;
        },0)

        alert(ret);
    </script>
    

Vue 中的计算属性 computed

  • computed 是 Vue 中的一个计算属性,主要作用是把数据存储到内存中,减少不必要的请求,还可以利用computed给子组件的data赋值。

    <div id="app">
        <p>总价:{{ total }}</p>
    </div>

    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                arr = [
                    {name: 'Vuejs入门', price: 99, count: 3},
                    {name: 'Vuejs底层', price: 89, count: 1},
                    {name: 'Vuejs从入门到放弃', price: 19, count: 5},
                ];
            },
            // Vue 中的计算
            computed: {
                // 直接当做普通属性调用不加括号
                // 任何data中数据变化立即重新计算
                // 计算属性会缓存
                total() {
                    var ret = this.arr.reduce(function (pre, current) {
                        var total = pre + (current.price * current.count);

                        return total;
                    },0)

                    return ret;
                }
            },
        })
    </script>
    

methods 方法和 computed 计算属性的区别

  • methods 方法每调用一次就重新执行代码,这样子大大损耗了服务器的性能

  • computed 计算属性的内部方法会缓存,只要执行过一次,后面再执行,就不会重新执行代码,而是直接将前面缓存过的数据拿来使用哪个。

    • 如果直接拿来当做属性调用则不需要加括号
    • 任何 data 中的数据只要一发生改变就会重新计算
    • 计算属性会自动进行缓存,以便以后的重复调用
  • 注意:当不需要缓存的时候,就可以使用 methods ,如果需要缓存,则 computed 更优。

computed 内部方法的另一种写法 get() 和 set()

  • get()方法是取,相当于我们可以在get中给计算属性的变量赋值

  • set()方法是改变时触发,这里的改变是指当我们定义在 computed 中的变量发生改变时,会触发 set 方法

    • 例如:vm.需要返回的变量名 = '重新定义的值' (我们的返回值都存储在 vm 中)

v-model 的原理

  • v-model 的原理本质上包含了两点:

    • v-bind:绑定input标签value 属性
    • v-on:绑定input标签input 事件
  • v-on:input 事件只要用户一输入内容就会触发 input 事件的执行.

    <div id="app">
        <!-- <input type="text" v-model="txtVal"> --> // 双向数据绑定
        
        // v-model 的原理就是这样子来的
        <input type="text" v-bind:value="txtVal" v-on:input="handelInput">
        <p>{{ txtVal }}</p>
    </div>
    
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                txtVal: "",
            },
            methods:{
                handelInput(e){ // 一输入内容就触发一次事件对象
                // e.target.value 里面存放着用户输入的文本内容
                    this.txtVal = e.target.value
                }
            }
        })
    </script>

Vue 的过滤器的使用

  • Vue 过滤器的语法即格式 ---> Vue 过滤器用来对数据展示前做的一些处理
    <div id="app">
        <!-- 格式 {{ 变量名 | 过滤器名 }} -->
        <p>{{ num | formatNum}}</p>
    </div>
    
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                num: 10
            },
            filters:{
                formatNum(val){ // 这个形参接收的 | 符号前面的变量数据
                    return val + 50; 
                    // return 后面的返回值就是将来要展示在页面上的值(即过滤后的值)
                }
            }
        )
    </script>
  • 过滤器的使用 ---> 过滤一个时间戳(当我们获取到一个时间戳的时候,就要使用过滤器对它进行过滤转化为标准的时间格式 YYYY-MM-DD HH:mm:ss)
    <div id="app">
        <p>{{ timestamp | formatDate }}</p>
    </div>
    
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                timestamp: new Data().getTime(),
            },
            filters:{
                formatDate(val){  // 获取到的是 timestamp 的数据
                    var now = new Date(val)
                    var year=now.getFullYear(); 
                    var month=now.getMonth()+1; 
                    var date=now.getDate(); 
                    var hour=now.getHours(); 
                    var minute=now.getMinutes(); 
                    var second=now.getSeconds(); 
                    return year+"-"+month+"-"+date+" "+hour+":"+minute+":"+second; 
                }
            }
        })
    </script>

Vue 全局过滤器的使用

  • 当出现多个 app 共用一个过滤器的时候,可以将这个过滤器设置成全局的,以便可以重复使用
<!-- 两个标签都是共用同一个过滤器,如果为每一个标签都设置一个过滤器,过于浪费服务器资源 -->
    <div id="app1">
        <p>{{ timestamp | formatDate }}</p>
    </div>
    <div id="app2">
        <p>{{ timestamp | formatDate }}</p>
    </div>
    
    <script>
<!-- 全局过滤器书写格式 Vue.filter("过滤器名称",(val) => {}) -->
        Vue.filter("formatDate",(val) => { // 切记 全局过滤器filter是不用加 s 的
            var now = new Date(val)
            var year=now.getFullYear(); 
            var month=now.getMonth()+1; 
            var date=now.getDate(); 
            var hour=now.getHours(); 
            var minute=now.getMinutes(); 
            var second=now.getSeconds(); 
            return year+"-"+month+"-"+date+" "+hour+":"+minute+":"+second; 
        })
<!-- 将两个Vue构造函数的过滤器提取出来设置成全局过滤器 -->
        var vm1 = new Vue({
            el: "#app1",
            data: {
                timestamp: new Date().getTime();
            }
        })
        var vm2 = new Vue({
            el: "#app2",
            data: {
                timestamp: new Date().getTime();
            }
        })
    </script>