一、vue的特点
1、响应式的数据绑定(一旦修改了数据,立马更新视图)
- 数据驱动思想 (数据到视图的映射、操作数据改变视图、简化对DOM的操作)
- 追踪依赖变化 ( Object.defineProperty 、watcher 实例对象)
把一个普通 JavaScript 对象传给 Vue 实例的 data
选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。Object.defineProperty 是仅 ES5 支持,且无法 shim 的特性,这也就是为什么 Vue 不支持 IE8 以及更低版本浏览器的原因。
每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter
被调用时,会通知 watcher
重新计算,从而致使它关联的组件得以更新。
2、可组合的视图组件
把视图按照功能,切分若干基本单元;组件可以一级一级组合成整个应用,形成了倒置的组件树。
使用组件的好处:可维护、可重用、可测试。
注意:一个组件中只能有一个顶层标签;
实例中的data是对象,组件中的data是函数。因为组件中的data如果以对象的形式存在,会被其它组件共用。
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <style> [v-cloak] { display: none; }
/*v-clock 隐藏未编译的mustach*/
</style> <script src="./js/vue.js"></script> </head> <body> <!-- 模板 view--> <div id="app" v-cloak> <custom-com></custom-com> <custom-com2></custom-com2> <custom-coms></custom-coms> </div> <script> //定义组件 Vue.component('custom-com',{ data(){ return { test:"hello" } }, template:` <div>我是组件{{test}}</div> ` }) Vue.component('custom-com2',{ data(){ return { test:"hello" } }, template:` <div> <div>我是组件-custom-com2{{test}}</div> <input type="button" value="改变数据" @click="test=123" /> </div> ` }) // 数据 model var data = { message: 'hello,miaov.com' }; // vm view-model var vm = new Vue({ el: "#app", data: data, components:{ 'custom-coms': { template:` <div>我是局部组件</div> ` } } }); </script> </body> </html>
二、vue实例
每个vue.js应用都是通过构造函数vue创建一个vue的根实例启动的:
new Vue({ //选项 }) 选项参数:el data methods computed watch template
methods 处理纯粹的逻辑 而不是处理dom操作细节 例如 keyup 等; model 用的oninput 进行监听的 而angular 用的脏值检查。
三、vue实例生命周期
vue实例从创建到销毁的过程,就是生命周期。
钩子函数:
beforeCreate:数据绑定前; created:数据绑定后;beforeMount:挂载之前;mounted:挂载之后;
beforeUpdate:更新之前; updated:更新之后; beforeDestroy:销毁前;destroyed: 销毁后;
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <style> [v-cloak] { display: none; } </style> <script src="./js/vue.js"></script> </head> <body> <!-- 模板 view--> <div id="loading">loading....</div> <div id="app" v-cloak> {{message}} <div>1111</div> </div> <script> // 数据 model var data = { message: '' }; // vm view-model var vm = new Vue({ data: data, beforeCreate(){ console.log("数据绑定前"); console.log(this.message ); console.log("-------------------"); }, created(){ console.log("数据绑定后"); console.log( this.message ); console.log( this.$el ); console.log("-------------------"); }, beforeMount(){ console.log("挂载之前"); console.log( this.$el ); console.log("-------------------"); }, mounted(){ console.log("挂载之后"); console.log( this.$el ); console.log("-------------------"); loading.style.display = 'none'; //获取数据 发送ajax请求 setTimeout( () => { var obj = {message:"我是从服务端来得"} this.message = obj.message; },2000) }, beforeUpdate(){ console.log("更新之前"); console.log( this.message ); console.log("-------------------"); }, updated (){ console.log("更新之后"); console.log( this.message ); console.log("-------------------"); }, beforeDestroy(){ console.log("销毁前"); console.log("-------------------"); }, destroyed(){ console.log("销毁后"); } }); vm.$mount("#app"); /*setTimeout(function (){ vm.message = 'hello'; vm.$mount("#app"); },2000)*/ </script> </body> </html>
钩子函数(可理解为回调函数)其中的this 指向当前的实例对象;
$mount 推迟到未来的某个点挂载你的应用
mount的作用: 1推迟挂载点 2发送ajax请求
四、组件中的通信
1、使用prop传递数据
组件实例的作用域是孤立的。这意味着不能(也不应该)在子组件的模板内直接引用父组件的数据。要让子组件使用父组件的数据,我们需要通过子组件的props选项。
子组件要显式地用 props
选项声明它期待获得的数据。
Vue.component('child', { // 声明 props props: ['message'], // 就像 data 一样,prop 可以用在模板内 // 同样也可以在 vm 实例中像 “this.message” 这样使用 template: '<span>{{ message }}</span>' })
然后我们可以这样向它传入一个普通字符串:
<child message="hello!"></child>
在模板中,要动态地绑定父组件的数据到子模板的props,与绑定到任何普通的HTML特性相类似,就是用 v-bind
。每当父组件的数据变化时,该变化也会传导给子组件:
<div> <input v-model="parentMsg"> <br> <child v-bind:my-message="parentMsg"></child> </div>
<child :my-message="parentMsg"></child>
prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。
另外,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着你不应该在子组件内部改变 prop 。如果你这么做了,Vue 会在控制台给出警告。
2、组件间通信
- 父组件-->子组件 使用prop传递
- 子组件-->父组件 自定义事件
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <style> [v-cloak] { display: none; } </style> <script src="./js/vue.js"></script> </head> <body> <!-- 模板 view--> <div id="app" v-cloak> <custom-com :test="abc" @abc-change="abcHandle"></custom-com> <custom-com test="miaov"></custom-com> </div> <script> //定义组件 Vue.component('custom-com',{ props:["test"], data(){ return { value: this.test } }, template:` <div> <p>test:{{test}}</p> <p>value:{{value}}</p> <input type="button" @click="value=123" /> <input type="button" value="通知父组件" @click="changeAbc" /> </div> `, methods:{ changeAbc(){ // this.test = 10; this.$emit("abc-change",10) } } }) // 数据 model var data = { message: 'hello,miaov.com', abc:"hello" }; // vm view-model var vm = new Vue({ el: "#app", data: data, methods:{ abcHandle(newValue){ console.log("子组件改数据了"); console.log(newValue); this.abc = newValue } } }); </script> </body> </html>