澳门新萄京:入门总计,js一些标题和沉思学习笔
分类:澳门新萄京最大平台

前言

本文不是Vue.js的教程,只是一边看官网Vue的教程文档一边记录并总结学习过程中遇到的一些问题和思考的笔记

前言

生成vue的实例

var vm=new vue({

//这里是选项  他可以包含数据、模板、挂载元素、方法、生命周期钩子等函数

})

首先创建一个简单的vue应用

# 全局安装 vue-cli
$ npm i -g vue-cli
# 创建一个简单的vue仓库
$ vue init webpack-simple learnvue
# 安装依赖
$ cd learnvue
$ npm i
$ npm run dev

1、vue和avalon一样,都不支持VM初始时不存在的属性

而在Angular里是可以支持的,因为angular采用脏检查的方式实现双向绑定,vue和avalon都是采用setter和getter实现双向绑定

例,如下代码在一秒后不会显示出“xxcanghai”的字样

<div id="app">
   <h1>{{obj.text}}</h1>
</div>

<script>
   var v = new Vue({
       el: '#app',
       data: {
           obj:{}
       }
   });
   setTimeout(function(){
       v.obj.text="xxcanghai";//无效
   },1000);
</script>

若给定初始值,则可生效,如下:

<div id="app">
   <h1>{{obj.text}}</h1>
</div>

<script>
   var v = new Vue({
       el: '#app',
       data: {
           obj:{
               text:"default Text" //给定初始值
           }
       }
   });
   setTimeout(function(){
       v.obj.text="xxcanghai";//有效
   },1000);
</script>

不过Vue其中比avalon好的一点是,Vue在只是对初始化时不存在的属性赋值无效,但显示是不会报错的。而avalon则根本无法显示,对于上述第一段代码运行都会报错(不知道最新的avalon是否修改此问题)

好在vue中提供了$set方法来解决这种赋值失败的问题,如下:

<div i<div id="app">
   <h1>{{obj.text}}</h1>
</div>

<script>
   var v = new Vue({
       el: '#app',
       data: {
           obj: {}
       }
   });
   setTimeout(function() {
       v.$set("obj.text", "xxcanghai");//有效
   }, 1000);
</script>

虽然这种采用字符串来表示变量名的方式会导致无法使用强类型的预编译检查(TypeScript),但也至少算能解决问题吧。

本文不是Vue.js的教程,只是一边看官网Vue的教程文档一边记录并总结学习过程中遇到的一些问题和思考的笔记。

实例生命周期(在生命周期里this指向调用它的vue实例)

created在实例被创建后调用

created(){

    this.hello();

}

class绑定——动态地切换class

  • 在:class上绑定一个对象
  • 在:class上绑定一个对象名
  • 在:class上绑定一个返回对象的计算属性
  • 在:class上绑定一个数组,数组语法中也可以使用对象语法
  • 三元表达式:根据条件切换列表中的class

注意:普通class和绑定class可以共存

<template>
  <div id="app">
    {{msg}}
    <!--  1.在在:class上绑定一个对象  -->
    <div :class="{active:isActive}" class="header">
      我是header,我有一个普通class和一个可能存在的class对象
    </div>
    <div :class="{bigger:isBigger,'text-danger':hasError}" class="main">
      我是main,我有一个普通class和一个可能存在的class对象
    </div>

    <!--  在:class上绑定一个对象名  -->
    <div :class="classObj1">
      我是小字,我有背景色
    </div>

    <!-- 在:class上绑定一个返回对象的计算属性 -->
    <div :class="classObj2">
      我是大字,没有背景色
    </div>

    <!--在:class上绑定一个数组,可使用三元表达式,数组语法中也可以使用对象语法  -->
    <div :class="['text-danger',classObj1]">我始终是红色字,可能是大字也可能是小字,有或者没有绿色背景</div>
    <div :class="[classObj2,{'text-danger':hasError}]">我现在是大字且为红色,没有背景色</div>
    <div :class="[isActive? '' :'text-danger']">我是红字</div>

  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      msg: 'Welcome to Your Vue.js App',
      isActive: 0,
      isBigger: '',
      hasError: true,
      classObj1: {
        active: !this.isActive,
        bigger: this.isBigger
      }
    }
  },
  computed: {
    classObj2() {
      return {
        active: this.isActive && this.hasError,
        bigger: !this.isBigger && this.hasError
      }
    }
  }
}
</script>

<style>
.active {
  background: green;
}

.header {
  font-size: 2em;
}

.bigger {
  font-size: 4em;
}

.text-danger {
  color: red;
}

.main {
  font-style: italic;
}
</style>

澳门新萄京 1

2、input元素中属性与v-model同时存在在以属性为优先

