vue基础

vue2主要语法点记录。下面的代码是为了速查用法,没有使用脚手架,js为es5写法,没有注意eslink验证。

vue实例

js

var vm = new Vue ({
    el: '#app',
    data: {
      msg: 'hello vue'
    }
});

console.info(vm.msg); //hello vue
console.info(vm.$data.msg); //hello vue
console.info(vm.msg === vm.$data.msg) //true

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue</title>
    <script type="text/javascript" src="https://cdn.bootcss.com/vue/2.5.13/vue.min.js"></script>
</head>
<body>
    <div id="app">
        {{msg}}
    </div>
    <script type="text/javascript" src="script/index.js"></script>
</body>
</html>

vue实例中的选项:
el:vue实例的挂载点,和angular中的ng-app类似,可以用css选择符
data:vue实例上挂载的数据,可以用实例.$data.名称提取,也可以用实例.名称提取,是一份数据,和angular中的scope类型。
template:使用template模板替换挂载点内容。
components:引入其他组件。

使用脚手架生成的SPA框架,vue实例已经初始化好,挂载在入口index.html的#app上。

动态改变数据

var vm = new Vue ({
    el: '#app',
    data: {
      msg: 'hello vue',
      person: {
         name: 'thatway'
      }
    },
    methods: {
       addAge: function(){
         console.info("addAge");
         this.$data.person.age = 18;
         console.info(this.person.age); //18
       }
    }
});

给this.$data动态添加数据,注意是添加新数据不是修改,视图上不会出现新数据,上面的实例中虽然打印出18,但视图并没有改变,动态改变实例数据的方法:

用途用法
单个属性Vue.set(Object,key,value)
多个属性Object.assign()

实例中this.$data.person.age = 18;更改为Vue.set(this.person,'age',18);视图随之改变。

多个数据:

 this.person = Object.assign({},this.$data.person,{age: 18, name:'wp'});

Object.assign 将参数中的所有对象属性和值 合并到第一个参数 并返回合并后的对象。

获取dom更新后数据
更新后dom中的数据 通过 Vue.nextTick(callback)

tick: function(){
           this.msg = 'change'
           this.$nextTick(function () {
               console.log('$nextTick中打印:', this.$el.children[0].innerText);
           })
           console.log('直接打印:', this.$el.children[0].innerText);
       }

输出:
直接打印: hello vue
$nextTick中打印: change

计算属性
计算属性,是vue中可以声明一系列属性,这些属性是通过计算而来的,它依赖于参与计算的属性是否发生变化,计算结果会被缓存,参与计算的属性值不变则会使用缓存,可以提升性能。

var vm = new Vue ({
    el: '#app',
    data: {
      v1: 10,
      v2: 9
    },
    computed: {
      computeValue: function(){
         return this.v1 + this.v2;
      }
    }
});

页面中

<div>{{computeValue}}</div>

组件

全局组件
全局组件在所有的vue实例中都可以使用

Vue.component('component-test',{
    template: '<div>this is component-test,{{componentMsg}}</div>',
    data: function(){
        return {
            componentMsg: 'hello component'
        }
    }
});

页面中使用标签
<component-test></component-test>
需要注意的是
全局组件要在vue实例化之前注册,坑
template比较长时可以用x-template方式引入

<script type="text/x-template" id="testtpl">
   <div>{{componentMsg}}</div>
</script>

组件中改为

Vue.component('component-test',{
    template: '#testtpl',
    data: function(){
        return {
            componentMsg: 'hello component'
        }
    }
});

效果一样。有点angular中模板缓存的意思。
大多数情况下是不需要注册全局组件的,而是创建好组件需要的地方引入组件。
局部组件
在需要引入组件的实例中使用components选项实现。

var componentTest = {
    template: '#testtpl',
    data: function(){
        return {
            componentMsg: 'component'
        }
    }
}

var vm = new Vue ({
    el: '#app',
    data: {
      msg: 'hello vue',
      person: {
         name: 'thatway'
      }
    },
    components: {
      'component-test':componentTest
    }
});

