Vue 选项 / 数据,DOM

每个vue应用都是通过构造函数Vue创建的一个Vue的根实例启动的,在实例化Vue时,需要传入一个选项对像,它可以包括是数据,模板,挂载元素,方法,生命周期函数等选项

const vm=new Vue({ })
el

提供一个在页面上已经存在的DOM元素作为实例的挂载目标,可以是CSS选择器,ID选择器等,也可以是一个HTMLElement实例

new Vue({
  el:"#app"
})

如果我们声明了一个vue实例,但是没有传入el属性,那么该实例会处于未挂载的状态,没有关联的DOM属性,可以使用$mount来实现手动挂载

const vm=new Vue({
  data:{
    say:"hellow world"
  }
}).$mount("app");
console.log(vm.$data.say)
data

类型: object | function
限制:在组件中对象必须是function格式

对象的格式必须是纯粹的对象(含有零或多个key/value的键值对),可以理解为data应该只能是数据,不推荐其它形似
不要对data属性使用箭头函数,在data中this的指向应该是Vue实例

new Vue({
  el:"#app",
  data:{
    name:"tom"
  }
})

实例创建之后,可以通过vm.$data访问原始数据对象,在实例内部可以直接通过this.data[属性]来获取指定的属性

  <p>{{this.test}}</p>
  <p>{{test}}</p>
  <p>{{this.$data.test}}</p>
  
  new Vue({
    ...
    data(){
        return {
          test:"测试"
      }
    }
  })
props

类型: Array | Object

props可以是数组或对象,用来接收来自父组件的数据,props可以是简单的数组,或者是用对象作为替代,对象允许接收高级选项,如类型检测,自定义校验和设置默认值

//简单语法
Vue.compoment("props-demo",{
  props:['size','myMessage']
})

//对象语法
//在对象语法中可以进行类型检测,设置默认值或者自定义校验规则
//类型检测可以是Js中的简单数据类型和复杂数据类型,如果从父组件中获取的值的类型不符合的话,命令依然会执行,但是在控制台中会报错
Vue.component("props-demo",{
  props:{
    props_a:{
      type:'Number',
      //type 类型可以是String Number Boolearn Function Fbject Array Symbol 'null'表示允许传入任意值
      //也可以组合传入 [String,Number] ,表示是多种类型
      default:10,
      //设置的默认值,如果在父组件中没有获取值的话会展示默认值
      //如果我们设置类型为Object/Array,default的值必须是一个函数,default(){  return{ }    }
      required:true,
      //表示必传
      validator: function (value) { 
      //设置自定义校验规则,value为获取的父组件的数据,如果不符合校验条件也会在控制台报错
          return value > 10
      } 
    }
  }
})

在模板中如果要动态的绑定父组件的数据到子组件中,需要使用v-bind,在使用动态绑定后,如果父组件的数据发生变化,该变化也会传导给子组件

<child :get-parent-msg="parentMsg"></child>

如果不使用动态绑定,那么我们最终获取到的数据只是在标签中写入的字符串

<child get-parent-msg="parentMsg"></child> 
<!--最后我们在子组件中获取到的只是字符串parentMsg,并不是父组件中data的parentMsg变量的值-->

由于html的特性是不区分大小写的,所以当使用的不是字符串模板时,使用驼峰命名法的prop需要转换为相对应的短横线相隔开的命名格式

<child :get-parent-msg="parentMsg"></child>

Vue.component("child",{
  props:["getParentMsg"]
})

注意,每一次父组件数据更新时,子组件的所有props都会更新为最新值,如果我们在子组件直接修改props的值,控制台会报错

虽然明确给组件定义props是传参的推荐方式,但实际组件可以接收任意传入的特性,这些特性都会被添加到组件根元素上,例如在使用Botstrap时,我们需要在某一个组件上添加一个data-3d-data-picker特性,这时可以直接把属性添加到组件上,不需要事先定义prop

<组件 data-3d-date-picker='true'><组件>

添加的属性data-3d-data-picker会自动被添加到组件的根元素上

computed

我们在模板内可以运用表达式,但是如果在模板内放入太多的逻辑代码会让后期的维护变得十分困难,vue为我们提供了computed来处理复杂逻辑,例如:

 <p>{{msg.split('').reverse().join("")}}</p>