如下代码:当文本框中的value属性与v-model冲突时会以input的value属性为优先,并覆盖v-model的属性
最终console.log输出的也是“inputText”

<div id="app">
   <input type="text" v-model="a" value="inputText">
</div>
<script>
   var v = new Vue({
       el: '#app',
       data: {
           a: "vueText"
       }
   });
   console.log(v.a);//inputText
</script>

对于复选框类型的input上述结论也同样适用,如下:

<div id="app">
   <input type="checkbox" v-model="isCheck" checked>
</div>
<script>
   var v = new Vue({
       el: '#app',
       data: {
           isCheck: false
       }
   });
   console.log(v.isCheck);//true
</script>

复选框的v-model设定为false不选中,同时设定checked属性选中,最终效果为以checked属性优先,复选框被选中,同时v.isCheck属性被改写为true。

1、vue和avalon一样,都不支持VM初始时不存在的属性

vue2.0生命周期:

beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed

style绑定——绑定内联样式

  • 看着很像css内联样式,属性名可用驼峰式或用短横线分隔,短横线分隔要用单引号引起来
  • 直接绑定到一个样式对象
  • 结合计算属性使用
  • 数组语法

v-bind:style 使用需要添加浏览器引擎前缀的 CSS 属性时,如 transform,Vue.js 会自动侦测并添加相应的前缀。

<template>
  <div id="app">
    {{msg}}
    <div :style="{color:activeColor,fontSize:fontSize 'px'}">
      hello world
    </div>

    <div :style="styleObj1">
      hello dot
    </div>

    <div :style="styleObj2">
      hello dolby
    </div>

    <div :style="[styleObj1,styleObj2]">
      hello dolby
    </div>

  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      msg: 'Welcome to Your Vue.js App',
      activeColor: 'red',
      fontSize: 12,
      styleObj1: {
        background: 'yellow',
        color: 'pink'
      }
    }
  },
  computed: {
    styleObj2() {
      return {
        fontStyle: 'italic',
        fontWeight: 'bolder'
      }
    }
  }
}
</script>

澳门新萄京 2

3、VM中的函数放到data属性和methods属性中的区别,以及函数调用时带括号与不带括号的区别

  1. Vue在实例化的时候有一个特殊的属性即methods,我看官方文档中把所有VM中的函数都放到methods属性里面,经测试把函数写在data和methods中都可以正常运行,那么两者有何区别?
  2. 通过官方demo可知,在绑定函数的时候可以带括号也可以不带括号,对于有参数的函数那必须带括号调用,但是对于无参函数带括号调用与不带括号调用的区别是什么?
    以下测试:
<div id="app">
    <button @click="dataFn">1.dataFn</button> 
    <!--输出:<button>,[MouseEvent]-->

    <button @click="dataFn()">2.dataFn()</button> 
    <!--输出:Vue,[]-->

    <button @click="methodsFn">3.methodsFn</button> 
    <!--输出:Vue,[MouseEvent]-->

    <button @click="methodsFn()">4.methodsFn()</button> 
    <!--输出:Vue,[]-->
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            dataFn: function() {
                console.log(this,arguments);
            }
        },
        methods: {
            methodsFn: function() {
                console.log(this,arguments);
            }
        }
    });
    //xxcanghai@博客园
</script>

通过上述代码对比可以得到以下结论:

  1. 若想要在事件响应函数中获得Event对象,那么事件绑定时不能加括号,参见上述1、3示例。
  2. 若想在函数中this指向Vue实例化对象,函数调用时应当加括号。同时,所有在methods属性中的函数,无论如何调用,this都指向当前Vue实例化对象。
  3. 遂最终结论为:应当把所有VM中的函数都放在methods中,同时对于事件的绑定应当使用无括号方式。即上述示例3中为最优方案。

PS:当然你也可以使用vue内置的$event来显示的传递event对象,以保证函数写在任何位置都可以正常使用this和event。

<div id="app">
    <button @click="dataFn($event)">5.dataFn($event)</button> 
    <!--输出:Vue,[MouseEvent]-->

    <button @click="methodsFn($event)">6.methodsFn($event)</button> 
    <!--输出:Vue,[MouseEvent]-->
</div>

而在Angular里是可以支持的,因为angular采用脏检查的方式实现双向绑定,vue和avalon都是采用setter和getter实现双向绑定

模板语法(不使用模板可以使用render函数使用JSX语法)

底层实现上Vue将模板编译成虚拟DOM渲染函数,在应用状态改变时,vue计算出重新渲染组件的最小代价并应用到DOM上。

先看怎么用

插值:双大括号!!!!!!必须的  数据改变 大括号内的值也跟着改变 

<span>{{msg}}</span>