当组件名声明为驼峰写法时,视图中应在驼峰处改为-连接,如声明一个组件componentTest,视图中的标签名应为component-test。
component模板中只能有一个根节点,这点与angular、react都是一样的。
使用webpack模板,每一个组件可以封装成一个.vue文件,导出后在需要的组件上引入,多页面应用时就要自己来组织了。

组件data
上面封装组件时,如果数据是使用data{componentMsg: 'component'}那么,所有组件都将引用这个data,有点类似angular的全局scope,实际希望每个组件拥有自己的数据,对外不影响,应该使用data:function(){return 数据对象}的方式,有点类似angular的独立scope。

组件通信

组件内的数据仅当前组件可见,这就需要一套与其他组件进行数据通信的机制,比如首页上有可能出现两个广告位,这两个广告位的数据是相互独立的,互不影响,但又有可能都是从父组件(首页)中获取的。在之前的angular项目中绝大部分的组件数据都封装成开放的了,共有一份scope数据,仅将页面中一开始就有多个的组件数据封装为独立scope,实践证明是有问题的,在某个组件在未来需要在页面上出现多个时麻烦就来了,及时不出现多个,数据也是混乱的。

  • 父组件到子组件
    父组件中的数据传递到子组件中,关键在子组件的component实例中使用props选项。
 var componentTest = {
    props: [
        'personInfo',
        'stringMsg'
    ],
    template: '#testtpl',
    data: function(){
        return {
            componentMsg: 'component'
        }
    }
};

var vm = new Vue ({
    el: '#app',
    data: {
      msg: 'hello vue',
      person: {
         name: 'thatway'
      }
    },
    components: {
      'component-test':componentTest
    }
});

组件模板

<script type="text/x-template" id="testtpl">
    <div>
        <div>personName:{{personInfo.name}}</div>
        <div>stringMsg:{{stringMsg}}</div>
    </div>
</script>

页面中

<component-test :person-info="person" string-msg="this is string"></component-test>

这里同样注意参数的驼峰转连接符问题。

  • 子组件到父组件
    子组件的数据传递给父组件,需要使用vue的自定义事件机制,与react是一样的。
 var childComponent = {
  template: '<div><button @click="toParent">向父组件传递数据</button></div>',
  data: function(){
    return {
        info: {
            msg: 'this is child msg'
        }
    }
  },
  methods: {
    toParent: function(){
      console.info("toParent");
      this.$emit('parentfn',this.info);
    }
  }
};

var vm = new Vue ({
    el: '#app',
    data: {
      msg: 'hello vue',
      person: {
         name: 'thatway'
      }
    },
    components: {
      'component-test': componentTest,
      'childComponent': childComponent
    },
    methods: {
      handleChild: function(data){
         console.info("来自子组件的数据" + data.msg);
      }
    }
});

页面中

<child-component @parentfn="handleChild"></child-component>

子组件上定义一个自定义事件parentfn,指向父组件的一个方法handleChild。
子组件内部toParent方法,使用$emit触发parentfn事件,并给事件传值。

  • 非父子组件通信
    两个没关系的组件通信可以借助在空vue实例绑定与触发自定义事件来实现。
var vueTemp = new Vue();

var childComponentA = {
    template: '<div><button @click="toA">告诉B点事</button></div>',
    data: function(){
        return {
            msg: '你背后有个人...'
        }
    },
    methods: {
      toA: function(){
        var that = this;
        vueTemp.$emit('handleA',that.msg);
      }
    }
};

var childComponentB = {
    template: '<div>B告诉我{{talk}}</div>',
    data: function(){
      return{
        talk: ''
      }
    },
    created: function(){
      var that = this;
      vueTemp.$on('handleA',function(data){
        console.info("handleA:"+data);
        that.talk = data;
      });
    }
};


var vm = new Vue ({
    el: '#app',
    data: {
      msg: 'hello vue',
      person: {
         name: 'thatway'
      }
    },
    components: {
      'childComponentA': childComponentA,
      'childComponentB': childComponentB
    }
});

