Vue(二)——实例的选项属性

版权声明:转载请注明出处 https://blog.csdn.net/le_17_4_6/article/details/88836480
vue实例

vue.js是通过 new View({…})来声明一个实例的,在这个实例中包含了当前页面的HTML结构、数据、还有事件。vue实例是MVVM模式中的viewModel,它实现了数据和视图的双向绑定。在实例化时我们可以传入一个选项对象,它包含数据、模板、挂载元素、方法、生命周期函数等选项。

模板

el:通过使用css选择语法来选择绑定的元素,如el : '#app'
templete:需要和replace一起使用,会用templete的值替换并合并绑定的元素(el指定的元素),如templete : '<div class="templete"><h2>I use a templete</h2></div>

示例:

<!DOCTYPE html>
<html>
<head>
	<title>test_template 1</title>
	<script src='http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js'></script>
</head>
<body>
	<div id="app">
	</div>
</body>

<!-- 测试templete -->
<script type="text/javascript">
	var app = new Vue({
	  el : '#app',
	  template : '<div class="template"><h2>I use a template</h2></div>'
	})
</script>
</html>

结果:

还可以通过在script元素中写入template的内容来进行调用,这样会使得html代码和js代码分离,更利于阅读和维护:

<!DOCTYPE html>
<html>
<head>
	<title>test templete 2</title>
	<script src='http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js'></script>
</head>
<body>
	<div id="app">
	</div>
</body>

<script id='template' type="x-template">
	<div class="template"><h2>I use a template</h2></div>
</script>
<!-- 测试templete 2 -->
<script type="text/javascript">
	var app = new Vue({
	  el : '#app',
	  template : '#template'
	})
</script>
</html>

结果和之前一致:

简要说一下replace参数,replace必须和template参数一起使用,replace参数决定是否用模板替换挂载元素。如果设为 true(这是默认值),模板将覆盖挂载元素,并合并挂载元素和模板根节点的 attributes。如果设为 false 模板将覆盖挂载元素的内容,不会替换挂载元素自身。

在vue.js 2.0废除了replace参数,并且强制要求vue.js实例中必须要有一个根元素包围,应该是这样

<script id='template' type="x-template">
	<div class='wrap'>
		<div class='div1'></div>
		<div class='div2'></div>
	</div>
</script>

而不是

<script id='template' type="x-template">
	<div class='div1'></div>
	<div class='div2'></div>
</script>
数据

在vue实例中初始化的data里的所有数据会自动的进行监听绑定。然后可在view中通过使用两个大括号来绑定data中的数据:

<!DOCTYPE html>
<html>
<head>
	<title>Hello World</title>
	<script src='http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js'></script>
</head>
<body>
	<div id="app">
		<h1>{{message}}</h1>
		<input type="text" v-model="message"> 
	</div>
</body>

<script type="text/javascript">
	var app = new Vue({
	  el : '#app',
	  data: {
	   message : 'Hello world'
	  } 
	})
</script>
</html>

在之后的代码中,只要通过app.message = '...'即可进行视图的实时更新,使用起来很简单,但是需要注意几点:
1、data中的数据都是浅拷贝,这意味着你修改原来的对象也会改变data,从而触发更新事件:

var info = { a: 1 }
var app = new Vue({
	el: '#app',
	data: info
})
info.a = 3 //使得data.a = 3 这里也会触发数据监听,从而更新视图
app.a = 2	//使得info.a = 2 同样会触发数据监听