vue不得不说的生命周期

当一个vue实例被创建时,它向 Vue 的响应式系统中加入了其 data 对象中能找到的所有的属性。当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。

看下图:

澳门新萄京 3

图源Vue.js教程

一个实例的生命周期分为creat、mount、update、destroy四个阶段,它们的分工各有不同:

  • create:创建
  • mount:挂载DOM
  • update:数据更新
  • destroy:销毁(一般为手动清理事件和定时器)

同时在这些过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。对应生命周期来看,又有以下8个钩子:

beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed。

看一个例子:

<template>
  <div id="app">
    {{msg}}
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      msg: 'Welcome to Your Vue.js App',
    }
  },
  beforeCreate() {
    console.log('beforeCreate')
  },
  created() {
    console.log('created')
    setTimeout(() => {
      this.msg = 'change msg'
    }, 1000);
  },
  beforeMount() {
    console.log('beforeMount')
  },
  mounted() {
    console.log('mounted')
  },
  beforeUpdate() {
    console.log('beforeUpdate')
  },
  updated() {
    console.log('updated')
  },
  beforeDestroy() {
    console.log('beforeDestroy')
  },
  destroyed() {
    console.log('destroyed')
  },
  methods: {
    clickBtn() {
      alert('hello')
    }
  },
  watch: {
    msg() {
      console.log('hello')
    }
  }
}
</script>

打开localhost:8080,页面显示初始msg内容,控制台打印beforeCreate、created、beforeMount、mounted

澳门新萄京 4

大约1s之后,页面内容发生变化,紧接着watch生效,控制台一次打印出hello,beforeUpdate,updated,这里没有打印出beforeDestroy和destroyed是因为页面上没有事件。

澳门新萄京 5

相关笔记

Vue学习笔记-1()

Vue学习笔记-2()

例,如下代码在一秒后不会显示出“xxcanghai”的字样

v-once

如果你想插入一次接下来大括号内的数据不改变 则添加v-once属性

<span v-once>不改变{{msg}}</span>

v-model

<div id="app">
 <h1>{{obj.text}}</h1>
</div>

<script>
 var v = new Vue({
 el: '#app',
 data: {
 obj:{}
 }
 });
 setTimeout(function(){
 v.obj.text="xxcanghai";//无效
 },1000);
</script>

v-html

<span>{{msg}}</span>效果和<span v-html="msg"></span>相同 ,但是后者是将数据转变为纯文本 不是HTML 为了输出HTML 所以使用v-html

单行文本

v-model 指令用于在表单 <input><textarea> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。

<template>
  <div id="app">
    <input type="text" placeholder="edit me" v-value="hello">
  </div>
</template>

以上代码的效果是页面上会出现一个input输入框且有初始值value

澳门新萄京 6

当我们在input中使用v-model用于绑定数据时,value值不生效

<template>
  <div id="app">
    <input type="text" placeholder="edit me" v-model="message" value="hello">
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      message: '',
    }
  },
}
</script>

澳门新萄京 7

v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源。如果有需要,我们应在组件的 data 选项中声明初始值。

<template>
  <div id="app">
    <input type="text" placeholder="edit me" v-model="value">
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      message: '',
      value: 'init',
    }
  },
}
</script>

澳门新萄京 8

现在结合前面学到的看一段代码:

<template>
  <div id="app">
    <input type="text" placeholder="edit me" v-model="message">
    <button @click="clickBtn">Click me</button>
    <p :style="styleObj">Message is: {{message}}</p>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      message: '',
      isClick: ''
    }
  },
  computed: {
    styleObj() {
      return {
        color: this.isClick && this.message ? 'red' : '',
        background: this.isClick && this.message ? 'yellow' : ''
      }
    }
  },
  methods: {
    clickBtn() {
      if (this.message) {
        this.isClick = true
      }
    }
  },
}
</script>

我们为input定义了一个placeholder值为'edit me'并绑定了一个message属性

澳门新萄京 9

首先看input里绑定的message和p中message之间的关系,前面说v-model双向绑定不过是语法糖,实际上还是单向绑定。
当input中的内容发生变化,也就是input中绑定的message——来自于data中的message属性值发生了变化,p中的message也会随之改变,所以数据改变是单向的从data中的message属性到页面上的message属性变换的过程。所以p中的文本会随着input中的内容改变而改变。

澳门新萄京 10

我们再来看看data中的另一个属性'isClick',我们给它赋值为一个空的字符串,即布尔值false

继续看代码,在button按钮上定义了一个单击事件'clickBtn',在p元素上绑定了一个内联样式'styleObj',我们把样式对象放在computed中,这样就会返回计算后的属性对象。当用户点击按钮时,如果input中有输入,我们将'isClick'值设为true,反应在页面上就是输入不为空的情况下点击按钮之后p元素有了黄色背景,字色变为红色。