页面中

<child-component-a></child-component-a>
<child-component-b></child-component-b>

代码中创建了一个空的vue实例vueTemp,在A中$on绑定一个自定义事件,在B中触发自定义事件。
上面代码中因为是es5的语法,会出现this指向问题,es6箭头函数就不用转换了。

  • 组件插槽
    vue中使用slot标签可以实现内容的占位或者叫分发。
var slotComponent = {
  template: '<div>' +
  '这是slotComponent的内容' +
  '<slot></slot>' +
  '<slot name="slotA"></slot>' +
  '</div>'
};


var vm = new Vue ({
    el: '#app',
    data: {
      msg: 'hello vue',
      person: {
         name: 'thatway'
      }
    },
    components: {
      'slotComponent': slotComponent
    }
});

页面中

<slot-component>
    <div slot="slotA">这是带名称的slot</div>
    <div slot>页面上原来的内容</div>
</slot-component>

可以有一个不带名称的slot,实际场景里一般一个就够用了,就不用写name了,内容出现的位置是组件template中slot标签的位置。

  • 引用组件
    vue实例上有一个$refs,页面中的元素(标签)如果声明了ref,则可以通过$refs获取到,如果是普通html标签,则获取到的是html元素,如果是一个组件,则获取到这个组件的实例数据。
var vm = new Vue ({
    el: '#app',
    data: {
      msg: 'hello vue',
      person: {
         name: 'thatway'
      }
    },
    components: {
      'slotComponent': slotComponent
    },
    mounted: function(){
       console.info(this.$refs.refdiv);
       console.info(this.$refs.refcomponent);
    }
});

页面中

<div v-text="person.age" ref="refdiv"></div>
<slot-component ref="refcomponent">
    <div slot="slotA">这是带名称的slot</div>
    <div slot>页面上原来的内容</div>
</slot-component>

指令

指令(directive)是用于数据与视图进行交互,实际运用是vue中以v-开头的标签属性,在vue中指令叫directive,组件叫component,需要理解、区分概念。
指令看官方文档即可,下面简单罗列常用指令。

指令简写修改器描述
v-html--向元素绑定html内容
v-text--与插值{{}}相同效果,但可防止闪屏
v-bind:-绑定属性值
v-model--绑定数据对象,双向绑定
v-for--循环,item in list、(item,index)in list、(item,key,index) in list、item in 1000,提供唯一标识避免渲染耗时用:key=”标识”
v-if--判断,会创建和销毁dom
v-show--切换显示状态,dom始终存在
v-on@.stop 阻止冒泡、.prevent 阻止默认行为、capture 添加事件侦听器时使用事件捕获模式、.self 只当事件在该元素本身(比如不是子元素)触发时,才会触发事件、.once事件只触发一次绑定时间,如v-on:click或@click
v-once--数据只绑定一次
v-pre--内容显示原始状态

样式
与angular中的ng-class类似。

<!-- 1 -->
<div v-bind:class="{ active: true }"></div> ===> 解析后
<div class="active"></div>

<!-- 2 -->
<div :class="['active', 'text-danger']"></div> ===>解析后
<div class="active text-danger"></div>

<!-- 3 -->
<div v-bind:class="[{ active: true }, errorClass]"></div> ===>解析后
<div class="active text-danger"></div>


--- style ---
<!-- 1 -->
<div v-bind:style="{ color: activeColor, 'font-size': fontSize + 'px' }"></div>
<!-- 2 将多个 样式对象 应用到一个元素上-->
<!-- baseStyles 和 overridingStyles 都是data中定义的对象 -->
<div v-bind:style="[baseStyles, overridingStyles]"></div>

自定义指令

自定义指令用来操作dom,就是自己定义一些v-指令,和组件、过滤器一样,有全局和局部的区别。
直接贴个大拿的解释代码吧:
全局指令

