一,Vue基础补充
1.获取DOM对象
给标签加ref属性,ref="xxx"
this.$refs.xxx
<body> <div id="app"> <div ref="my_box">div> <button @click="my_click">点击显示文本button> div> <script> const app = new Vue({ el: "#app", methods:{ my_click:function () { // 给div标签加入文本 let ele = this.$refs.my_box; // this=>app console.log(ele); ele.innerText = "alex" } } }) script> body>
2.Vue对象:计算属性
<body> <div id="app"> <table> <thead> <tr> <th>科目th> <th>成绩th> tr> thead> <tbody> <tr> <td>Pythontd> <td><input type="text" v-model.number="python">td> tr> <tr> <td>Djangotd> <td><input type="text" v-model.number="django">td> tr> <tr> <td>Mysqltd> <td><input type="text" v-model.number="mysql">td> tr> <tr> <td>总分td> <td>{{total}}td> tr> <tr> <td>平均分td> <td>{{average}}td> tr> tbody> table> div> <script> const app = new Vue({ el: "#app", data: { // 静态属性 python: "", django: "", mysql: "", // sum: this.python + this.django + this.mysql, // =>sum:nul,不能实时监听数据的变化 }, methods: { }, computed: { // 计算属性:将所有数据放入缓存,实时监听数据,当数据改变的时候才会重新渲染,否则一直存在缓存 total: function () { return this.python + this.django + this.mysql }, average: function () { return this.total()/3 } } }) script> body>
3.Vue对象:数据的监听
watch 监听数据
-- 字符串
-- 监听到改变新的值和旧的值不同
-- 数组
-- 只能监听到长度的变化 新旧值相同的
-- 改变数组的时候监听不到,必须用$set(array,index,value)
新旧值相同
-- 对象
-- 只能监听到value的改变 必须深度监听
-- 增加对象的key 必须用$set(obj,key,value)
-- 新旧值相同
<body> <div id="app"> {{name}} <br> {{hobby}} <br> {{obj}} <button @click="my_click">点我改变数据button> div> <script> const app = new Vue({ el: "#app", data: { name: "alex", hobby: ["抽烟","烫头"], obj: { girl: "nezha", age: 36, } }, methods: { my_click: function () { //修改数据 // this.name = "alexdsb"; // 不可变数据类型,重新开辟内存,可以读两块不同的内存 // this.hobby.push("腹黑"); // 可变数据类型,会在原内存修改 // this.hobby[0] = "吸猫"; // console.log(this.hobby);//数据被修改,监听不到数据的变化,深度监听也不行 app.$set(this.hobby,0,"吸猫"); //修改可变数据类型的专用方法,主动通知浏览器有数据修改,并重新渲染页面 // this.obj.age = 18; //数据被修改,可以监听到数据的变化 // this.obj["sex"] = "女"; //添加数据,监听不到数据的变化,深度监听也不行 app.$set(this.obj,"sex","女") //修改可变数据类型的专用方法 } }, watch:{ // 监听器 name: { handler: function (val,oldval) { // hander 回调函数 console.log(val); console.log(oldval) // 可以做某些操作 } }, hobby: { //只能监听数组的长度变化,所有即使值修改了,也不会重新渲染页面 handler: function (val,oldval) { // 改变数组的长度的时候新旧值相同 console.log(val); console.log(oldval); console.log(this.hobby) }, // deep: true //深度监听 }, obj: { //在深度监听的情况,可以监听到value的变化,其他情况监听不了 handler: function (val,oldval) { console.log(val); console.log(oldval); console.log(this.obj) }, // deep: true } } }) script> body>
二,Vue的组件
1.组件的全局注册
Vue.component("组件名称",{ // 也就是不能同时有两个div template:`只识别一个块级作用域`, data() { return { name: xxx } }, methods:{}, }) -- 任何Vue实例里用<组件名称>组件名称>
<body> <div id="app"> <my_header>my_header> div> <hr> <div id="app2"> <my_header>my_header> div> <script> //全局注册的组件 可以被在其他根实例的作用域中使用 Vue.component("my_header",{ // 每一个组件都是vue可复用的实例,但是没有一些根实例的属性 template:`<div><h1>{{title}}</h1></div>`, // template:`{{title}}{{title}}`, //只能识别第一个div data(){ // 对象的单体模式 ==> data function (){} return { title:"这是头部", } }, methods: { } }); const app = new Vue({ // 根实例 el: "#app", data: {}, }); const app2 = new Vue({ el: "#app2", }) script> body>
2.组件的局部注册
-- let com_config = {......} -- const app = new Vue({ el: "#app", components: { 组件名称: com_fig } }) -- <div><组件名称>组件名称>div>
<body> <div id="app"> <div><my_com>my_com>div> div> <div id="app2"> <my_com>my_com> div> <script> let my_com_config = { template: `<div><h1>这是局部组件</h1></div>`, }; const app = new Vue({ el: "#app", data: {}, components: { my_com: my_com_config }, }); const app2 = new Vue({ el: "#app2", data: {}, components: { my_com: my_com_config }, }) script> body>
3.子组件的注册
-- 在父组件里 components: { 子组件的名称: 子组件的配置信息 } -- 在父组件的template里展示子组件 <child>child>
<body> <div id="app"> <my_com>my_com> div> <script> let child_config = { template: `<div><h2>这是一个子组件</h2></div>` }; let my_com_config = { template: `<div> <child></child> <h1>这是一个组件</h1> <child></child> </div>`,//子组件只识别一个作用域块 components: { child:child_config } }; const app = new Vue({ el: "#app", data: {}, components: { my_com: my_com_config } }); script> body>
4.父子组件的通信
先给子组件绑定属性
在子组件通过props:["属性名称"]
<body> <div id="app"> <my_com>my_com> div> <script> let child_config = { template: `<div> <h2>这是一个子组件</h2> <p>父亲跟你们说~~{{father_say}}}</p> </div>`, props: ["father_say",] //父子通信桥梁 }; let my_com_config = { template: `<div> <h1>这是一个组件</h1> <child :father_say="f_say"></child> //子组件值识别一个作用域块 </div>`, // f_say不能直接传字符串 components: { child:child_config }, data(){ //对象的单体模式 return { f_say: "滚~~~" } } }; const app = new Vue({ el: "#app", data: {}, components: { my_com: my_com_config } }) script> body>
5.子父组件的通信
子组件先提交数据:this.$emit("事件名称",data)
父组件,给子组件绑定事件:自己处理这个事件
<body> <div id="app"> <my_com>my_com> div> <script> let child_config = { template: `<div> <h2>这是一个子组件</h2> <button @click="my_click">点击向父亲说话</button> </div>`, methods: { my_click() { //向父亲说话 //子组件提交事件 this.$emit("son_say","父皇,儿臣有事启奏");
// 组件就是一个Vue实例,并且this就是指本身这个组件,但是this同时包含Vue根实例的属性 } }, }; let my_com_config = {//子组件值识别一个作用域块 template: `<div> <h1>这是一个组件</h1> <child @son_say="my_son_say"></child> <p>儿子给我说~~{{s_say}}</p> </div>`, components: { child:child_config }, methods: { my_son_say:function (data) { //这里需要接收参数,标签中可以不接受参数 this.s_say = data; //修改数据 } }, data(){ //对象的单体模式 return { s_say: "" } } }; const app = new Vue({ el: "#app", data: {}, components: { my_com: my_com_config, } }) script> body>
6.非父子组件通信
定义一个中间调度器:let Event = new Vue();
其中一个组件向中间调度器提交事件:Event.$emit("事件名称",data)
另一个组件要监听中间调度器的时间:Event.$on("事件的名称",function(data) { })
<body> <div id="app"> <com1>com1> <com2>com2> div> <script> let Event = new Vue(); // 充当中间调度器 let com1_config = { template: `<div> <h1>这是com1</h1> <button @click="my_click">点击给com2打电话</button> </div>`, methods:{ my_click(){ //给com2打电话,今晚等我 // 向Event提交事件 Event.$emit("call","今晚等我~~") } } }; let com2_config = { template: `<div> <h1>这是com2</h1> <p>com1跟我说~{{com1_say}}</p> </div>`, data(){ return{ com1_say: "" } }, mounted() { // 组件加载完成后,执行的方法 // 监听Event的事件 let that = this; Event.$on("call",function (data) { console.log(data); that.com1_say = data // 当前的this => Event }) } }; const app = new Vue({ el: "#app", data: {}, components: { com1: com1_config, com2: com2_config, } }) script> body>
7.混合
复用共用的代码块:mixins:[base]
<body> <div id="app"> <com1>com1> <com2>com2> div> <script> let base ={ data() { return { is_show: false } }, methods:{ show_text(){ this.is_show = true }, hide_text(){ this.is_show = false } } }; let com1 = { template:`<div> <button @click="show_text">点击显示文本</button> <button @click="hide_text">点击隐藏文本</button> <div v-show="is_show">点我</div> </div>`, mixins:[base], data() { //可以重写base的data,以设置is_show的值 return { is_show: true } }, }; let com2 = { template:`<div> <button @mouseenter="show_text" @mouseleave="hide_text">提示框</button> <div v-show="is_show">点我</div> </div>`, mixins:[base], }; const app = new Vue({ el: "#app", components:{ com1:com1, com2:com2 }, }) script> body>
8.插槽
实现组件内容的分发:
slot:
直接用slot标签
命名的slot:
先给slot加name属性
给标签元素添加slot属性 = name属性值
<body> <div id="app"> <com> <h3 slot="title">pythonh3> <p slot="brief">从入门到放弃p> com> <com> <h3 slot="title">Mysqlh3> <p slot="brief">从删库到跑路p> com> div> <template id="my_com"> <div> <h1>这是一个组件h1> <hr> <slot name="title">slot> <slot name="brief">slot> div> template> <script> let com = { template:"#my_com" }; const app = new Vue({ el: "#app", data: {}, components:{ com:com, } }) script> body>