澳门新萄京 11

若给定初始值,则可生效,如下:

v-bind

大括号不能在HTML属性中使用 要使用v-bind

<span v-bind:id="msg"></span>

如果msg为false  移除属性

<span></span>

多行文本
<template>
  <div id="app">
    Multiline message is:
    <p style="white-space: pre-line;">{{ message }}</p>
    <br>
    <textarea v-model="message" placeholder="add multiple lines"></textarea>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      message: '',
    }
  },
}
</script>

澳门新萄京 12

澳门新萄京 13

澳门新萄京 14

在文本区域插值 (<textarea></textarea>) 并不会生效,应用 v-model 来代替。

<div id="app">
 <h1>{{obj.text}}</h1>
</div>

<script>
 var v = new Vue({
 el: '#app',
 data: {
 obj:{
 text:"default Text" //给定初始值
 }
 }
 });
 setTimeout(function(){
 v.obj.text="xxcanghai";//有效
 },1000);
</script>

使用JS表达式

{{msg 1}}

{{msg==true?0:1}}

=

复选框
  • 单个复选框绑定到布尔值
<template>
  <div id="app">
    <input type="checkbox" v-model="checked">
    <label for="checkbox">{{checked}}</label>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      checked: false,
    }
  },
}
</script>

澳门新萄京 15

澳门新萄京 16

  • 多个复选框绑定到同一数组
<template>
  <div id="app">
    <input type="checkbox" value="Jack" v-model="checkedArr">
    <label for="jack">Jack</label>
    <input type="checkbox" value="John" v-model="checkedArr">
    <label for="john">John</label>
    <input type="checkbox" value="Mike" v-model="checkedArr">
    <label for="mike">Mike</label>
    <br>
    Checked names: {{ checkedArr }}
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      checkedArr: [],
    }
  },
}
</script>

绑定到checkedArr中的值是input中的value

澳门新萄京 17

不过Vue其中比avalon好的一点是,Vue在只是对初始化时不存在的属性赋值无效,但显示是不会报错的。而avalon则根本无法显示,对于上述第一段代码运行都会报错(不知道最新的avalon是否修改此问题)

指令

带有v-前缀

<div v-if="msg">如果msg为true则插入div标签</div>

<div v-bind:id="msg">如果msg为false则移除属性,否则显示</div>

<div v-on:click="toDo">点击触发函数</div>

<input v-model="msg"/>//双向数据绑定

.....等等  vue还支持自定义指令。后面说。

单选按钮
<template>
  <div id="app">
    <input type="radio" value="Jack" v-model="picked">
    <label for="jack">Jack</label>
    <input type="radio" value="John" v-model="picked">
    <label for="john">John</label>
    <input type="radio" value="Mike" v-model="picked">
    <label for="mike">Mike</label>
    <br>
    picked names: {{ picked }}
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      picked: '',
    }
  },
}
</script>

澳门新萄京 18

好在vue中提供了$set方法来解决这种赋值失败的问题,如下:

指令缩写

v-bind:href  或者 v-bind:id 可以缩写为 :href  和:id 就是省略前面的 v-bind

v-on:click  缩写为@click=""

选择框
  • 单选时
<template>
  <div id="app">
    <select v-model="selected">
      <option disabled value="">请选择</option>
      <option>A</option>
      <option>B</option>
      <option>C</option>
    </select>
    Selected: {{ selected }}
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      selected: '',
    }
  },
}
</script>

澳门新萄京 19

如果 v-model 表达式的初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态。这种情况下iOS 不会触发 change 事件,这会使用户无法选择第一个选项。因此推荐像上面这样提供一个值为空的禁用选项。

  • 多选时
<template>
  <div id="app">
    <select v-model="selectedArr" multiple >
      <option>A</option>
      <option>B</option>
      <option>C</option>
    </select>
    SelectedArr: {{ selectedArr }}
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      selectedArr: [],
    }
  },
}
</script>

澳门新萄京 20

用v-for渲染的动态项

<template>
  <div id="app">
    <select v-model="selected">
      <option v-for="option in options" :value="option.value">{{option.text}}</option>
    </select>
    Selected: {{ selected }}
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      selected: 'A',
      options: [
        { value: 'A', text: 'One' },
        { value: 'B', text: 'Two' },
        { value: 'C', text: 'Three' },
      ]
    }
  }
}

澳门新萄京 21

<div i<div id="app">
 <h1>{{obj.text}}</h1>
</div>

<script>
 var v = new Vue({
 el: '#app',
 data: {
 obj: {}
 }
 });
 setTimeout(function() {
 v.$set("obj.text", "xxcanghai");//有效
 }, 1000);
