通过一系列vue-demo入门vue2

一、创建简单vue实例

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>hello world</title><!-- 引入vue.js文件创建vue实例 --><script src='./vue.js'></script>
</head><body><div id="app">{{content}}</div><!-- <div>{{content}}</div> --><script>// var dom = document.getElementById('app');// dom.innerHTML = "Hello World!"// setTimeout(function(){//     dom.innerHtml='bye world'// },2000)var app = new Vue({el: '#app',data: {content: 'hello world!'}})setTimeout(function () {app.$data.content = 'bye world!'}, 2000)</script>
</body></html>

二、实现todoList

1.通过简单vue实例

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>todo list</title><script src='./vue.js'></script>
</head><body><div id="app"><input type='text' v-model="inputValue" /><button v-on:click="handleBtnClick">提交</button><ul><!-- <li>第一课的内容</li><li>第二课的内容</li> --><li v-for="item in list">{{item}}</li></ul></div><script>var app = new Vue({el: '#app',data: {list: [],inputValue:''},methods: {handleBtnClick: function () {// alert('click')this.list.push(this.inputValue);this.inputValue=''}}})</script>
</body></html>

2.通过jquery

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>todoList Jquery</title><script src='./jquery.js'></script>
</head><body><div><input id="input" type='text' /><button id="btn">提交</button><ul id="list"></ul></div><script>function Page() {}$.extend(Page.prototype, {init: function () {this.bindEvents()},bindEvents: function () {var btn = $('#btn');// proxy方法 会改变handleBtnClick方法的this指向,使其一直是指向这个page实例btn.on('click', $.proxy(this.handleBtnClick, this))},handleBtnClick: function () {// alert('123')var inputElem = $("#input");// 获取Input框的内容var inputValue = inputElem.val();// 将其添加到ul里面var ulElem = $("#list");ulElem.append('<li>' + inputValue + '</li>');// input框内容再置空inputElem.val('');}})var page = new Page();page.init();</script>
</body></html>

三、全局组件、局部组件、简单父传子、子传父

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>todo list</title><script src='./vue.js'></script>
</head><body><div id="app"><input type='text' v-model="inputValue" /><button v-on:click="handleBtnClick">提交</button><ul><li v-for="item in list">{{item}}</li><!-- <todo-item v-bind:content="item" v-for="item in list"></todo-item> --></ul></div><script>// 全局组件// Vue.component("TodoItem",{//     template:"<li>todo item</li>"// })// Vue.component("TodoItem",{//     props:['content'],//     template:"<li>{{content}}</li>"// })// 局部组件// var TodoItem = {//     props: ['content'],//     template: "<li>{{content}}</li>"// }var app = new Vue({el: '#app',components: { TodoItem: TodoItem },data: {list: [],inputValue: ''},methods: {handleBtnClick: function () {// alert('click')this.list.push(this.inputValue);this.inputValue = ''}}})</script>
</body></html>
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>todo list</title><script src='./vue.js'></script>
</head><body><div id="root"><input type='text' v-model="inputValue" /><button v-on:click="handleBtnClick">提交</button><ul><todo-item v-bind:content="item" v-bind:key="index" v-for="(item,index) in list" v-on:delete="handleItemDelete(index)"></todo-item></ul></div><script>// 局部组件var TodoItem = {props: ['content','index'],template: "<li v-on:click='handleItemClick'>{{content}}</li>",methods: {handleItemClick: function () {this.$emit("delete",this.index);}}}var app = new Vue({el: '#root',components: { TodoItem: TodoItem },data: {list: [],inputValue: ''},methods: {handleBtnClick: function () {// alert('click')this.list.push(this.inputValue);this.inputValue = ''},handleItemDelete: function (index) {// alert('delete')this.list.splice(index,1)}}})</script>
</body></html>

四、两种创建vue实例

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>hello world</title><script src='./vue.js'></script>
</head><body><div id="root" @click="handleCLick">{{message}}<item></item></div><script>// 全局组件Vue.component(),不用在父组件当中components中再注册Vue.component("item",{template:"<p>hello item</p>"})// 根实例var vm = new Vue({el: "#root",data: {message: "hello world!"},methods: {handleCLick: function () {alert('hello world!');}}// props computed watch})</script>
</body></html>

五、vue实例生命周期

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>生命周期</title><script src='./vue.js'></script>
</head><body><div id="app">111111</div><script>// 生命周期函数就是vue实例在某个"时间点"会"自动执行"的函数// 注意生命周期钩子没有定义在methods里面// 下面一共8个生命周期钩子,其实vue源码当中是11个,点击vue官网的学习->API// activated()  deactivated()  errorCaptured()  在后面的学习当中会给演示说明var vm = new Vue({el: "#app",template: "<div>{{test}}</div>",data: {test: "hello world!"},beforeCreate: function () {console.log("beforeCreate");},created: function () {console.log("created")},// 接着会询问是否有el选项// 然后询问有无template选项// 有template,就把模板内容直接渲染// 无template,就把el接管的dom标签的全部内容当做模板template来进行渲染 // 在渲染之前,也就是在模板和数据相结合之前的一瞬间,会执行beforeMount函数beforeMount: function () {console.log(this.$el);console.log("beforeMount");// alert("beforeMount");},// beforeMount执行后,模板和数据结合后生成的vue实例当中的dom元素会挂载(显示)到页面之上// vue实例挂载之后,会执行mounted()mounted: function () {//上面的和这行的$el反映出mounted执行后页面才渲染完毕// 这里的$el才打印出模板template中的内容console.log(this.$el);console.log("mounted");},// 下面有两个beforeDestroy()和destroyed()// 但是到页面刷新后发现并没有执行,那么它们什么时候会被执行呢?// 答:只有当vm.$destroy()方法被调用执行之后才会触发这两个生命周期钩子// 组件即将被销毁时 beforeDestroybeforeDestroy: function () {console.log("beforeDestroy");},// 组件被完全销毁后 destroyed            destroyed: function () {console.log("destroyed");},// 下面有两个beforeUpdate()和updated()// 但是到页面刷新后发现并没有执行,那么它们什么时候会被执行呢?// 答:只有当数据发生改变之后才会触发这两个生命周期钩子// 打开控制台 vm.test="zhangsan" 或 vm.$data.$test="zhangsan"// 数据发生改变但还没重新渲染之前 beforeUpdatebeforeUpdate: function () {console.log("beforeUpdate");},// 重新渲染之后 updatedupdated: function () {console.log("updated");},})</script>
</body></html>

六、vue模板语法

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>模板语法</title><script src='./vue.js'></script>
</head><body><div id="app"><div>{{name+" Lee"}}</div><div v-text="name+' Lee'"></div><div v-html="name+' Lee'"></div></div><script>var vm = new Vue({el: "#app",data: {name: "Dell"}})</script>
</body></html>

七、计算属性computed、方法method、侦听器watch

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>计算属性方法侦听器</title><script src='./vue.js'></script>
</head><body><div id="app"><!--冗余的 插值表达式 --><!-- {{firstName+" "+lastName}} --><!--1 计算属性computed --><!-- {{fullName}}  --><!--2 方法methods --><!-- {{fullName()}}  --><!--3 侦听器watch -->{{fullName}} {{age}}</div><script>var vm = new Vue({el: "#app",data: {firstName: "Dell",lastName: "Lee",// 下面这样会数据冗余fullName: "Dell Lee",age: 28},// computed watch methods  若三者都可实现某种功能,推荐使用computed// 侦听器(有缓存,只要侦听的变量所依赖的不变化,就不执行,用缓存)// 即watch与computed很类似都有缓存机制,但是推荐computed// watch: {//     firstName: function () {//         console.log("计算了一次firstName");//         this.fullName = this.firstName + " " + this.lastName;//     },//     lastName: function () {//         console.log("计算了一次lastName");//         this.fullName = this.firstName + " " + this.lastName;//     }// },// 方法(无缓存特点,只要页面渲染一次,方法就会重新执行一次)// 测试:vm.lastname="liu" 会打印“计算了一次”// 测试:vm.age=27 也会打印“计算了一次”// methods: {//     fullName: function () {//         console.log("计算了一次");//         return this.firstName + " " + this.lastName;//     }// }// 计算属性(内置缓存的特点:若计算属性依赖的值没有发生变化,就不会执行)// 测试:vm.age=27 不会打印“计算了一次”// 测试:vm.lastname="liu" 会打印“计算了一次”// computed: {//     fullName: function () {//         console.log("计算了一次");//         return this.firstName + " " + this.lastName;//     }// }})</script>
</body></html>

八、计算属性setter-getter

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>计算属性-setter+getter</title><script src='./vue.js'></script>
</head><body><div id="app">{{fullName}}</div><script>var vm = new Vue({el: "#app",data: {firstName: "Dell",lastName: "Lee"},computed: {// fullName: function () {//     return this.firstName + " " + this.lastName;// }fullName: {get: function () {return this.firstName + " " + this.lastName;},set: function (value) {// console.log(value);var arr = value.split(" ");// 因为firstName和lastName重新赋值了,所以执行set()后会引起上面的get()的执行this.firstName = arr[0];this.lastName = arr[1];}}}})</script>
</body></html>

九、vue样式绑定

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>样式绑定</title><script src='./vue.js'></script><style>.activated {color: red;}</style>
</head><body><div id="app"><!-- class 对象--><!-- 样式和数据的一个绑定,我们把这个叫做class的对象绑定 --><!-- :class="{activated:isActivated}" --><!-- class 数组-->        <!-- 可绑定多个样式名 --><!-- :class="[activated,activatedOne]" --><!-- style 对象--><!-- :style="styleObj" --><!-- style 数组 除此之外其他代码同上面style 对象形式--><!--  :style="[styleObj]" --><!-- style 数组(可以放多个对象 --><!--  :style="[styleObj,{fontSize:'20px'}]" --><div :style="[styleObj, {fontSize:'20px'}]" @click="handleDivClick">hello world</div></div><script>var vm = new Vue({el: "#app",data: {// isActivated:false// activated: '',// activatedOne:"activated-one",styleObj: {color: "black"}},methods: {handleDivClick: function () {// class :class="{activated:isActivated}"// this.isActivated = !this.isActivated;// class :class="[activated]"// this.activated = this.activated === "activated" ? "" : "activated";// stylethis.styleObj.color = this.styleObj.color === "black" ? "red" : "black";}}})</script>
</body></html>

十、vue条件渲染 v-if v-show

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>条件渲染</title><script src='./vue.js'></script>
</head><body><div id="app"><!-- v-if和v-show --><!-- v-if 直接不挂载,不存在页面dom之上 --><!-- v-show 是不显示 display:none --><!-- v-show的性能较高,因为不会频繁移除dom --><!-- <div v-if="show" data-test="v-if">{{message}}</div><div v-if="show" data-test="v-if">{{message}}</div> --><!-- v-if和v-else --><!-- v-else不必绑定变量,但这两个指令所在的标签必须紧贴使用,中间不可放其他标签,比如放一个<span></span>  --><!-- 有你没我,有我没你,dom树上只挂载其中一个 --><!-- <div v-if="show">{{message}}</div><div v-else>bye world</div> --><!-- v-if和v-else-if和v-else --><!-- 注意这三者也是有紧贴着使用 --><!-- <div v-if="show==='a'">This is A</div><div v-else-if="show==='b'">This is B</div><div v-else>This is Others</div> --><!-- 简单例子 --><!-- 问题:vue的虚拟dom机制会尽量复用页面上的dom --><!-- 比如下面如果<input/>,在切换用户名和邮箱名的时候,Input框会复用,即内容不会清空 --><!-- 解决方案,给<input key="" /> 这样vue会知道是唯一元素,就不会复用它--><!-- <div v-if="show">用户名:<input key="userName"/></div><div v-else>邮箱名:<input key="emailName"/></div> --></div><script>var vm = new Vue({el: "#app",data: {show:false,// show: 'a',message: "hello world!"}})</script>
</body></html>

十一、vue列表渲染 v-for

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>列表渲染</title><script src='./vue.js'></script>
</head><body><div id="app"><!-- 数组的循环 --><!-- <div v-for="item in list"></div> --><!-- 更推荐用of这个语法 -->   <!-- 为了提高循环性能,推荐给每一个循环项加上唯一的key值--><!-- 但是key不推荐用这里的index,推荐使用后端返回的id标识,即item.id --><!-- <div v-for="(item,index) of list":key="item.id">{{item.text}}---{{index}}</div> --><!-- template 占位符 在sources中不显示这个标签,即并不会渲染到页面之上 --><!-- 需要一个新的标签包裹使其只循环一次但是又不想用div--><!-- <template v-for="(item,index) of list"><div>{{item.text}}---{{index}}</div><span>{{item.text}}---{{index}}</span></template> --><!-- 对象的循环 --><!-- vm.userInfo.name="Dell Lee" 操作已有的key值 数据变 页面变--><!-- vm.userInfo.address="Beijing" 操作没有的key值 数据变 页面不变--><!-- 如何解决这种问题,想添加新的Key值? --><!-- 答:和上面数组一样的方法,改变对象的引用。 vm.userInfo={新对象新的Key和value值} --><!-- 但其实还有set方法,见下一节内容 --><div v-for="(item,key,index) of userInfo">{{item}}---{{key}}---{{index}}</div></div><script>var vm = new Vue({el: "#app",// vm.list.push({id:"26419",text:"try"})  成功  数据变 页面变// vm.list[4]={id:"26419",text:"try"}  失败  数据变 页面不变// 注意:我们不能通过下标方式来操作数组,只能通过vue提供的七种数组变异方法来操作数组// 数组尾部添加删除push pop// 数组头部添加删除shift unshift// 截取splice 排序sort 取反reverse// 除了上面七种方法,可以有别的方法吗?// 答:改变数组的引用地址,即直接给List赋值 vm.list=[新数组]// 还可以用set方法,见下一节内容// data: {//     list: [{//         id:"1628640",//         text:"hello"//     },{//         id:"6924155",//         text:"Dell"//     },{//         id:"0174746",//         text:"Lee"//     }]// }// 对象data:{userInfo:{name:"Dell",age:28,gender:"male",salary:"secret"}}})</script>
</body></html>

十二、vue-set

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>vue-set</title><script src='./vue.js'></script>
</head><body><div id="app"><!-- 对象 --><!-- <div v-for="(item,key,index) of userInfo">{{item}}---{{key}}---{{index}}</div> --><!-- 数组 --><div v-for="(item,index) of userInfo">{{item}}---{{index}}</div></div><script>// 对象// set即是全局方法,也是实例方法// 全局方法// Vue.set(vm.userInfo,"address","Beijing")// 实例方法// vm.$set(vm.userInfo,"address","Beijing")// 数组// 全局方法 Vue.set(vm.userInfo,2,10)// 实例方法 vm.$set(vm.userInfo,3,100)// 改数组(数据变,页面变)// (1) 七种变异方法 (2) 改变引用地址 (3)set// 改对象(数据变,页面变)// (1) 改变引用地址 (2)setvar vm = new Vue({el: "#app",data: {// userInfo: {//     name: "Dell",//     age: 28,//     gender: "male",//     salary: "secret"// }userInfo:[1,2,3,4]}})</script>
</body></html>

十三、事件绑定 v-on、@click

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>事件绑定</title><script src='./vue.js'></script>
</head><body><div id="app"><!-- @click="handleClick()"这样写会触发点击事件,但是获取不到事件对象e,可写成@click="handleClick($event)"  --><!--写法1 <button @click="handleClick($event)">Button</button> --><!--写法2 <button @click="handleClick">Button</button> --><!--写法1加括号,可以传参 @click="handleClick($event,1,2,3)" --><!-- <button @click="handleClick($event,1,2,3)">Button</button> --><!-- "/abc" 为提交form表单后的跳转地址 --><!-- 为阻止这个默认跳转的行为,可在handleClick()函数内写上e.preventDefault(); --><!-- 当然也可这样 <form action="/abc" @click.prevent> 便可实现完全一致的功能--><!-- 这是vue提供的修饰符,上面也可写成 @click.prevent="handleClick" --><!-- <form action="/abc" @click.prevent><input type="submit" /></form> --><!-- 这样的基础事件修饰符还有很多,如下 --><!-- 普通修饰符 --><!-- @click.prevent   阻止默认行为  e.preventDefault()--><!-- @click.stop   阻止事件冒泡  e.stopPropagation()--><!-- @click.self   只有e.target=e.currentTarget的时候才会执行。即只有触发元素和绑定元素一致时才会触发事件执行--><!-- @click.once   只执行一次事件 --><!-- @click.capture   事件冒泡——>事件捕获规则,当然是父和子元素都加上.capture --><!-- @click.stop   点击子元素时,若父元素也监听同样事件,将 不会冒泡到父元素身上--><!-- @click.self   只有点击标签自身的时候才会触发点击事件。点击其子元素时不触发。点击父元素也不触发。--><!-- @click.capture   按道理是按事件冒泡,由子到父的顺序,先触发子的事件再触发父的事件。 --><!-- 若加上capture的话,就事件捕获,即由父到子的顺序,先触发父的事件再触发子的事件 --><!-- <div @click.capture="handle">love<div @click.capture="handleClick">hello world</div></div> --><!-- 按键修饰符 --><!-- @keydown.enter 只有点击enter键时候才会执行后面的函数 --><!-- @keydown.esc @keydown.tab @keydown.delete 等等 --><!-- <input @keydown.enter="handleKeyDown" /> --><!-- 系统修饰符 --><!-- 和按键修饰符差不多,有四个 --><!-- @keydown.ctrl --><!-- @keydown.alt --><!-- @keydown.shift --><!-- @keydown.meta 有些特殊键盘有这个键--><!-- 即要想执行后面的函数,关按键是不够的,还需要按下对应的系统键 --><!-- <input @keydown.shift="handleKeyDown" /> --><!-- 鼠标修饰符 --><!-- @click.right  监听鼠标右键的点击事件 --><!-- @click.left  监听鼠标左键的点击事件 --><!-- @click.middle  监听鼠标中键的点击事件 --><!-- <div @click.right="handleMouseClick">click</div> --></div><script>var vm = new Vue({el: "#app",methods: {handleClick: function (e) {console.log("儿子");},handle: function (e) {console.log("爸爸");},handleKeyDown:function(e){console.log(e.target.value)},handleMouseClick:function(e){console.log("right")}}})</script>
</body></html>

十四、表单绑定v-model

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>表单绑定</title><script src='./vue.js'></script>
</head><body><!-- 表单绑定主要是指 v-model --><!-- v-model不仅可以用于 <input>标签还可以 --><div id="app"><!-- <input v-model="value" type="text"> --><!-- <textarea v-model="value"></textarea> --><!-- <input v-model="value" type="checkbox"> --><!-- <input v-model="value" type="radio" value="test"> --><!-- select v-model的value值优先选择option里的value(1,2,3),没有value才选择innerHtml(A,B,C) --><!-- <select v-model="value"><option disabled>----请选择-----</option>  这个是为了更好的用户体验<option value="1">A</option><option value="2">B</option><option value="3">C</option></select> --><!-- {{value}} --><!-- 表单修饰符 --><!-- <input type="text" v-model.lazy="value" /> --><!-- <input type="text" v-model.number="value" /> --><!-- <input type="text" v-model.trim="value" /> --><!-- v-model.number 不加时,123也会判断为string类型,加了之后会把能转换为number类型的都转换为number类型再输出 --><!-- v-model.lazy  当输入框失焦的时候才输出 --><!-- v-model.trim  去首尾空格修饰符后才输出 -->{{value}}</div><script>var vm = new Vue({el: "#app",data:{value:""},watch:{value:function(){console.log(typeof this.value)}}})</script>
</body></html>

十五、组件细节点

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>组件细节点</title><script src='./vue.js'></script>
</head><body><div id="root"><!-- 知识点1 用is解决h5标签上的一些小bug--><!-- 因为tbody里面只能接<tr> --><!-- 因为ul里面只能接<li> --><!-- 因为ol里面只能接<li> --><!-- 因为select里面只能接<option> --><!-- 故以上的都用 is属性来接所设置的子组件名字 --><!-- <table><tbody><tr is="row"></tr><tr is="row"></tr><tr is="row"></tr></tbody></table><table><ul><li is="row"></li><li is="row"></li><li is="row"></li></ul></table><table><ol><li is="row"></li><li is="row"></li><li is="row"></li></ol></table><select><option is="row"></option><option is="row"></option><option is="row"></option></select> --><!-- 知识点2 子组件当中定义data,data必须是一个返回对象的函数。只有在根组件实例中,data才可以是一个对象--><!-- <table><tbody><tr is="row"></tr><tr is="row"></tr><tr is="row"></tr></tbody></table> --><!-- 知识点3 ref --><!-- ref 获取dom或实例引用的语法 --><!-- ref在dom标签上,则this.$refs.name 获取的是这个dom元素 --><!-- ref在组件上,则this.$refs.name 获取的是这个组件的引用,即这个vue子组件实例的引用 --><!-- ref在组件的知识点见知识点4 --><!-- <divref='hello'@click="handleClick">hello world</div> --><!-- 知识点4 --><!-- 实现一个计算器求和的功能 --><!-- ref在组件上,在父组件用this.$refs.name 获取的是这个子组件的引用,即这个vue子组件实例的引用 -->        <counter ref="one" @change="handleChange"></counter><counter ref="two" @change="handleChange"></counter><div>{{total}}</div></div><script>// 知识点1// Vue.component('row', {//     template: '<tr><td>this is a row</td></tr>'// })// 知识点2 data// Vue.component('row', {// 下面这样错误,只有根组件的data才可以是对象形式// data:{//     content:"this is a row"// },// 子组件的data应该是function形式 这个函数返回一个对象// 这样设置的目的是每一个子组件<row>是独享一套数据,而不是和其他<row>共享同一套数据,这样就不会出现不同子组件之间数据互相影响的情况//     data:function(){//         return {//             content:"this is a row"//         }//     },//     template: '<tr><td>{{content}}</td></tr>'// })// 知识点3 ref// vue不建议我们直接操作dom,而是希望通过操作数据来实现对dom的操作// 但必要情况下,我们需要直接操作dom,这就需要用到ref// var vm = new Vue({//     el: '#root',//     methods:{//         handleClick:function(){// alert('click')// this.$refs 指的是整个vue实例中所有的引用// this.$refs.hello 指的是ref名为hello的dom元素//             console.log(this.$refs.hello);//             console.log(this.$refs.hello.innerHTML);//         }//     }// })// 知识点4Vue.component('counter',{template:'<div @click="handleClick">{{number}}</div>',data:function(){return {number:0}},methods:{handleClick:function(){this.number++;this.$emit('change')}}})// 注意computed不能监听refs的变化,只能放在methods当中var vm=new Vue({el:'#root',data:{total:0},methods:{handleChange:function(){// 为了父组件能够对两个子组件的数据进行求和,这时候需要用到ref方法// console.log(this.$refs.one.number);this.total=this.$refs.one.number+this.$refs.two.number}}})</script>
</body></html>

十六、父传子

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>父传子</title><script src='./vue.js'></script>
</head><body><div id="root"><!-- 父传子 props 单项数据流--><!-- :count="0" 0是数字 "0"是js表达式 --><!-- count="0" 0是字符串 --><counter :count="1"></counter><counter :count="2"></counter></div><script>var counter = {props: ['count'],data: function () {return {number: this.count}},template: "<div @click='handleClick'>{{number}}</div>",methods: {handleClick: function () {// 下面这样直接操作父组件传过来的数据,虽然可以操作成功,但是控制台会报警告说不要这样操作// 单向数据流:子组件只能接收使用父组件传过来的数据,而不可以进行操作// 因为万一传过来的不是值数据而是引用型数据的话,子组件再修改数据,会引起混乱this.number++;}}}var app = new Vue({el: '#root',// 注意局部组件才需要注册components: {counter: counter}})</script>
</body></html>

十七、子传父

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>子传父</title><script src='./vue.js'></script>
</head><body><div id="root"><!-- 子监听父的 --><!-- 监听事件 @加上事件名 例如 @inc= --><counter :count="3" @inc="handleInc"></counter><counter :count="2" @inc="handleInc"></counter><div>{{total}}</div></div><script>var counter = {props: ['count'],data: function () {return {number: this.count}},template: "<div @click='handleClick'>{{number}}</div>",methods: {handleClick: function () {this.number = this.number + 2;// 子传父,通过触发事件并且携带参数的方式// 子传父 发送事件名,后面为带过去的数据this.$emit('inc', 2)}}}var app = new Vue({el: '#root',data: {total: 5},components: {counter: counter},methods: {handleInc: function (step) {this.total += step;}}})</script>
</body></html>

十八、组件参数校验和非props

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>组件参数校验和非props</title><script src='./vue.js'></script>
</head><body><div id="root"><child content="hello world"></child><child content="hell"></child><!-- 下面为Number,不会通过String类型的校验 控制台会报错 --><!-- <child :content="123"></child> --></div><script>// 组件参数校验// 指的是子组件对父组件传递过来的content进行一些校验,比如必须要是字符串,如果是别的我不要// 要进行参数校验的话,就不能是props:['content']这种数组格式,应该写成对象,如下// props特性:父传子,子要接(一个属性),即子在props内进行了声明  父子组件有一个对应关系// 非props特性:父传子,子不接(一个属性),即子没有在props内进行声明// props特性的特点:// (1)传递的这个属性不会出现在最终渲染的标签上// (2)子可以通过插值表达式或者this.的方式获取父传过来的属性值// 非props特性的特点:// (1)传递的这个属性 会展示在子组件最外面的dom标签的html之中,即是attribute而不是property// (2)子无法获取父组件的这个内容,没法用Vue.component('child', {// 校验1// props: {//     content: Number// },// 校验2          // props: {//     content: [Object, String]// },// 校验3            // props: {//     content: {//         type: Number//     }// },// 校验4// props: {//     content: {//         type: String,// required:false, //true指的是这个值是必传的,就会报错。false则是可传可不传// default:'default value' //required:false 时如果没传则会用这个默认值// 更复杂的校验项// validator: function (value) {// 要求传过来的值的长度要大于5,否则报错//             return (value.length > 5)//         }//     }// },template: "<div>{{content}}</div>"})var app = new Vue({el: '#root'})</script>
</body></html>

十九、给组件绑定原生事件

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>给组件绑定原生事件</title><script src='./vue.js'></script>
</head><body><div id="root"><!-- @click.native --><!-- 加了native之后,此时监听的是原生事件,而不是组件的自定义事件 --><!-- 给组件绑定原生事件:在后面加上 .native修饰符即可 --><child @click.native="handleClick"></child></div><script>Vue.component('child', {template: '<div>Child</div>',// template: '<div @click="handleClick">Child</div>',// methods: {//     handleClick: function () {//         // alert('child click');//         this.$emit('click');//     }// }})var app = new Vue({el: '#root',methods: {handleClick: function () {alert('click')}}})</script>
</body></html>

二十、非父子组件传值(Bus/总线/发布订阅模式/观察者模式)

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>非父子组件传值(Bus/总线/发布订阅模式/观察者模式)</title><script src='./vue.js'></script>
</head><body><div id="root"><child content="Dell"></child><child content="Lee"></child></div><script>Vue.prototype.bus = new Vue();// 这样可以使后面创建的每个组件或者每个vue实例都具有bus这个属性// 并且这个vue属性将指向同一个vue实例// 这个vue实例存在的意义Vue.component('child', {data: function () {return {selfContent: this.content}},props: {content: String},template: "<div @click='handleClick'>{{selfContent}}</div>",methods: {handleClick: function () {// console.log(this.content);this.bus.$emit('change', this.selfContent);}},// this.bus是一个vue实例,所以具有emit和on方法mounted: function () {this.bus.$on('change', (msg) => {// alert(msg)this.selfContent = msg;})}})var app = new Vue({el: '#root'})</script>
</body></html>

二十一、vue插槽(slot)

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>vue插槽(slot)</title><script src='./vue.js'></script>
</head><body><div id="root"><!-- 旧的方案 props --><!-- <child content="<p>Dell</p>"></child> --><!-- 新的方案 slot --><!-- <child><p>Dell</p></child><child></child> --><!-- 具名插槽 slot --><body-content><div class="header" slot="header">header</div><div class="footer" slot="footer">footer</div></body-content></div><script>// 插槽的使用场景// 需求:div标签里面不仅要展示p标签,还需要展示一个标签,但是这个标签不是由子组件决定的,是由父组件传递过来的// 1.按以前的解决方法:props// 缺点1:// 这样会在p标签外多一层div标签// <div v-html="this.content"></div>// 这个模板占位符不管用// <template v-html="this.content"></template>// 缺点2:// 一旦父组件传递过来的内容变多了,就会变得阅读性困难// 单插槽// 2.这时候我们需要用新的解决方案:插槽 slot// 即如何在父子组件之间优雅的传递dom// 在子组件当中直接用<slot></slot> 即可把父组件传递的展示出来// 在子组件当中直接用<slot>默认内容</slot>,若父组件不传递内容过来便展示默认内容,若传递则展示父组件的// 多插槽 具名插槽// Vue.component('child',{//     props:['content'],//     template:`<div>//                     <p>hello</p>//                     <slot>默认内容</slot>//               </div>`// })// 具名插槽Vue.component('body-content',{props:['content'],template:`<div><slot name="header"></slot><p>hello</p><slot name="footer"></slot></div>`})var app = new Vue({el: '#root'})</script>
</body></html>

二十二、作用域插槽

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>作用域插槽</title><script src='./vue.js'></script>
</head><body><div id="root"><child><template slot-scope="props1"><li>{{props1.item}}--hello</li></template></child></div><script>Vue.component('child', {data: function () {return {list: [1, 2, 3, 4]}},template: `<div><ul><slot v-for="item of list":item=item></slot></ul></div>`})var app = new Vue({el: '#root'})</script>
</body></html>

二十三、动态组件 v-once

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>动态组件</title><script src='./vue.js'></script>
</head><body><div id="root"><!-- <component></component>就是vue里的动态组件 --><!-- 动态组件定义:根据is值的变化动态的加载不同的组件 --><component :is="type"></component><!-- 原始组件 --><child-one v-if="type==='child-one'"></child-one><child-two v-if="type==='child-two'"></child-two><button @click="handleClick">change</button><!-- v-once 内部内容只渲染一次,即使内部内容依赖数据发生变化也不重新渲染 --></div><script>Vue.component('child-one', {template: "<div>child-one</div>"})Vue.component('child-two', {template: "<div>child-two</div>"})var app = new Vue({el: '#root',data: {type: "child-one"},methods: {handleClick: function () {this.type = (this.type === 'child-one' ? 'child-two' : 'child-one')}}})</script>
</body></html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/545.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年核科学与地球化学国际会议 (ICNSG 2024)

2024年核科学与地球化学国际会议 (ICNSG 2024) 2024 International Conference on Nuclear Science and Geochemistry 【会议简介】 2024年核科学与地球化学国际会议即将在北京召开。本次会议旨在汇聚全球核科学与地球化学领域的专家学者&#xff0c;共同探讨核科学的最新进展…

不是我说,这玩意也叫高可用?

背景&#xff1a;有人求助说数据库起不来了。原因是某个文件有问题&#xff08;可以理解为无法访问或者读写&#xff09;。我问有从库吗&#xff1f;说没有。这里的高可用架构是通过存储复制做的。然后高可用那端的文件也一样。听到这里随着这个系统不是我的&#xff0c;我都忍…

Django模型的字段类型

Django模型中最重要并且也是唯一必须执行的就是字段定义。字段在类中进行定义&#xff0c;对应于实体数据库的字段。另外&#xff0c;定义模型字段名时为了避免冲突&#xff0c;不建议使用模型API中已经定义的关键字。 字段类型用以指定数据库的数据类型&#xff0c;例如Integ…

美团外卖10元无门槛通用券怎么领取10元外卖通用红包?

词令公众号美团外卖红包天天领入口&#xff0c;首次使用的外卖新客可领取10元无门槛通用券&#xff0c;点餐使用即可享受优惠&#xff1b; 美团外卖10元无门槛通用券怎么领取&#xff1f; 1、关注「词令」公众号&#xff0c;回复「外卖红包」&#xff1b; 2、打开后立即领取外…

R语言 并行计算makeCluster报错

问题&#xff1a;使用parallel包进行并行计算&#xff0c; cl <- makeCluster(detectCores()) 出现以下问题&#xff1a; 解决方式&#xff1a;用makeClusterPSOCK命令代替即可 library("future") cl <- makeClusterPSOCK(124, revtunnel TRUE, outfile &…

华为OD-C卷-查找接口成功率最优时间段[100分]Python3-100%

题目描述 服务之间交换的接口成功率作为服务调用关键质量特性,某个时间段内的接口失败率使用一个数组表示, 数组中每个元素都是单位时间内失败率数值,数组中的数值为0~100的整数, 给定一个数值(minAverageLost)表示某个时间段内平均失败率容忍值,即平均失败率小于等于m…

日志记录不再烦恼!Python开发利器Logbook模块带你飞!

在Python开发中&#xff0c;日志记录是一项至关重要的功能。通过记录应用程序的运行状态、错误信息和调试信息&#xff0c;可以帮助开发人员更好地理解程序的运行情况&#xff0c;快速定位问题并进行调试。 Python标准库中的logging模块提供了基本的日志记录功能&#xff0c;但…

基于粒子群算法改进三隐含层BP神经网络的回归预测,基于粒子群算法改进的多输入多输出BP神经网络回归分析

目录 摘要 BP神经网络的原理 BP神经网络的定义 BP神经网络的基本结构 BP神经网络的神经元 BP神经网络的激活函数, BP神经网络的传递函数 粒子群算法的原理及步骤 粒子群算法优化三隐含层BP神经网络回归分析,粒子群优化多输入多输出BP神经网络 matlab代码下载链接:粒子群算法…

华为ensp中Hybrid接口原理和配置命令

作者主页&#xff1a;点击&#xff01; ENSP专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年4月19日14点03分 Hybrid接口是ENSP虚拟化中的一种重要技术&#xff0c;它既可以连接普通终端的接入链路&#xff0c;又可以连接交换机间的干道链路。Hybrid接口允许多…

德鲁伊参数踩坑之路

上文说到 Druid德鲁伊参数调优实战&#xff0c;也正因此次优化&#xff0c;为后续问题埋下了伏笔 背景 2024/04/16日&#xff0c;业务反馈某个定时统计的数据未出来&#xff0c;大清早排查定位是其统计任务跑批失败&#xff0c;下面给一段伪代码 // 无事务执行 public void …

Linux 基于 UDP 协议的简单服务器-客户端应用

目录 一、socket编程接口 1、socket 常见API socket()&#xff1a;创建套接字 bind()&#xff1a;将用户设置的ip和port在内核中和我们的当前进程关联 listen() accept() 2、sockaddr结构 3、inet系列函数 二、UDP网络程序—发送消息 1、服务器udp_server.hpp initS…

git rebase回退到根

项目初始有2个commit&#xff0c;git rebase -i 合并提交记录只能看到一个最新的&#xff0c; 需要git rebase -i --root才能看到第一个提交 git rebase -i -root以后&#xff0c;编辑提交信息&#xff0c;然后就可以了。 之前本地调试的时候经过多次实验性操作&#xff0c;导致…

探索“人工智能+”战略下的企业切入点

在“人工智能”的大战略框架下&#xff0c;企业正面临着巨大的发展机遇与挑战。本文将深入探讨在这一战略框架下&#xff0c;企业可以采取的具体切入点&#xff0c;以实现技术创新、提升竞争力和实现可持续发展。 --- 随着人工智能技术的不断发展和应用&#xff0c;以“人工智能…

java spring 05 图灵 启动性能优化

一.doscan方法的补充&#xff1a; 01.在findCandidateComponents(basePackage)方法中&#xff1a;优化&#xff0c;因为扫描package 如果存在有索引的文件&#xff0c;使用索引文件来加载bean public Set<BeanDefinition> findCandidateComponents(String basePackage)…

docker-004-搭建本地镜像库

背景 1 官方Docker Hub地址:https:/hub.docker.com,中国大陆访问太慢了且有被阿里云取代的趋势,不太主流 2 Dockerhub、阿里云这样的公共镜像仓库可能不太方便,涉及机密的公司不可能提供镜像给公网,所以需要创建一个本地私人仓库供给团队使用,基于公司内部项目构建镜像。…

python教学入门:字典和集合

字典&#xff08;Dictionary&#xff09;&#xff1a; 定义&#xff1a; 字典是 Python 中的一种数据结构&#xff0c;用于存储键值对&#xff08;key-value pairs&#xff09;。字典使用花括号 {} 定义&#xff0c;键值对之间用冒号 : 分隔&#xff0c;每对键值对之间用逗号 …

动态规划——记忆化搜索

数字三角形 找一条最大路径。发现从上面往下一步步走很麻烦&#xff0c;直接搜索肯定超时&#xff0c;我们可以逆向求解。从下往上看。从倒数第二行开始看&#xff0c;2可以选4和5&#xff0c;因为找最大&#xff0c;所以我们选5&#xff0c;把2加上5更新为7&#xff0c;以此类…

vs2022断点空心加感叹号 解决方案

有时会出现设置的调试时&#xff0c;断点红色断点出现黄色的感叹号&#xff0c;并提示与原版本不同&#xff0c;现两种解决办法。 1、“工具”&#xff0c;“选项”&#xff0c;“调试”&#xff0c;“要求源文件与原始版本完成匹配”去掉勾。

设计模式系列:适配器模式

简介 适配器模式&#xff08;Adapter Pattern&#xff09;又称为变压器模式&#xff0c;它是一种结构型设计模式。适配器模式的目的是将一个类的接口转换成客户端所期望的另一种接口&#xff0c;从而使原本因接口不匹配而不能一起工作的两个类能够一起工作。 适配器模式有两种…

使用LVGL提升交互效率:基于启明智显Model3A方案的7寸智能屏用户界面(UI)设计介绍

项目概述&#xff1a; 【启明智显】&#xff0c;作为一家专注于HMI和AIoT解决方案的公司&#xff0c;我们致力于为用户提供创新、可靠且高效的产品和解决方案。近日我们推出了高性能及高性价比的HMI芯片——Model3A。芯片搭载了强大的2D图形加速引擎&#xff0c;能够提供高达7…