<!--对于这样的逻辑,我们可以将其放置到computed中来进行处理-->
computed:{
    reverse:function () {
        return this.msg.split("").reverse().join("");
    }
}
//computed的变量会挂载到实例本身,可以直接使用
<p>{{reverse}}</p>

在上面的例子中,reverse的值依赖于msg,使用计算属性,在msg的值发生变化时,reverse的值也会相应的发生变化

对于在computed中设置监测数据变化方法,如果我们使用methods同样可以实现

var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // a computed getter
    reversedMessage: function () {
      // `this` points to the vm instance
      return this.message.split('').reverse().join('')
    }
  }
})

//转化为method方式

var vm=neww Vue({
  el:'#example',
  data:{
    message:"hello"
  },
  methods:{
     reversedMessage: function () {
      return this.message.split('').reverse().join('')
  }
})

//然后在页面中调用reversedMessage()方法即可
{{reversedMessage()}}

两者的区别在于computed是会基于他们的依赖进行缓存,只有在它的依赖发生改变时才会重新求值
这意味着如果数据没有发生变化,即使多次访问计算机也只会返回之前的计算结果,而不必再次执行函数操作
而如果使用methods,只要重新渲染methods就会执行该函数

计算属性默认只有getter,但是我们也可以提供一个setter

var vm = new Vue({
        el: ".test",
        data: {
            a: 1
        },
        methods:{
          click(){
              this.b=2;
          }
        },
        computed: {
            b:{
                get: function () {
                    return this.a+1;
                },
                set: function (newValue) {  //参数是必须的
                    this.a = newValue-1;   
                }
            }
        }
    })
//计算属性中默认是只有get的,我们在平时使用的时候大部分都是通过改变a的值来改变b的值
//在设置了set之后,如果我们改变b的值,那么a的值也会相应的改变
//值得改变的顺序是首先调用set改变a的值,在a的值发生改变后会调用get,b的值同时发生改变
methods

大部分时候我们定义在元素上的方法都是定义在methods中的

methods将被混入到Vue实例中,可以直接通过vm实例访问这些方法,或者在指令表达式中使用

方法中的this自动绑定为vue的实例,也就是我们需要注意一点,在使用methods时不要通过箭头函数来定义methods函数,因为箭头函数会自动绑定父级作用域的上下文

在methods中定义的事件,可以通过v-on来定义一个方法来接收

<div @click="get($event)"></div>
new Vue({
  methods:{
    get(event){
      
    }
  }
})

在通过v-on定义的方法来接收事件时可以传入参数,$event是vue封装的事件运动状态
在这段代码中在div标签get($event)中$event是我们传入的实参,methods中传入的event是形参
如果我们在div标签中没有传入参数,那么在methods中传入的是实参

在使用v-on进行事件绑定还可以有以下几种写法

<!-- 行内语法 -->
<button v-on:click="counter+=1"></button>
<!-- 对象语法 (2.4.0+) -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
<!-- 阻止默认行为,没有表达式 -->
<form @submit.prevent></form>
<input type="text" :value=value @input="value=$event.target.value">

它实际是一下写法的简写形式(这里是对vue中利用v-model分析时写的)

<body>
<div id="box">
    <!--<input type="text" :value=value @input="$event.target.value">-->
    <input type="text" @input='change($event)'>
    {{value}}
</div>
<script>
    new Vue({
        data: {
            value: ''
        },
        methods:{
            change(e){
              this.value=e.target.value
          }
        }
    }).$mount("#box")
</script>
</body>

vue.js为v-on提供了事件修饰符,可以通过.表示的指令来调用修饰符

<!--阻止事件冒泡-->
<a @click.stop="click"></a>
<!--阻止默认事件-->
<form @submit.prevent="click"></form>
<!--添加事件侦听器时使用事件捕获模式-->
<a @click.capture="click"></a>
<!--只当事件在元素本身触发时触发回调,例如在子元素触发是不响应的-->
<a @click.self="click"></a>
<!--点击事件只会触发一次-->
<a @click.once="click"></a>

<!--2.3.0版本提供了.passive选项,用来优化scroll等事件的滚动流畅度,提升移动端的流畅度-->
<div @scroll.passive="onScroll"></div>
<!--注意不要及那个passive和prevent同时使用,prevent将会被忽略-->

<!--使用修饰符时注意 1.修饰符是可以串联的-->
<a @click.stop.prevent="click"></a>
<!--2.顺序很重要 @click.prevent.self会阻止所有的点击,而@click.self.prevent只会阻止该元素的点击-->

vue.js提供了键值修饰符,在监听键盘事件时,我们经常需要监测常见键值

<!--只有在按下keyCode键码为13的键时才会触发submit事件-->
<input @keyup.13="submit">

<!--veu为常见的按键提供了别名-->
.enter .tab .delete (捕获 “删除” 和 “退格” 键) .esc .space .up .down .left .right
<!--可以通过全局config.keyCode对象自定义键值修饰符别名,例如定义keyCode为112的按键定义别名为.f1-->
Vue.config.keyCode.f1=112
<!--可以用如下修饰符开启键盘事件监听-->
.ctrl .alt .shift .meta
<!--Alt + C-->
<input @keyup.alt.67="clear">

<!--2.5.0新增加了.exact修饰符,允许我们控制精确的按键-->
<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button @click.ctrl="onClick">A</button>
<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

vue.js提供了鼠标按钮修饰符

.left   .right  .middle

在一个组件被销毁时所有挂载在该组件上的方法都会被销毁

watch

vue中提供watch对象,可以用来监视实例属性的变化,键是需要观察的表达式,值是对应回调函数/方法名/包含选项的对象,

new Vue({
        data: {
            a: 1
        },
        methods:{
          click(){
              this.a=2
          }
        },
        watch: {
            a: function (val, oldVal) {
                console.log('new: %s, old: %s', val, oldVal)
            }
        }
  //watch用来监视变量a的变化,在a发生变化后执行我们定义的函数
  //函数中传入的两个参数val代表a改变后的值,oldVal代表a改变之前的值
   
}).$mount(".test")
 
 //也可以通过调用一个在methods中已经定义方法的方法名来执行改动后的操作
 new Vue({
        data: {
            a: 1,
            b:{
              num:10
            }
        },
        methods: {
            click() {
                this.a = 2
            },
            someMethod(n, o) {
                console.log(n);
            },
        },
        watch: {
            a: "someMethod",
              //对于复杂类型的数据,要使用以下的深度类型的方法
            b: { 
                handler(val, old) {
                    console.log(val);
                    console.log(old);
                }
              //如果想要查看对象内部的某个属性值的变化,需要开启深度检测,被监测者需要是一个字符串格式例如 "b.num" 的格式
            //如果不开启深度检测对象的两个参数返回的都是改变后的值,如果开启了深度检测那么还是会返回改变之前和改变之后的值
              deep:true 
            }
        }
}).$mount(".test")

Vue实例可以通过调用$watch方法来进行监测

var vm = new Vue({
        data: {
            a: 8
        }
        methods: {
            click() {
                this.a = 2
            },
            someMethod(n, o) {
                console.log(n);
            },
        }
}).$mount(".test")

vm.$watch("a",function (n,o) {
    console.log(n);
})
parent

指定已创建的实例的父实例,在两者之间建立父子关系,子实例可以用this.$parent访问父实例
子实例被推入父实例的$children数组中

<body>
<div id="parent"></div>
<div id="child"></div>
<script>
    var vm = new Vue({
        el: "#parent",
    })
   var vn=new Vue({
       el:"#child",
       parent:vm
   })
    console.log(vn.$parent.$el) //<div id="parent"></div>
    console.log(vm.$children[0].$el); //<div id="child"></div>
</script>
</body>
mixins

混合对象可以包含任意组件选项,以组件使用混合对象时,所有混合对象的选项将被混入该组件本身的选项

这是vue官方对混合的解释,比较抽象,在实际运用后自己大概有个了解,可以简单理解为混合的作用就是将我们在页面内的组件或实例中的公共部分抽离出来,将这些公共部分单独设置为一个模块,在使用时将该模块导入即可,而不需要重复再去写这些公共部分,

在这一部分上我们可以将它理解为组件,但是与组件的不同在于,混合对象在被导入到实例/组件的时候会自动的查看是否与组件本身已有的数据冲突,如果有冲突,那么它会按照自定的规则进行合并

<body>
<div id="box">
    <child></child>
    <p @click="click">{{msg}}</p>
</div>
<script>
    var msg = {
            data: {
                msg: "实例混合对象的数据"
            }
        },
        tem = {
            data() {
                return {
                    msg: "组件混合对象的数据"
                }
            }
        },
        callback = {
            methods: {
                click() {
                    console.log("混合对象的点击事件")
                }
            },
            mounted(){
                console.log("混合对象的挂载完成函数触发");
            }
        };
    Vue.component("child", {
        template: `
            <div>
                <p @click="click">{{msg}}</p>
            </div>
        `,
        methods: {
            click(){
                console.log("组件本身的点击事件")
            }
        },
        mixins: [tem, callback]
    })
    new Vue({
        el: "#box",
        data: {
            msg: "实例原本的数据"
        },
        mounted(){
            console.log("实例本身的挂载完成函数触发");
        },
        mixins: [msg, callback]
    })
</script>
</body>

在上面的栗子我们可以注意到,混合本身的混合规则:

  • 如果实例/组件的值为对象的选项,如methods,components将被混合为一个对象,在两个对象键名冲突时,取组件/实例对象的键值对,实例中不存在相同键名时则会将混合对象的键值添加到实例/组件中
  • 如果实例/组件和混合对象含有同名选项时,例如存在同名钩子函数,那么会将这些函数混合为一个数组,因此混合对象的钩子函数和实例/组件的钩子函数都将会被调用,但是混合对象的钩子函数将会在实例/组件的钩子函数之前被调用

也可以注册全局混合对象,但是需要注意,一旦使用全局混合对象,将会影响到所有之后所有创建的Vue实例,包括第三方模板,大多数情况下不推荐使用

Vue.mixin({
  ....
})
filter

在Vue2.0之后,官方取消了内置的过滤器,但是仍然保留了自定义过滤器的方法,我们如果需要对一些常见的文本进行格式化,可以自定义一个过滤器

Vue为我们提供了两种自定义过滤器的方法,第一种是在组件内部自定义一个内部使用的过滤器

<p>{{ str | upperCase}}</p>
new Vue({
  //...
  filters:{
   upperCase(value){
     return value.toUpperCase();
   }
  }
})

第二种就是可以在Vue实例上创建全局的过滤器

new Vue({
  //...
})

Vue.filter("lowerCase",(value)=>{
  if(!value) return;
  return value.toLowerCase();
})

过滤器可以进行联写

 <p>{{ str | upperCase | lowerCase }}</p>

在过滤器中,默认的第一个参数就是我们的就收的变量,除此之外还可以接收其他参数,其他参数的第一个是我们函数中参数的第二个,依次类推

 <p>{{ str | upperCase | lowerCase("a","b") }}</p>  

过滤器除了可以应用在{{ }},也可以用来处理v-bind:

<div v-bind:id="rawId | formatId"></div>

在创建全局的filter时我们一般会将所有的过滤器放在一个文件下,然后利用Object.keys将所有的过滤器绑定到Vue实例上

import filters from './filters'
Object.keys(filters).forEach(key => Vue.filter(key, filters[key]))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容

  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 5,040评论 0 29
  • 晨起朝霞满天,一连三坐,别无二致,三山五岳,四面八方,五湖四海,六经三史,七弯八拐,八索九丘,九变十化,十步香草。...
    笨鱼也想飞阅读 251评论 0 1
  • 前些天,医叔介绍了薄荷草本磨砂膏的做法,用于滋润干燥的皮肤。不知大家有没有尝试呢?华小美童鞋说不爱薄荷那款。没关系...
    医叔有话说阅读 383评论 0 0
  • 你们都不幸福,我想。
    违愿阅读 193评论 0 0
  • 那是个不好的开头 即便它既含有巧遇的成分 又兼顾意外的契合。但无论如何 他都只能称为悲剧中反衬的两三幕喜剧片段。 ...
    空尘阅读 464评论 0 0