</script>

计算属性

computed 计算属性会根据data 的值改变

<div>{{getNewMsg}}</div>

new Vue({

      el:'#App',

      data:{

            msg:'hello'

      },

      computed:{

            getNewMsg:function(){

                        return this.msg.split('').reverse().join('');

            } 

      }

})

上边代码计算属性只用到了get,没有set。所以我们可以给自己一个set

new Vue({

      el:'#App',

      data:{

            msg:'hello',

            text:'word'

      },

      computed:{

            all:{

                      get:function(){

                                    return this.msg this.text;

                       },

                     set:function(val){

                                   return val this.msg this.text

                      }

            }

      }

})

然后vm.all="你好" 会返回 你好 hello word

computed

接下来我们来说一个前面反复提到的计算属性对象computed,计算属性可以应用于各种复杂的逻辑,使代码更加轻便容易维护。
语法:computed: {xxx: function () { return /* */}}

<template>
  <div id="app">
    <p>Original message: "{{ message }}"</p>
    <p>Computed reversed message: "{{ reversedMessage }}"</p>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      message: 'hello'
    }
  },
  computed: {
    reversedMessage() {
      return this.message.split('').reverse().join('')
    }
  },
}

澳门新萄京 22

可以像绑定普通属性一样在模板中绑定计算属性。Vue 知道 reversedMessage 依赖于message,因此当 message 发生改变时,所有依赖 reversedMessage 的绑定也会更新。而且最妙的是用计算属性没有副作用,更易于测试和理解。

虽然这种采用字符串来表示变量名的方式会导致无法使用强类型的预编译检查(TypeScript),但也至少算能解决问题吧。

函数

methods也可以实现刚才computed的效果。

<div>{{getNewMsg}}</div>

new Vue({

      el:'#App',

      data:{

            msg:'hello'

      },

       methods:{

             getNewMsg:function(){

                   return this.msg.split('').reverse().join('');

            }

      }

})

methods

看了上面computed的例子你会发现,我们在methods中使用方法可达到同样的效果:

<template>
  <div id="app">
    <p>Original message: "{{ message }}"</p>
    <p>Methods reversed message: "{{ reversedMessage() }}"</p>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      message: 'hello'
    }
  },
  methods: {
    reversedMessage() {
      return this.message.split('').reverse().join('')
    }
  },
}

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。不同的是计算属性是基于它们的依赖进行缓存的,只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

这也同样意味着下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:

<template>
  <div id="app">
    <p>{{ now }}</p>
    <p>{{ now }}</p>
    <p>{{ now }}</p>
    <p>{{ now }}</p>
  </div>
</template>

<script>
export default {
  name: 'app',
  computed: {
    now() {
      return Date.now()
    }
  },
}

澳门新萄京 23

相比之下,每当触发重新渲染时,调用方法总会再次执行函数。

<template>
  <div id="app">
    <p>{{ now() }}</p>
    <p>{{ now() }}</p>
    <p>{{ now() }}</p>
    <p>{{ now() }}</p>
  </div>
</template>

<script>
export default {
  name: 'app',
  methods: {
    now() {
      return Date.now()
    }
  },
}

澳门新萄京 24

我们为什么需要缓存?假设我们有一个性能开销比较大的的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter函数,如果你不希望有缓存,请用方法来替代。

前面说过了computed计算属性与methods方法的比较,现在说说计算属性和侦听属性watch的比较。

<template>
  <div id="app">
    {{ fullName }}
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      firstName: 'Foo',
      lastName: 'Bar',
      fullName: 'Foo Bar'
    }
  },
  watch: {
    firstName: function(val) {
      this.fullName = val   ' '   this.lastName
    },
    lastName: function(val) {
      this.fullName = this.firstName   ' '   val
    }
  },
}

以上做法是命令式的watch回调,而且代码重复,也没办法做到响应式,没有任何意义。看computed如何实现

<template>
  <div id="app">
    {{ fullName }}
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      firstName: 'Foo',
      lastName: 'Bar',
    }
  },
  computed: {
    fullName() {
      return this.firstName   ' '   this.lastName
    }
  },
}

代码简洁直观,且当firstName或lastName改变时,fullName也会随之改变并反映到页面上。
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器,于是就有了watch。

注意:Vue2.0已经废弃了vm.$set的用法,应该使用Vm.set()全局方法。

computed和methods比较

虽然最终的结果相同,但是计算属性基于缓存依赖,只有在他依赖的数据发生改变才会重新计算取值,而methods 每次都会重新计算取值。

watch

当需要在数据变化时执行异步或开销较大的操作时,watch是最有用响应数据变化的方法,一般用于监听input等有输入操作的场景。

