zoukankan      html  css  js  c++  java
  • Vue 01.基础

    Vue与MVVM模式

    后端中的 MVC 与 前端中的 MVVM 之间的区别

    • MVC 是后端的分层开发概念;

    • MVVM是前端视图层的概念,主要关注于 视图层分离,也就是说:MVVM把前端的视图层,分为了 三部分 Model, View , VM ViewModel

    • 为什么有了MVC还要有MVVM

    Vue.js 基本代码 和 MVVM 之间的对应关系

    <body>
    <!-- 将来 new 的Vue实例,会控制这个 元素中的所有内容 -->
    <!-- Vue 实例所控制的这个元素区域,就是我们的 V  -->
    <div id="app">
        <p>{{ msg }}</p>
    </div>
    
    <script>
        // 2. 创建一个Vue的实例
        // 当我们导入包之后,在浏览器的内存中,就多了一个 Vue 构造函数
        //  注意:我们 new 出来的这个 vm 对象,就是我们 MVVM中的 VM调度者
        var vm = new Vue({
            el: '#app',  // 表示,当前我们 new 的这个 Vue 实例,要控制页面上的哪个区域
            // 这里的 data 就是 MVVM中的 M,专门用来保存 每个页面的数据的
            data: { // data 属性中,存放的是 el 中要用到的数据
                msg: '欢迎学习Vue' // 通过 Vue 提供的指令,很方便的就能把数据渲染到页面上,程序员不再手动操作DOM元素了【前端的Vue之类的框架,不提倡我们去手动操作DOM元素了】
            }
        })
    </script>
    </body>
    

    声明式渲染

    插值表达式{{ }}

    插值表达式会出现闪烁问题,即在网速慢时会出现{{ msg }},数据加载好后才会显示数据

    v-cloak、v-text、v-html

    • v-cloak

      • 解决插值表达式闪烁的问题

        <style>
            [v-cloak] {
               display: none; 
            }
        </style>
        
        <p v-cloak>{{ msg }}</p>
        
    • v-text

      • 没有闪烁问题
      • v-text会覆盖元素中原本的内容,但是 插值表达式 只会替换自己的这个占位符,不会把 整个元素的内容清空
    • v-html

      • 可以输出html标签,插值表达式和v-text只会输出普通文本

    v-bind 绑定属性

    1. 直接使用指令v-bind

    2. 使用简化指令:

    3. 在绑定的时候,拼接绑定内容::title="btnTitle + '追加内容'"

    <div id="app">
        <input type="button" value="按钮" v-bind:title="mytitle + '123'">
    </div>
    
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                mytitle: '这是一个自己定义的title'
            },
        })
    </script>
    

    v-on 绑定事件

    1. 直接使用指令v-on

    2. 使用简化指令@

    <div id="app">
        <input type="button" value="按钮" v-on:click="show">
    </div>
    
    <script>
        var vm = new Vue({
            el: '#app',
            methods: { 
                // 这个 methods属性中定义了当前Vue实例所有可用的方法
                show: function () {
                    alert('Hello')
                }
            }
        })
    </script>
    

    demo:跑马灯

    分析

    1. 给 【浪起来】 按钮,绑定一个点击事件 v-on @
    2. 在按钮的事件处理函数中,写相关的业务逻辑代码:拿到 msg 字符串,然后 调用 字符串的 substring 来进行字符串的截取操作,把 第一个字符截取出来,放到最后一个位置即可;
    3. 为了实现点击下按钮,自动截取的功能,需要把 2 步骤中的代码,放到一个定时器中去;

    代码

    1. HTML
    <div id="app">
        <input type="button" value="浪起来" @click="lang">
        <input type="button" value="低调" @click="stop">
    
        <h4>{{ msg }}</h4>
    </div>
    
    1. Vue实例
    <script>
        // 在 VM 实例中,如果想要获取 data 上的数据,或者 想要调用 methods 中的 方法,
        // 必须通过 this.数据属性名 或 this.方法名 来进行访问,
        // this表示 new 出来的 VM 实例对象
        var vm = new Vue({
            el: '#app',
            data: {
                msg: '猥琐发育,别浪~~!',
                intervalId: null // 在data上定义 定时器Id
            },
            methods: {
                lang() {
                    if (this.intervalId != null) return; // 防止多次点击按钮,创建多个定时器
    
                    // =>箭头函数解决了this的指向问题,如果不加,则this指向的是setInterval方法
                    this.intervalId = setInterval(() => {
                        var start = this.msg.substring(0, 1)
                        // 获取到 后面的所有字符
                        var end = this.msg.substring(1)
                        // 重新拼接得到新的字符串,并赋值给 this.msg
                        this.msg = end + start
                    }, 400)
    
                    // VM实例监听自己身上 data 中的数据,只要数据改变,就会自动把最新的数据,同步到页面中去
                    // 【好处:程序员只需要关心数据,不需要考虑如何重新渲染DOM页面】
                },
                stop() { // 停止定时器
                    clearInterval(this.intervalId)
                    // 每当清除了定时器之后,需要重新把 intervalId 置为 null
                    this.intervalId = null;
                }
            }
        })
    
    </script>
    

    事件修饰符

    • .stop 阻止冒泡

    • // 此时点击按钮,不会触发div1Handler事件
      <div class="inner" @click="div1Handler">
            <input type="button" value="戳他" @click.stop="btnHandler">
      </div>
      
    • .prevent 阻止默认事件

    • // 此时点击a标签不弹网页
      <a href="http://www.baidu.com" @click.prevent="linkClick">有问题,先去百度</a> 
      
    • .capture 添加事件侦听器时使用事件捕获模式

    • // 此时点击按钮,先触发div1Handler再触发btnHandler,由外向里
      <div class="inner" @click.capture="div1Handler">
            <input type="button" value="戳他" @click="btnHandler">
      </div>
      
    • .self 只当事件在该元素本身(比如不是子元素)触发时触发回调

    • // 此时点击按钮,不会触发div1Handler事件
      <div class="inner" @click.self="div1Handler">
            <input type="button" value="戳他" @click="btnHandler">
      </div>
      
    • .once 事件只触发一次

    • // 点击第一次不跳转,第二次跳转,使prevent事件只触发一次
      // 事件修饰符可以链式操作
      <a href="http://www.baidu.com" @click.prevent.once="linkClick">有问题,先去百度</a>
      

    stop和self在阻止冒泡时的区别:

    • stop阻止了所有的冒泡
    • self只会阻止自己身上冒泡行为的触发,并不会真正阻止冒泡的行为

    v-model 双向数据绑定

    • v-bind 只能实现数据的单向绑定,从 M 自动绑定到 V,无法实现数据的双向绑定
    • v-model 指令可以实现 表单元素和 Model 中数据的双向数据绑定
    • v-model 只能运用在 表单元素中 input/select/checkbox/textarea

    demo:简易计算器

    1. HTML
    <div id="app">
        <input type="text" v-model="n1">
    
        <select v-model="opt">
            <option value="+">+</option>
            <option value="-">-</option>
            <option value="*">*</option>
            <option value="/">/</option>
        </select>
    
        <input type="text" v-model="n2">
    
        <input type="button" value="=" @click="calc">
    
        <input type="text" v-model="result">
    </div>
    
    1. Vue实例
    <script>
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
            el: '#app',
            data: {
                n1: 0,
                n2: 0,
                result: 0,
                opt: '+'
            },
            methods: {
                calc() { // 计算器算数的方法
                    // 逻辑:
                    switch (this.opt) {
                        case '+':
                            this.result = parseInt(this.n1) + parseInt(this.n2)
                            break;
                        case '-':
                            this.result = parseInt(this.n1) - parseInt(this.n2)
                            break;
                        case '*':
                            this.result = parseInt(this.n1) * parseInt(this.n2)
                            break;
                        case '/':
                            this.result = parseInt(this.n1) / parseInt(this.n2)
                            break;
                    }
    
                    // 注意:这是投机取巧的方式,正式开发中,尽量少用
                    // var codeStr = 'parseInt(this.n1) ' + this.opt + ' parseInt(this.n2)'
                    // this.result = eval(codeStr)
                }
            }
        });
    </script>
    

    在Vue中使用样式

    使用class样式

    1. 数组
    <h1 :class="['red', 'thin']">这是一个邪恶的H1</h1>
    
    1. 数组中使用三元表达式
    <h1 :class="['red', 'thin', isactive?'active':'']">这是一个邪恶的H1</h1>
    
    // 三元表达式isactive?'active':''
    // 其中isactive是判断条件,如果为true,则执行?后面的否则执行:后面的
    
    1. 数组中嵌套对象
    <h1 :class="['red', 'thin', {'active': isactive}]">这是一个邪恶的H1</h1>
    // 'active'是style中的类名,isactive是vm实例中data中的变量
    
    1. 直接使用对象,对象的属性是类名,可不带引号
    <h1 :class="{red:true, italic:true, active:false, thin:true}">这是一个邪恶的H1</h1>
    

    使用内联样式

    1. 直接在元素上通过 :style 的形式,书写样式对象
    <h1 :style="{color: 'red', 'font-size': '40px'}">这是一个善良的H1</h1>
    // 属性中有-时必须加引号
    
    1. 将样式对象,定义到 data 中,并直接引用到 :style
    • 在data上定义样式:
    data: {
            h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' }
    }
    
    • 在元素中,通过属性绑定的形式,将样式对象应用到元素中:
    <h1 :style="h1StyleObj">这是一个善良的H1</h1>
    
    1. :style 中通过数组,引用多个 data 上的样式对象
    • 在data上定义样式:
    data: {
            h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' },
            h1StyleObj2: { fontStyle: 'italic' }
    } 
    
    • 在元素中,通过属性绑定的形式,将样式对象应用到元素中:
    <h1 :style="[h1StyleObj, h1StyleObj2]">这是一个善良的H1</h1>
    

    循环与条件

    v-for和key属性

    1. 迭代数组
    <ul>
      <li v-for="(item, i) in list">索引:{{i}} --- 姓名:{{item.name}}</li>
    </ul>
    
    1. 迭代对象中的键值对
    <!-- 循环遍历对象身上的属性 -->
    <div v-for="(val, key, i) in userInfo">{{val}} --- {{key}} --- {{i}}</div>
    
    1. 迭代数字,从1开始
    <p v-for="i in 10">这是第 {{i}} 个P标签</p>
    

    2.2.0+ 的版本里,当在组件中使用 v-for 时,key 现在是必须的。

    当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。如果数据项的顺序被改变,Vue将不是移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。

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

    注意:

    • v-for 循环时,key属性使用number或string
    • key在使用时,必须使用v-bind属性绑定的形式指定key的值 :key="item.id"

    v-if和v-show

    • v-if
      • 每次都会重新删除或创建元素
      • 有较高的切换性能消耗,如果元素可能永远不会显示出来,推荐用v-if
    • v-show
      • 每次不会重新进行DOM的删除和创建操作,只是切换了元素的 display:none 样式
      • 有较高的初始渲染消耗,需要频繁切换时用v-show
    <h3 v-if="flag">这是用v-if控制的元素</h3>
    <h3 v-show="flag">这是用v-show控制的元素</h3>
    // flag等于true时标签显示,否则不显示
    

    一般来说,v-if 有更高的切换消耗而 v-show 有更高的初始渲染消耗。因此,如果需要频繁切换 v-show 较好,如果在运行时条件不大可能改变 v-if 较好。

    demo:品牌管理

    HTML

    <div id="app">
    
      <div class="panel panel-primary">
        <div class="panel-heading">
          <h3 class="panel-title">添加品牌</h3>
        </div>
        <div class="panel-body form-inline">
          <label>
            Id:
            <input type="text" class="form-control" v-model="id">
          </label>
    
          <label>
            Name:
            <input type="text" class="form-control" v-model="name">
          </label>
    
          <!-- 在Vue中,使用事件绑定机制,为元素指定处理函数的时候,如果加了小括号,就可以给函数传参了 -->
          <input type="button" value="添加" class="btn btn-primary" @click="add()">
    
          <label>
            搜索名称关键字:
            <input type="text" class="form-control" v-model="keywords">
          </label>
        </div>
      </div>
    
    
      <table class="table table-bordered table-hover table-striped">
        <thead>
        <tr>
          <th>Id</th>
          <th>Name</th>
          <th>Ctime</th>
          <th>Operation</th>
        </tr>
        </thead>
        <tbody>
        <!-- 之前, v-for 中的数据,都是直接从 data 上的list中直接渲染过来的 -->
        <!-- 现在, 自定义了一个 search 方法,同时,把搜索的关键字通过传参的形式,传递给了 search 方法 -->
        <!-- 在 search 方法内部,通过 执行 for 循环, 把所有符合 搜索关键字的数据,保存到一个新数组中,再返回 -->
        <tr v-for="item in search(keywords)" :key="item.id">
          <td>{{ item.id }}</td>
          <td v-text="item.name"></td>
          <td>{{ item.ctime }}</td>
          <td>
            <a href="" @click.prevent="del(item.id)">删除</a>
          </td>
        </tr>
        </tbody>
      </table>
    
    </div>
    

    添加新品牌

    var vm = new Vue({
        el: '#app',
        data: {
            id: '',
            name: '',
            keywords: '', // 搜索的关键字
            list: [
                {id: 1, name: '奔驰', ctime: new Date()},
                {id: 2, name: '宝马', ctime: new Date()}
            ]
        },
        methods: {
            add() {
                // 1. 从data中取出id和name并组成一个对象
                // 2. 把这个对象,添加到 data 上的 list 中
                // 注意:Vue已经实现了数据的双向绑定,每当修改了 data 中的数据,Vue会默认监听到数据的改动,自动把最新的数据,应用到页面上;
    
                var car = {id: this.id, name: this.name, ctime: new Date()}
                this.list.push(car)
              	// 将input标签内的内容清空
                this.id = this.name = ''
            },
    

    删除品牌

    del(id) { // 根据Id删除数据
        // 分析:
        // 1. 如何根据Id,找到要删除这一项的索引
        // 2. 如果找到索引了,直接调用 数组的 splice 方法
      
        // 方法一,使用数组的some方法
        /* this.list.some((item, i) => {
          if (item.id == id) {
            this.list.splice(i, 1)
            // 在 数组的 some 方法中,如果 return true,就会立即终止这个数组的后续循环
            return true;
          }
        }) */
    
        // 方法二,使用数组的findIndex方法
        var index = this.list.findIndex(item => {
            if (item.id == id) {
                return true;
            }
        })
    
        this.list.splice(index, 1)
    },
    

    根据条件筛选品牌

    • 筛选框绑定到 VM 实例中的 keywords 属性

    • 在使用 v-for 指令循环每一行数据的时候,不再直接 item in list,而是 in 一个 过滤的methods 方法,同时,把过滤条件keywords传递进去

    • search 过滤方法中,使用 数组的 filter 方法进行过滤:

    search(keywords) { // 根据关键字,进行数据的搜索
      	// 方法一
        /* var newList = []
        this.list.forEach(item => {
          if (item.name.indexOf(keywords) != -1) {
            newList.push(item)
          }
        })
        return newList */
    
        //  注意:  forEach   some   filter   findIndex   这些都属于数组的新方法,
        //  都会对数组中的每一项,进行遍历,执行相关的操作;
      	
        // 方法二
        return this.list.filter(item => {
            // if(item.name.indexOf(keywords) != -1)
    
            //  注意 : ES6中,为字符串提供了一个新方法,叫做  String.prototype.includes('要包含的字符串')
            //  如果包含,则返回 true ,否则返回 false
            if (item.name.includes(keywords)) {
                return item
            }
        })
    
        // return newList
    }
    

    调试工具vue-devtools

    过滤器

    概念:Vue.js 允许你自定义过滤器,可被用作一些常见的文本格式化。过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示;

    私有过滤器

    私有局部过滤器,只能在 当前 VM 对象所控制的 View 区域进行使用

    HTML

    <td>{{item.ctime | dataFormat('yyyy-mm-dd')}}</td>
    

    Vue实例

    filters: {
        // 第一个参数接收过滤器前面的值,后面的参数接收过滤器的参数
      
        dataFormat(input, pattern = "") { // 在参数列表中 通过 pattern="" 来指定形参默认值,防止报错
            var dt = new Date(input);
            // 获取年月日
            var y = dt.getFullYear();
            var m = (dt.getMonth() + 1).toString().padStart(2, '0');
            // month从0开始,所以要+1
            var d = dt.getDate().toString().padStart(2, '0');
          	// padStart(2, '0')把个位数转化为01,02的两位数
            
            // 如果 传递进来的字符串类型,转为小写之后,等于 yyyy-mm-dd,那么就返回 年-月-日
            // 否则,就返回  年-月-日 时:分:秒
    
            if (pattern.toLowerCase() === 'yyyy-mm-dd') {
                return `${y}-${m}-${d}`;
            } else {
                // 获取时分秒
                var hh = dt.getHours().toString().padStart(2, '0');
                var mm = dt.getMinutes().toString().padStart(2, '0');
                var ss = dt.getSeconds().toString().padStart(2, '0');
                
                return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
            }
        }
    }
    

    使用ES6中的字符串新方法 String.prototype.padStart(maxLength, fillString='') 或 String.prototype.padEnd(maxLength, fillString='')来填充字符串;

    全局过滤器

    HTML

    <div id="app">
        <p>{{ msg | msgFormat('疯狂', '123') | test }}</p>
    </div>
    

    vue实例

    // 定义一个 Vue 全局的过滤器,名字叫做  msgFormat
    Vue.filter('msgFormat', function (msg, arg, arg2) {
        // 字符串的  replace 方法,第一个参数,除了可写一个 字符串之外,还可以定义一个正则
        return msg.replace(/内容/g, arg + arg2)
    })
    
    Vue.filter('test', function (msg) {
        return msg + '========'
    })
    
    
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
        el: '#app',
        data: {
            msg: '一段内容'
        },
        methods: {}
    });
    

    注意:当有局部和全局两个名称相同的过滤器时候,会以就近原则进行调用,即:局部过滤器优先于全局过滤器被调用!

    键盘修饰符以及自定义键盘修饰符

    vue文档-按键修饰符

    自定义键盘修饰符

    1. 通过Vue.config.keyCodes.名称 = 按键值来自定义案件修饰符的别名:
    Vue.config.keyCodes.f2 = 113;
    
    1. 使用自定义的按键修饰符:
    <input type="text" v-model="name" @keyup.f2="add">
    

    自定义指令

    vue文档-自定义指令

    1. 自定义全局和局部的自定义指令:

    注意: 在每个函数中,第一个参数永远是 el ,它表示被绑定了指令的那个元素。这个 el 参数,是一个原生的JS对象

    // 自定义全局指令 v-focus,为绑定的元素自动获取焦点:
    Vue.directive('focus', {
        inserted: function (el) { // inserted 表示被绑定元素插入父节点时调用
            el.focus();
        }
    });
    
    // 自定义局部指令 v-color 和 v-font-weight,为绑定的元素设置指定的字体颜色 和 字体粗细:
    
    directives: {
        color: { // 为元素设置指定的字体颜色
            bind(el, binding) {
                el.style.color = binding.value;
            }
        },
        'font-weight': function (el, binding2) { // 自定义指令的简写形式,等同于定义了 bind 和 update 两个钩子函数
            el.style.fontWeight = binding2.value;
        }
    }
    
    1. 自定义指令的使用方式,必须v-名字
    <input type="text" v-model="searchName" v-focus v-color="'red'" v-font-weight="900">
    

    钩子函数 (均为可选)

    • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次
      • 和样式相关的操作,一般都可以在 bind 执行。样式只要通过指令绑定给了元素,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联的样式。将来元素肯定会显示到页面中,这时候,浏览器的渲染引擎必然会解析样式,应用给这个元素
    • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。inserted 表示元素 插入到DOM中的时候,会执行 inserted 函数【触发1次】。
      • 和JS行为有关的操作,最好在 inserted 中去执行,放置 JS行为不生效
    • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。

    钩子函数参数

    • el:指令所绑定的元素,可以用来直接操作 DOM 。
    • binding:一个对象,包含以下属性:
      • name:指令名,不包括 v- 前缀。
      • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
      • oldValue:指令绑定的前一个值,仅在 updatecomponentUpdated 钩子中可用。无论值是否改变都可用。
      • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
      • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"
      • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }
    • vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
    • oldVnode:上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用。

    methods、watch、computed

    三者对比

    1. computed属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用;必须return
    2. methods方法表示一个具体的操作,主要书写业务逻辑;
    3. watch属性的值是一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是computedmethods的结合体;

    通过一个demo,来介绍三者的区别和使用方法。

    实现姓、名两个文本框的内容的改变,则全名的文本框中的值也跟着改变

    methods方法

    通过监听keyup事件,然后调用方法实现

    <div id="app">
    
      <input type="text" v-model="firstname" @keyup="getFullname"> +
      <input type="text" v-model="lastname" @keyup="getFullname"> =
      <input type="text" v-model="fullname">
    
    </div>
    
    var vm = new Vue({
      el: '#app',
      data: {
        firstname: '',
        lastname: '',
        fullname: ''
      },
      methods: {
        getFullname() {
          this.fullname = this.firstname + '-' + this.lastname
        }
      }
    });
    

    watch属性

    1. 监听data中属性的变化
    <div id="app">
    
      <input type="text" v-model="firstname"> +
      <input type="text" v-model="lastname"> =
      <input type="text" v-model="fullname">
    
    </div>
    
    var vm = new Vue({
      el: '#app',
      data: {
        firstname: '',
        lastname: '',
        fullname: ''
      },
      methods: {},
      watch: { // 使用watch属性可以监视 data 中指定数据的变化,然后触发 watch 中对应的 function 处理函数
        'firstname': function (newVal, oldVal) {
          // newVal, oldVal分别是变化前的值和变化后的值
          this.fullname = newVal + '-' + this.lastname
        },
        'lastname': function (newVal) {
          this.fullname = this.firstname + '-' + newVal
        }
      }
    });
    
    1. 监听路由对象的变化

    computed计算属性的使用

    1. 默认只有getter的计算属性
    <div id="app">
    
      <input type="text" v-model="firstname"> +
      <input type="text" v-model="lastname"> =
      <input type="text" v-model="fullname">
    
    </div>
    
    var vm = new Vue({
      el: '#app',
      data: {
        firstname: '',
        lastname: ''
      },
      methods: {},
      computed: { // 在 computed 中可以定义一些叫做 【计算属性】的属性,计算属性的本质就是一个方法,只不过在使用这些计算属性时,是把它们的名称直接当作属性来使用的;并不会把计算属性当作方法去调用;
        // 注意1:在引用计算属性时,不要加()去调用,直接把它当作普通属性去使用;
        // 注意2:只要计算属性的 function 内部,所用到的任何 data 中的数据发送了变化,就会立即重新计算这个计算属性的值
        // 注意3:计算属性的结果会被缓存起来,方便下次直接使用;如果计算属性方法中的任何数据都没有发生过变化,则不会重新对计算属性求值;即不会重新执行这个方法
        'fullname': function () {
          console.log('ok')
          return this.firstname + '-' + this.lastname
        }
      }
    });
    
    1. 定义有gettersetter的计算属性
    <div id="app">
        <input type="text" v-model="firstName">
        <input type="text" v-model="lastName">
        <!-- 点击按钮重新为 计算属性 fullName 赋值 -->
        <input type="button" value="修改fullName" @click="changeName">
    
        <span>{{fullName}}</span>
      </div>
    
    var vm = new Vue({
      el: '#app',
      data: {
        firstName: 'jack',
        lastName: 'chen'
      },
      methods: {
        changeName() {
          this.fullName = 'TOM - chen2';
        }
      },
      computed: {
        fullName: {
          get: function () {
            return this.firstName + ' - ' + this.lastName;
          },
          set: function (newVal) {
            var parts = newVal.split(' - ');
            this.firstName = parts[0];
            this.lastName = parts[1];
          }
        }
      }
    });
    

    nrm的安装使用

    作用:提供了一些最常用的NPM包镜像地址,能够让我们快速的切换安装包时候的服务器地址;
    什么是镜像:原来包刚一开始是只存在于国外的NPM服务器,但是由于网络原因,经常访问不到,这时候,我们可以在国内,创建一个和官网完全一样的NPM服务器,只不过,数据都是从人家那里拿过来的,除此之外,使用方式完全一样;

    1. 运行npm i nrm -g全局安装nrm包;
    2. 使用nrm ls查看当前所有可用的镜像源地址以及当前所使用的镜像源地址;
    3. 使用nrm use npmnrm use taobao切换不同的镜像源地址;

    相关文章

    1. vue.js 1.x 文档
    2. vue.js 2.x 文档
    3. String.prototype.padStart(maxLength, fillString)
    4. js 里面的键盘事件对应的键码
    5. Vue.js双向绑定的实现原理
  • 相关阅读:
    互动媒体学习社区-ASP.NET MVC 后台用户管理模块
    互动媒体学习社区-ASP.NET MVC 开发步骤
    互动媒体学习社区-ASP.NET MVC 数据库设计
    辗转相除法求最大公约数和最小公倍数分析
    C语言循环
    C语言中语句的跨行支持总结
    值得一学的C语言
    概率论
    Saul's Blog
    深入浅出 神经网络
  • 原文地址:https://www.cnblogs.com/LittlePanger/p/12626213.html
Copyright © 2011-2022 走看看