2、只有初始化时传入的参数是响应的,这意味着在初始化之后才加入的数据并没有数据监听,修改它也不会有任何作用,如在初始化之后设置app. d a t a . b = 2 使 b 2 3 a p p . d a t a u n d e f i n e 使 a p p . data.b = 2,并在模板中使用{{b}},这时是不会输出2的。 3、app.data是undefine的,使用的是app. data(在vue初始化时会生成相应的参数,通过app.a调用和app.$data.a调用是一样的。但是添加初始化时没有的数据时却是截然不同的:

<!DOCTYPE html>
<html>
<head>
	<title>Hello World</title>
	<script src='http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js'></script>
</head>
<body>
	<div id="app">
		<h1>{{message}}</h1>
		<h1>{{a}}</h1>
		<h1>{{b}}</h1>
		<input type="text" v-model="message"> 
	</div>
</body>

<script type="text/javascript">
	var app = new Vue({
	  el : '#app',
	  data: {
	   message : 'Hello world'
	  } 
	})
	app.message = 'hi'
	app.b = 2
	app.$data.a = 1
	console.log(app.$data)
	console.log(app.data)
</script>
</html>

结果:

注意到通过app.b、app.$data.a设置的数据并没有起作用

打开f12:


注意到 app.b设置的是app这个对象的属性,而app.$data.a才是设置的data对象的属性。但是可以发现只有监听message的get message方法和set message方法,而没有监听a的方法。


我们可以通过通过$set()添加新的数据:

<h1>{{c}}</h1>
//...
app.$set('c', 'it worked')

结果:

奇怪的是原先设置的app.b = 2也起了作用,这可以说明vue是用实例中的数据来进行绑定的。但是在初次添加时并没有进行监听绑定,而在使用$set之后就一起进行了绑定。
查看f12:

这里发现在实例对象中有 b 和 c 但是没有a,在_data中有a和c 但是a并没有set和get。从这里可以大概看出vue是怎么进行数据的响应的。但是在vue2中并没有这样的问题出现了,vue2会显示一片空白并直接报错:


在组件的使用过程中也可以使用data,需要注意的是:
1、data 的值 必须是一个函数,并且返回值是原始对象。如果传给组件的 data 是一个原始对象的话,则在 建立多个组件实例时它们就会共用这个 data 对象,修改其中一个组件实例的数据就会影响到 其他组件实例的数据,这显然不是我们所期望的。
2、data 中的属性和 props 中的不能重名。

示例:

<!DOCTYPE html>
<html>
<head>
	<title>Hello World</title>
	<script src='http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js'></script>
</head>
<body>
	<div id="app">
		<message content='Hello World'></message> 
	</div>
</body>
<!-- 测试组件 -->
<script type="text/javascript">
	var Message = Vue.extend({
		props : ['content'],
		data : function(){return {
			a: 'it worked'
		}},
		template : '<h1>{{content}}</h1><h1>{{a}}</h1>'
	})
	Vue.component('message', Message)
	var app = new Vue({
		el : '#app', 
	})
</script>
</html>

结果

方法

我们可以通过methods来定义方法,并用v-on指令来监听DOM事件,如:

<!DOCTYPE html>
<html>
<head>
	<title>test methods</title>
	<script src='http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js'></script>
</head>
<body>
	<div id="app">
		<h1 v-on:click='bind_click'>{{message}}</h1>
		<input type="text" v-model="message"> 
	</div>
</body>

<script type="text/javascript">
	var app = new Vue({
		el : '#app',
		methods : {
			bind_click: function() {
				alert("you click it")
			}
		},
		data: {
			message : 'click me'
		} 
	})
</script>
</html>

点击之后的结果:

生命周期函数

生命周期包含着vue从创建到更新到消亡的所有事件,通过重载这些事件,可以在某一个特定的时期执行相应的操作。
简单列举一下:

  • init: 在实例开始初始化时同步调用。此时数据观测、事件等都尚未初始化。2.0 中更名beforeCreate。
  • created :在实例创建之后调用。此时已完成数据绑定、事件方法,但尚未开始 DOM 编译,即未挂载到 document 中。
  • beforeCompile: 在 DOM 编译前调用。2.0 废弃了该方法,推荐使用 created。
  • beforeMount: 2.0 新增的生命周期钩子,在 mounted 之前运行。
  • compiled: 在编译结束时调用。此时所有指令已生效,数据变化已能触发 DOM 更新,但 不保证 $el 已插入文档。2.0 中更名为 mounted。
  • ready :在编译结束和$el 第一次插入文档之后调用。2.0 废弃了该方法,推荐使用 mounted。这 个变化其实已经改变了ready这个生命周期状态,相当于取消了在$el首次插入文档后的钩子函数。
  • attached :在 app.$el插入 DOM 时调用,ready 会在第一次 attached 后调用。操作 $el必须使用指令或实例方法(例如 $appendTo()),直接操作 app.$el 不会触发这个钩子。2.0 废 弃了该方法,推荐在其他钩子中自定义方法检查是否已挂载。
  • detached: 同 attached 类似,该钩子在 app.$el 从 DOM 删除时调用,而且必须是指令或 实例方法。2.0 中同样废弃了该方法。
  • beforeDestroy: 在开始销毁实例时调用,此刻实例仍然有效。
  • destroyed: 在实例被销毁之后调用。此时所有绑定和实例指令都已经解绑,子实例也被销毁。
  • beforeUpdate: 2.0 新增的生命周期钩子,在实例挂载之后,再次更新实例(例如更新 data)时会调用该方法,此时尚未更新 DOM 结构。
  • updated:2.0 新增的生命周期钩子,在实例挂载之后,再次更新实例并更新完 DOM 结构 后调用。
  • activated :2.0 新增的生命周期钩子,需要配合动态组件keep-live 属性使用。在动态 组件初始化渲染的过程中调用该方法。
<!DOCTYPE html>
<html>
<head>
	<title>test lifeCycle</title>
	<script src='http://cdnjs.cloudflare.com/ajax/libs/vue/2.6.3/vue.min.js'></script>
</head>
<body>
	<div id="app">
		<h1>{{message}}</h1>
		<input type="text" v-model="message"> 
	</div>
</body>

<script type="text/javascript">
	var app = new Vue({
		el : '#app',
		data: {
			message : 'test lifeCycle'
		},
		created: function() {
			console.log('created')
		},
		beforeCompile: function() {
			console.log('beforeCompile')
		},
		compiled: function() {
			console.log('compiled')
		},
		attached: function() {
			console.log('attached')
		},
		dettached: function() {
			console.log('dettached')
		},
		beforeDestroy: function() {
			console.log('beforeDestroy')
		},
		destroyed: function() {
			console.log('destroyed')
		},
		ready: function() {
			console.log('ready') // 组件完成后调用$destory()函数,进行销毁
			this.$destroy()
		} 
	})
</script>
</html>

结果:

猜你喜欢

转载自blog.csdn.net/le_17_4_6/article/details/88836480