<template>
  <div id="app">
    {{msg}}
    <input v-model="question">
    <div>{{answer}}</div>
  </div>
</template>

<script>
export default {
  name: 'app',
  created() {
    console.log('')
    setTimeout(() => {
      this.msg = '12121212'
    }, 1000);
  },
  data() {
    return {
      msg: 'Welcome to Your Vue.js App',
      question: '',
      answer: 'I cannot give you an answei until you ask a question'
    }
  },
  watch: {
    question() {
      this.answer = 'Waiting for you to stop typing...'
    },
    msg() {
      alert('hello')
    }
  }
}
</script>

以上代码在http://localhost:8080/中打开后,页面正常显示数据,接着先弹出hello

澳门新萄京 25

点击确定后msg值变为setTimeout中的12121212

澳门新萄京 26

在输入框中输入任意内容,answer值变为我们设定的字符串

澳门新萄京 27

2、input元素中属性与v-model同时存在以属性为优先

wach方法

用于观察VUE实例上的数据变动

<div>{{msg}}</div>

new Vue({

      el:'#App',

      data:{

            msg:'hello',

            text:'word',

            all:''

      },

      watch:{

            msg:function(){

                  this.all=this.msg this.text;

            }

      }

})

如下代码:当文本框中的value属性与v-model冲突时会以input的value属性为优先,并覆盖v-model的属性
最终console.log输出的也是“inputText”

class与style绑定

<div class="boxStyle"  v-bind:class="{active:isActive}"></div>

如果isActive为false 则不显示 active 这个class,否则相反。

class和v-bind:class可以共同使用。

class支持三目运算符

<div v-bind:class="active?style01:style02"></div>

内联样式

<div v-bind:style="{color:red,fontSize:fontSize 'px'}"></div>

还可以绑定到一个对象上

<div v-bind:style="obj"></div>

data(){

     return{

            obj:{

                     color:'red',

                      fontSize:'12px'

            }

     }

}

<div id="app">
 <input type="text" v-model="a" value="inputText">
</div>
<script>
 var v = new Vue({
 el: '#app',
 data: {
 a: "vueText"
 }
 });
 console.log(v.a);//inputText
</script>

条件渲染

v-if 、 v-else、v-else-if

<div v-if="msg>0">大于0</div>

<div v-else-if="msg==0">等于0</div>

<div v-else>小于0</div>

还可以使用template

<template v-if="msg>0">

          <div>1111</div>

</template>

<template v-else>

        <div>2222</div>

</template>

上边的代码修改msg切换不同的div内容,但是vue是不会重新渲染div标签的。根据就地复用策略,只是替换div里面的内容。如果想每次都重新渲染div标签。需要使用key,key不同则每次重新渲染。

对于复选框类型的input上述结论也同样适用,如下:

v-if 和 v-show

v-show只是控制display。

v-if有更高的切换消耗,v-show有更高的初始化消耗。

<div id="app">
 <input type="checkbox" v-model="isCheck" checked>
</div>
<script>
 var v = new Vue({
 el: '#app',
 data: {
 isCheck: false
 }
 });
 console.log(v.isCheck);//true
</script>

列表渲染

v-for

data(){

     return{

            parents:"我是",

            msg:[

                    {name:'foo'},

                    {name:'bar'},

             ]

      }

}

<div>

       <div v-for="{data,index} in msg">

              {{parents}}-{{index}}-{{data.name}}

       </div>

</div>

渲染结果: 我是-0-foo  我是-1-bar

复选框的v-model设定为false不选中,同时设定checked属性选中,最终效果为以checked属性优先,复选框被选中,同时v.isCheck属性被改写为true。

事件处理器

使用template的好处

1。通过HTML模板就可以轻松定位JS对应方法

2。不需要JS手动绑定事件,易于测试

3。当viewmodel销毁 所有的事件处理器自动删除,无需手动删除

<div v-on:click="msg">点击</div>

new Vue({

          el:'app',

          methods:{

          say:function(name,event){

                     alert(name '我是vue')

                    if(event){event.preventDefault}

                    }

           }

})

如果要获取原生DOM事件,需要传入event

3、VM中的函数放到data属性和methods属性中的区别,以及函数调用时带括号与不带括号的区别

事件修饰符

.stop 组件单击事件冒泡

.prevent   提交事件不在重载页面

.capture   使用事件捕获模式

.self          只当在本元素才发生

.once       新增

使用方式:

<div v-on:click.stop></div>

修饰符可以串联

<div v-on:click.stop.prevent="todo"></div>