// 第一个参数:指令名称
// 第二个参数:配置对象,指定指令的钩子函数
Vue.directive('directiveName', {
  // bind中只能对元素自身进行DOM操作,而无法对父级元素操作
  // 只调用一次 指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  bind( el,binding, vnode ) {
    // 参数详解
    // el:指令所绑定的元素,可以用来直接操作 DOM 。
    // binding:一个对象,包含以下属性:
      // name:指令名,不包括 v- 前缀。
      // value:指令的绑定值,等号后面的值 。
      // oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
      // expression:字符串形式的指令表达式 等号后面的字符串 形式
      // arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。
      // modifiers:指令修饰符。例如:v-directive.foo.bar中,修饰符对象为 { foo: true, bar: true }。
    // vnode:Vue 编译生成的虚拟节点。。
    // oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
  },
  // inserted这个钩子函数调用的时候,当前元素已经插入页面中了,也就是说可以获取到父级节点了
  inserted (  el,binding, vnode ) {},
  //  DOM重新渲染前
  update(el,binding, vnode,oldVnode) {},
  // DOM重新渲染后
  componentUpdated ( el,binding, vnode,oldVnode ) {},
  // 只调用一次,指令与元素解绑时调用
  unbind ( el ) {
    // 指令所在的元素在页面中消失,触发
  }
})
// 简写 如果你想在 bind 和 update 时触发相同行为,而不关心其它的钩子:
Vue.directive('自定义指令名', function( el, binding ) {})
// 例:
Vue.directive('color', function(el, binding) {
  el.style.color = binging.value
})
// 使用 注意直接些会被i成data中的数据“red” 需要字符串则嵌套引号"'red'"
<p v-color="'red'"></p>

局部变量

var vm = new Vue({
  el : "#app",
  directives: {
    directiveName: { }
  }
})

过滤器

过滤器是在页面上输出之前做一遍过滤,分全局过滤器和局部过滤器,用法和组件基本一样
全局过滤器:

Vue.filter('testfilter',function(value){
    return value+"filter";
});
 <div>{{person.name|testfilter}}</div>

局部过滤器只对当前实例有效,使用实例的filters属性

var testFilter = function(value){
    return 'filter,'+value;
};
var vm = new Vue ({
    el: '#app',
    data: {
      msg: 'hello vue',
      person: {
         name: 'thatway'
      }
    },
   filters:{
     testFilter:testFilter
   }
});

watch

监听实例数据,和angular的$watch作用一样。

var vm = new Vue ({
    el: '#app',
    data: {
      msg: 'hello vue',
      person: {
       name: 'thatway'
      },
      info: {
        key: 'thatway'
      }
    },
   filters:{
     testFilter:testFilter
   },
   methods:{
     changeData: function () {
        this.msg = "123";
        this.person.name = 'wp';
        this.info.key = '111';
     }
   },
   watch: {
     msg: function(newVal,oldVal){
        console.info("watch msg");
        console.info(newVal,oldVal);
     },
     person: {
        handler: function(newVal,oldVal){
           console.info("watch person");
           console.info(newVal,oldVal);
        },
        deep:true
     },
     'info.key': function(newVal,oldVal){
        console.info("watch info.key");
        console.info(newVal,oldVal);
     }
   }
});

生命周期

vue在生命周期中提供了一系列的钩子函数。官方图很清晰,这里做个简单记录。

  • beforeCreate()
    在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用,此时,无法获取 data中的数据、methods中的方法
  • created()
    实例已创建完毕,最常用的生命周期,可以调用methods中的方法、改变data中的数据
  • beforeMounted()
    实例挂载之前被调用
  • mounted()
    vue实例已经挂载到页面中,dom已经渲染好
  • beforeUpdated()
    数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。此处获取的数据是更新后的数据,但是获取页面中的DOM元素是更新之前的。
  • updated()
    组件 DOM 已经更新,可以执行依赖于 DOM 的操作。
  • beforeDestroy()
    实例销毁之前调用。在这一步,实例仍然完全可用。使用场景:实例销毁之前,执行清理任务,比如:清除定时器等。
  • destroyed()
    Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

vue中文文档:https://cn.vuejs.org/v2/api/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值