vue学习05
作者:互联网
methods中定义了Vue实例的方法,官网是这样介绍的:
例如::
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script> <title>Document</title> </head> <body> <div id="app">{{message}}<button @click="ChangeMessage">测试按钮</button></div> <script> new Vue({ el:'#app', data:{message:"Hello World!"}, methods:{ ChangeMessage:function(){this.message="Hello Vue!";} } }) </script> </body> </html>
显示的样式为:
当我们点击按钮后变为了:
methods方法中的上下文为当前实例,也就是this为当前实例。
注:不应该使用箭头函数来定义 method 函数 (例如ChangeMessage:()=>this.message="Hello Vue")。理由是箭头函数绑定了父级作用域的上下文,所以 this
将不会按照期望指向 Vue 实例,this.message
将是 undefined。
源码分析
Vue实例后会先执行_init()进行初始化(4579行)时,会执行initState()进行初始化,如下:
function initState (vm) { //第3303行 vm._watchers = []; var opts = vm.$options; if (opts.props) { initProps(vm, opts.props); } if (opts.methods) { initMethods(vm, opts.methods); } //如果定义了methods,则调用initMethods初始化data if (opts.data) { initData(vm); } else { observe(vm._data = {}, true /* asRootData */); } if (opts.computed) { initComputed(vm, opts.computed); } if (opts.watch && opts.watch !== nativeWatch) { initWatch(vm, opts.watch); } }
initMethods()定义如下:
function initMethods (vm, methods) { //第3513行 var props = vm.$options.props; for (var key in methods) { //遍历methods对象,key是每个键,比如例子里的ChangeMessage { if (methods[key] == null) { //如果值为null,则报错 warn( "Method \"" + key + "\" has an undefined value in the component definition. " + "Did you reference the function correctly?", vm ); } if (props && hasOwn(props, key)) { //如果props中有同名属性,则报错 warn( ("Method \"" + key + "\" has already been defined as a prop."), vm ); } if ((key in vm) && isReserved(key)) { //如果key是以$或_开头则,也报错 warn( "Method \"" + key + "\" conflicts with an existing Vue instance method. " + "Avoid defining component methods that start with _ or $." ); } } vm[key] = methods[key] == null ? noop : bind(methods[key], vm); //如果key对应的值不是null,则执行bind()函数 } }
执行bind()函数,参数1为对应的函数体,参数2是当前的Vue实例,如下:
function polyfillBind (fn, ctx) { //当Function的原型上不存在bind()函数时,自定义一个函数实现同样的功能,用apply()或call()来实现 function boundFn (a) { var l = arguments.length; return l ? l > 1 ? fn.apply(ctx, arguments) : fn.call(ctx, a) : fn.call(ctx) } boundFn._length = fn.length; return boundFn } function nativeBind (fn, ctx) { //调用Function的原型上的bind()方法,上下文闻ctx return fn.bind(ctx) } var bind = Function.prototype.bind //如果Function的原型上有bind方法,则调用该方法,否则用自定义的polyfillBind()方法 ? nativeBind : polyfillBind;
相比较其它API,method的实现是比较简单的。
vue--watch属性
Vue提供了一个watch方法可以让使用者去监听某些data内的数据变动,触发相应的方法,比如
queryData: { name: '', creator: '', selectedStatus: '', time: [], },
注: 下面watch后的函数上都可以拿到 新值和老值 function(val, oldVal){ /*do something*/}
现在我需要监听这个queryData,我可以这样做:
watch: { queryData: { handler: function() { //do something }, deep: true } }
里面的deep设为了true,这样的话,如果修改了这个queryData中的任何一个属性,都会执行handler这个方法。不过其实这样开销是蛮大的,尤其是对象里面结构嵌套过深的时候。而且有时候我们就想关心这个对象中的某个属性,比如name,这个时候可以这样
watch: { 'queryData.name': { handler: function() { //do something }, } }
也可以这样写:
watch: { 'queryData.name': function() { //do something }, }
或者还可以这样巧用计算属性
computed: { getName: function() { return this.queryData.name } } watch: { getName: { handler: function() { //do something }, } }
搜索
复制
标签:function,vue,methods,05,watch,vm,学习,key,opts 来源: https://www.cnblogs.com/fedrgd/p/16262020.html