Vue在实例化的时候有一个特殊的属性即methods,我看官方文档中把所有VM中的函数都放到methods属性里面,经测试把函数写在data和methods中都可以正常运行,那么两者有何区别?
通过官方demo可知,在绑定函数的时候可以带括号也可以不带括号,对于有参数的函数那必须带括号调用,但是对于无参函数带括号调用与不带括号调用的区别是什么? 以下测试:

表单控件

v-model 实现双向数据绑定

<span>{{msg}}</span>

<input v-model="msg"/>

new Vue({

    el:'#app',

   data:{

          msg:'我是默认'

   }

})

无论是复选框  单选框  下拉列表   基本上获取到用户选中的值的方式,就是使用v-model到一个数组

<input type="checkbox" id="jack" value="jack" v-model="checkedName"/>

<label for="jack">jack</label>

<input type="checkbox" id="mini" value="mini" v-model="checkedName"/>

<label for="mini">mini</label>

如果用户选中,则数组会把选中对象的value值存入数组中。

<div id="app">
 <button @click="dataFn">1.dataFn</button> 
 <!--输出:<button>,[MouseEvent]-->

 <button @click="dataFn()">2.dataFn()</button> 
 <!--输出:Vue,[]-->

 <button @click="methodsFn">3.methodsFn</button> 
 <!--输出:Vue,[MouseEvent]-->

 <button @click="methodsFn()">4.methodsFn()</button> 
 <!--输出:Vue,[]-->
</div>
<script>
 var vm = new Vue({
 el: "#app",
 data: {
 dataFn: function() {
 console.log(this,arguments);
 }
 },
 methods: {
 methodsFn: function() {
 console.log(this,arguments);
 }
 }
 });
 //xxcanghai@博客园
</script>

修饰符

.lazy   取消input事件转为change事件同步

.number   将用户输入的值转为number类型,如果返回NAN,则返回原值

.trim      取消前后空格

使用方式:

<input v-model.lazy="msg"/>

通过上述代码对比可以得到以下结论:

组件

  • 若想要在事件响应函数中获得Event对象,那么事件绑定时不能加括号,参见上述1、3示例。
  • 若想在函数中this指向Vue实例化对象,函数调用时应当加括号。同时,所有在methods属性中的函数,无论如何调用,this都指向当前Vue实例化对象。
  • 遂最终结论为:应当把所有VM中的函数都放在methods中,同时对于事件的绑定应当使用无括号方式。即上述示例3中为最优方案。

注册全局组件

Vue.component('my-component',{

    //选项

    data:function(){

              //在组件里 data 必须是函数,并且不能使用箭头函数

    }

})

澳门新萄京:入门总计,js一些标题和沉思学习笔记。PS:当然你也可以使用vue内置的$event来显示的传递event对象,以保证函数写在任何位置都可以正常使用this和event。

注册局部组件

通过使用组件实例选项注册,可以使组件在另一个组件中使用

var child={

澳门新萄京:入门总计,js一些标题和沉思学习笔记。template:'<div>我是组件</div>'

}

new Vue({

          components:{

                    'my-components ':child

           }

})

<div id="app">
 <button @click="dataFn($event)">5.dataFn($event)</button> 
 <!--输出:Vue,[MouseEvent]-->

 <button @click="methodsFn($event)">6.methodsFn($event)</button> 
 <!--输出:Vue,[MouseEvent]-->
</div>

组件通信

思想:父组件通信子组件,使用props。子组件通信父组件使用自定义事件,通过$on('事件名称')监听事件 和 $emit('事件名称') 触发事件。

如果使用vuex,在根组件注册,我们在任意组件中都可以通过$store拿到store对象。如果子组件想要获取到父组件的数据,或者说非父子组件想要拿到彼此的数据,最高效的方式是使用vuex。

但是,还是要说下基本的props用法。

相关笔记

props

Vue.components('child',{

          props :['msg'],

          template:'<div>{{msg}}</div>'

})

<child msg="hello"></child>

注意:因为HTML不区分大小写,所以在传递props时,驼峰写法要通过短横线隔开

<div my-props="hello"></div>

Vue.components('child',{

        props:['myProps'],

        template:'<div>{{myProps}}</div>'

})

Vue学习笔记-1(//www.jb51.net/article/98869.htm)

动态props

传递props使用 v-bind,这样父组件修改子组件也得到修改

<div>

        <input  v-model="msg"/>

        <child v-bind:msg="msg"></child>

</div>

Vue.components('child',{

              props:['msg'],

              template:'<div>{{msg}}</div>'

})

Vue学习笔记-2(//www.jb51.net/article/98878.htm)

字面量语法和动态语法

字面量:<child msg="1"></child>        props为   "1"

动态语法: <child v-bind:msg="1"></child>      props为   1

本文已被整理到了《Vue.js前端组件学习教程》,欢迎大家学习阅读。

单向数据流

props是单向绑定的,父组件修改影响子组件,但是不能反过来,这是为了防止子组件修改父组件的状态,让数据流难以理解。

可以通过Vuex管理state,这样子就避免了繁琐的props传递。后面会发布VUEX讲解的文章,请关注~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

props验证

只用于new创建的实例中,创建实例时传递 props。主要作用是方便测试。

支持类型:string  number  boolean  function  object   array

props:{

     msg:Number,//只检测类型

    //检测类型 其他验证

    call:{

       type:Number,

        default:0,

        requiredLtrue,

        validator:function(val){

            return val>=0

        }

     }

}

您可能感兴趣的文章:

  • 关于Vue.js一些问题和思考学习笔记(2)
  • Vue2.0使用过程常见的一些问题总结学习

自定义事件

使用 v-on 绑定事件

父组件在使用子组件的地方直接用v-on监听子组件触发的事件,  子组件触发事件会触发父组件事件

子组件中要使用this.$emit('事件',参数)

父组件就可以使用 $on去监听

 例如 在父组件中:

<child v-on:子组件$emit的事件名称="父组件事件名称"></child>

非父子组件通信

使用一个空的vue实例作为中央事件总栈

var bus=new Vue()

在A组件中触发事件

bus.$emit('a',1);

在B组件创建的钩子中监听事件

bus.$on('a',function(id){

})

slot

在子组件中

<div>

           <h1>我是子组件标题</h1>

           <slot>只有在没分发的内容才显示</slot>

</div>

在父组件中

<div>

      <child>

             <p>这里的内容会替换掉子组件中的slot</p>

     </child>

</div>

渲染结果为

<div>

        <div>

                <h1>我是子组件标题</h1>

              <p>这里的内容会替换掉子组件中的slot</p>

       </div>

</div>

具名slot

给slot添加name属性

在子组件中

<div>

           <h1>我是子组件标题</h1>

            <slot name="body">我是具名slot</slot>

</div>

在父组件中

<div>

           <child>

                   <div slot="body">这里替换掉 name为body的slot</div>

           </child>

</div>

Render函数

不想使用template,也可以用render写JSX。例如根据判断自动生成DOM结构,如果大量的判断用template会有大量的代码,这时候可以用render,使用createElement去创建标签。

这里只写个小用法。

new Vue({

      el:"#app",

     render:h=>h(App)

})

如果不使用render我们可以这样

new Vue({

          el:'#app',

          components:{App},

          template:'<App/>'

})

总之JSX可以使用JS的完全编程能力。详细:

自定义指令

有时候我们需要对DOM元素进行底层操作,所以需要自定义事件。

全局注册

例如我们创建v-focus

Vue.directive('focus',{

     inserted:function(el){

          el.focus();

     }

})

局部注册

组件接收一个选项

directives:{

         focus:{

                   //指定的定义

         }

 }

使用:<div v-focus></div>

自定义指令钩子函数

刚才我们全局定义 用到了 inserted函数,这就是钩子函数。

bind:function(){} //只调用一次,指令第一次绑定到元素时调用。

inserted:function(){} //被绑定元素插入到父节点 调用

update:function(){}  //更新时调用

componentUpdated:function(){}   //被绑定元素所在模板完成一次更新周期时调用

unbind:function(){}  //指令与元素解绑调用

钩子函数参数

el:指令绑定的元素对象

binding:一个obj对象,他包括以下属性:

               name:指令名称

               value:绑定的值

               oldValue:前一个值 只能在update函数和componentUpdate函数中使用

               expression:绑定的值是字符串形式 例如  v-demo="1"  为1

               arg: 传给指令的值  v-demo:foo   arg值为foo

               modifiers: 修饰符对象 只能在update函数和componentUpdate函数中使用

vnode:vue编译生成的虚拟节点

oldVnode:上一个虚拟节点

混合mixin

var mixin={

            created:function(){

                   this.hello();

             },

            methods:{

                  hello:function(){

                   console.log("Hello");

                   }

           }

}

var Component=Vue.extend({

        mixins:[mixin]

})

如果相同的属性,都会被调用,只是混合对象的钩子将在组件自身钩子之前调用

如果 例如 方法的名字相同,就取组件自身的方法

以上就是vue2.0常用的小点,省略了一些内容。包括像是vue-router、vuex、编写插件等等。

本篇只是总结基础知识点,希望能帮到你。

-by 麦浪XPEKI

本文由澳门新萄京发布于澳门新萄京最大平台,转载请注明出处:澳门新萄京:入门总计,js一些标题和沉思学习笔

上一篇:css position 下一篇:没有了
猜你喜欢
热门排行
精彩图文