前端:Vue学习-2

news2024/11/26 15:25:32

前端:Vue学习-2

    • 1. vue的生命周期
    • 2. 工程化开发和脚手架Vue CLI
      • 2.1 组件化开发
      • 2.2 scoped解决样式冲突
      • 2.3 data是一个函数
      • 2.4 组件通信
      • 2.5 非父子通信- event bus事件,provide&inject
    • 3.v-model原理->实现父子组件双向绑定
    • 4. sync 修饰符->实现父子组件双向绑定
    • 5. ref 和 $refs
    • 6. Vue异步更新,$nextTick

1. vue的生命周期

Vue的生命周期,一个Vue实例从创建到销毁的整个过程。
生命周期的四个阶段为:创建、挂载、更新、销毁

  1. 创建阶段,把数据转化为响应式数据;
  2. 挂载阶段,渲染模板;
  3. 更新阶段,数据修改,更新视图;
  4. 销毁阶段

Vue生命周期函数(钩子函数)
请添加图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue2</title>
    <script src="../vue2.js"></script>
</head>
<body>
    <div id="app">
        <input type="text" v-model.number="count">
        <h4>{{count}}</h4>
    </div>
    <script>
        const app = new Vue({
            el:'#app',
            data:{
                count:100
            },
            beforeCreate(){
                console.log('before Create',this.count);
            },
            created(){
                console.log('created',this.count);
            },
            // 创建阶段
            beforeMount(){
                console.log('beforeMount',document.querySelector('h4').innerText);
            },
            mounted(){
                console.log('mounted', document.querySelector('h4').innerText);
            },
            // 挂载阶段
            beforeUpdate(){
                console.log('beforeUpdate', document.querySelector('h4').innerText);
            },
            updated(){
                console.log('updated', document.querySelector('h4').innerText);
            },
            // 更新阶段
            beforeDestroy(){
                console.log('beforeDestory');
                console.log('清除一些vue以外的资源占用,比如定时器等');
            },
            destroyed(){
                console.log('destoryed');
            }
            //销毁阶段
        })
    </script>
</body>
</html>

请添加图片描述

2. 工程化开发和脚手架Vue CLI

安装脚手架的命令,前提是本地电脑上已经安装nodejs,安装命令为:

npm install @vue/cli -g
// 全局安装
vue --version
// 查看安装的版本

在这里插入图片描述
创建vue项目为:

vue create 项目名

启动项目命令为:

// 首先需要cd到当前项目目录下
cd 项目名
npm run serve   // 启动项目

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

这个项目文件结构为:node_modules-第三方包目录,public-放html文件的目录,src-源代码目录,package.json-项目配置文件,jsconfig.json-js配置文件。。。src有个main.js文件,为项目的核心文件

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

// vue实例化
new Vue({
  // render: h => h(App),
  render:(createElement)=>{
    return createElement(App)
  }
}).$mount('#app')


2.1 组件化开发

一个页面可以拆分为一个个组件,每个组件可以拥有自己独立的结构、样式、行为,结构下有且只能有一个根元素。使样式支持less语法,需要安装less,npm命令为:

npm install less-loader

组件注册:局部注册、全局注册
局部注册,在components目录下新建“.vue”文件,文件命名采用大驼峰命名。然后在这个新建的vue文件下输入组件的三个组成部分,分别为结构、样式和行为。在App.vue根组件引入这个组件,并进行组测,然后就可以在根组件中使用这个组件了。

<script>
import Com from './components/Com.vue'

export default {
  name: 'App',
  components: {
    Com:Com
  }
}
</script>

全局注册,在main.js中进行全局注册,==所有组件内均可以使用该组件 ==。

import Com from './components/Com.vue'

Vue.component('Com',Com)
// 进行全局注册,对应的组件名,组件对象

2.2 scoped解决样式冲突

写在组件中的样式会全局生效,因此会造成多个组件之间的样式冲突。可以给组件的样式标签添加scoped属性,可以让样式只作用于当前组件。
在这里插入图片描述
加上scoped属性。

<style scoped>
    .com-1{
        width: 200px;
        height: 40px;
        background-color: red;
    }
</style>

在这里插入图片描述
实现原理:加上scoped之后,不同组件的标签元素上会自动添加上自定义属性“data-一个hash值”。
在这里插入图片描述

2.3 data是一个函数

一个组件的data选项必须使一个函数,可以保证每个组件实例,维护独立的一份数据对象。 每次创建新的组件实例,都会重新执行一次data函数,得到一个新对象。
Com组件:

<template>
    <div class="com-1">
        <button @click="fn(-1)">-1</button>
        {{count}}
        <button @click="fn(1)">+1</button>
    </div>
</template>

<script>
export default {
    name:'Com',
    data(){
        return{
            count:1
        }
    },
    methods:{
        fn(p){
            this.count += p;
        }
    }
}
</script>

<style scoped>
    
</style>
<template>
  <div id="app">
    <Com></Com>
    <br>
    <Com></Com>
    <br>
    <Com></Com>
  </div>
</template>

请添加图片描述

2.4 组件通信

父、子组件通信,父组件通过props将数据传递给子组件。在父组件中给子组件添加动态属性,属性值为父组件中的数据。在子组件中使用props来接收父组件传递来的数据。如果在子组件中想要修改这个父组件中的数据,可以通过this.$emit(‘父组件中传递的动态函数名’,要修改的值)
父组件:

<template>
  <div id="app">
    <p>{{title}}</p>
    <Com :count1="count" @changeCount="fn" @changeTitle="fn1"></Com>
  </div>
</template>
<script>
export default {
  name: 'App',
  data(){
    return{
      count:1,
      title:'hello world!'
    }
  },
  methods:{
    fn(){
      this.count ++;
    },
    fn1(newTitle){
      this.title = newTitle;
    }
  }
}
</script>
<style>
</style>

子组件:

<template>
    <div class="com-1">
        <p>{{count1}}</p>
        <button @click="fn1">修改</button><br>
        <button @click="fn2">修改名称</button>
    </div>
</template>

<script>
export default {
    name:'Com',
    props:['count1'],
    methods:{
        fn1(){
            this.$emit('changeCount');
        },
        fn2(){
            this.$emit('changeTitle','hello Vue!');
        }
    }
}
</script>

<style>
    
</style>

请添加图片描述
可以传递任意数量的prop,传递任意类型的prop。

props校验
校验有类型校验、非空校验、默认值、自定义校验
类型校验如下:

props:{
	校验的属性名:类型
}
// 类型可以为Number、String、Boolean、

完整的校验为:

props:{
	校验的属性名:{
		type:类型,
		required:true,  // 是否必填
		default:默认值,
		validator(value){
			// 逻辑
			return 是否通过校验
			// return true或false
		}
	}
}

prop和data的区别
共同点:都可以给组件提供数据
区别:data的数据是组件本身的,可以随便改;prop的数据是外部的,不能直接改,要遵循单向数据流。

2.5 非父子通信- event bus事件,provide&inject

event bus事件
适用于兄弟组件。新建工具js文件,js文件代码如下:

import Vue from 'vue'

const bus = new Vue();

export default bus

在BaseA组件接收方代码如下:

<template>
  <div>
    我是BaseA组件
    <p>{{count}}</p>
  </div>
</template>

<script>
import bus from '../utils/bus'

export default {
    name:'BaseA',
    data(){
        return {
            count:1
        }
    },
    created(){
        bus.$on('changeCount',(count)=>{
            this.count = count;
        })
    }
}
</script>

<style scoped>
    div{
        width: 200px;
        height: 100px;
        border: 1px solid black;
    }
</style>

BaseB组件发送方代码如下:

<template>
  <div>
    我是组件BaseB <br>
    <button @click="fn">修改组件BaseA中的值</button>
  </div>
</template>

<script>
import bus from '../utils/bus'
export default {
    name:'BaseB',
    methods:{
        fn(){
            bus.$emit('changeCount',12);
        }
    }
}
</script>

<style scoped>
    div{
        width: 200px;
        height: 100px;
        border: 1px solid black;
    }
</style>

运行结果:
请添加图片描述
在组件接收方中通过bus.$on对事件进行监听,组件发送方通过bus.$emit使组件接收方中事件进行触发。这是一个一对多的关系,即一个发送方组件,可以有多个接收方组件进行监听。

provide&inject
跨层级共享数据,适用于祖孙组件,在祖先组件中使用provide进行数据共享,在子或孙组件中使用inject进行接收。需要注意的是如果数据是简单类型,那么为非响应式的;如果数据是复杂类型,那么为响应式的。
祖先组件代码如下:

import BaseS from './components/BaseS.vue'


export default {
  name: 'App',
  data(){
    return{
      color:'red',
      person:{
        name:'liuze'
      }
    }
  },
  components:{
    BaseS
  },
  provide(){
    return{
      person:this.person,
      color:this.color
    }
  },
  methods:{
    fn(){
      this.color = 'blue';
      this.person.name = 'lz';
    }
  }
}

孙子组件代码如下:

<template>
    <div class="son-s">
        孙子组件
        <p>
            {{color}}
            {{person.name}}
        </p>
    </div>
</template>

<script>
export default {
    name:'BaseSS',
    inject:[
        'color','person'
    ]
}
</script>

<style scoped>
    .son-s{
        border: 1px solid black;
        width: 100px;
        height: 100px;
    }
</style>

运行结果:
请添加图片描述

3.v-model原理->实现父子组件双向绑定

v-model本身是一个语法糖,应用在输入框上,就是value属性和input事件的合写。
数据变,视图跟着变“:value”;视图变,数据跟着变“@input”。

<input type="text" :value="val" @input="val = $event.target.value">

请添加图片描述

父子组件不能直接使用v-model的,因为v-model是双向数据绑定,而子组件是无法直接修改父组件中的数据的。如果要使用v-model,那么在子组件中对父组件中数据进行修改就必须使用“:value”及“input”,即 props:{value}和this.$emit(‘input’,更新的数据)
具体例子为:v-model原理:父组件、子组件使用v-model

4. sync 修饰符->实现父子组件双向绑定

可以实现子组件父组件数据的双向绑定,简化代码。prop属性名,可以自定义,非固定为value。使用场景,封装弹框类的基础组件。本质上就是 :属性名和@update:属性名 合写;如下的弹框父子组件如下:

<template>
  <div class="diag" v-show="visible">
    <button @click="fn">X</button>
  </div>
</template>

<script>
export default {
    props:{
        visible:Boolean
    },
    methods:{
        fn(){
            this.$emit('update:visible',false);
        }
    }
}
</script>

<style>
    .diag{
        width: 200px;
        height: 100px;
        border: 1px solid black;
        background-color: red;
        position: relative;
    }
    .diag button{
        position: absolute;
        top: 2px;
        right: 2px;
        width: 20px;
        height: 20px;
        line-height: 20px;
        text-align: center;
    }
</style>
<template>
  <div id="app">
      <button @click="fn">取消修改</button>
      <Diag :visible.sync="isShow" ></Diag>
  </div>
</template>
<script>
import Diag from './components/Diag.vue'

export default {
  name: 'App',
  components:{
    Diag
  },
  data(){
    return{
      isShow:false
    }
  },
  methods:{
    fn(){
      this.isShow = true;
    }
  }
}
</script>
<style scoped>
</style>

运行结果:
请添加图片描述

5. ref 和 $refs

利用ref和$refs可以用于获取dom元素或组件实例,查找范围为当前组件内。(如果dom进行查找,当其他组件和当前组件有同一个类名时,并且其他组件在当前组件前面进行渲染,那么此时就会出现dom找到的标签元素为其他组件内的。)

  1. 获取dom,在目标标签上添加ref属性
  2. 适当时机,通过this.$refs.xxx,获取目标标签
<div ref="div_1">
	
</div>

this.$refs.div_1
// 获取上述这个div标签
<template>
  <div id="app">
      <div ref="div_1">哈哈</div>
  </div>
</template>
<script>

export default {
  name: 'App',
  data(){
    return{
      isShow:false
    }
  },
  methods:{
    fn(){
      this.isShow = true;
    }
  },
  mounted(){
    console.log(this.$refs.div_1);
  }
}
</script>
<style scoped>
</style>

运行结果:
在这里插入图片描述
如果要获取组件实例,直接在组件实例的标签上添加属性ref,之后就可以通过this.$refs.xxx获取这个组件,返回的是一个Vue组件对象,通过==this.$refs.xxx.组件方法()==调用这个组件下的方法。

6. Vue异步更新,$nextTick

下述是异步更新实例,因为Vue是异步更新的,所有点击编辑按钮之后,输入框并不会出现聚焦,所有需要使用到$nextTick

<template>
  <div id="app">
    <div v-if="isShow">
      <span>{{v}}</span>
      <button @click="edit">编辑</button>
    </div>
    <div v-else>
      <input type="text" v-model="v" ref="inp">
      <button @click="save">保存</button>
    </div>
  </div>
</template>
<script>

export default {
  name: 'App',
  data(){
    return{
      isShow:true,
      v:'北京'
    }
  },
  methods:{
    edit(){
      this.isShow = false;
      this.$nextTick(()=>{
        this.$refs.inp.focus();
      });
    },
    save(){
      this.isShow = true;
    }
  }
}
</script>
<style scoped>
  #app{
    width: 100px;
    height: 100px;
    margin: 20px auto;
  }
</style>

运行结果:
请添加图片描述

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

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

相关文章

谷粒商城实战笔记-42-前端基础-Vue-生命周期和钩子函数

下面是Vue官网关于生命周期及不同阶段的钩子函数的图示。 Vue 实例生命周期是指从一个组件被创建到最终被销毁的整个过程。 在这一过程中&#xff0c;Vue 提供了一系列的“钩子”函数&#xff0c;在生命周期的不同阶段执行自定义的代码。 以下是 Vue 对象生命周期的主要阶段…

C语言实现二叉树以及二叉树的详细介绍

目录 1.树概念及结构 1.1树的概念 1.2树的相关概念 1.3树的表示 2.二叉树概念及结构 2.1二叉树的概念 2.2特殊的二叉树 2.3二叉树的性质 2.4二叉树的存储结构 3.二叉树顺序结构--特殊的二叉树--堆及其实现 3.1堆的概念及结构 3.2堆的实现 3.2.1堆的结构 3.2.2堆…

filebeat生产环境配置

配置文件属性 生产配置 filebeat.inputs: - type: logenabled: truepaths: - /tmp/logs/*.log- /var/log/system.log- /var/log/wifi.logsymlinks: truejson.keys_under_root: truejson.message_key: xxxjson.add_error_key: true# 如果想卡部分日志&#xff0c;比如用时间作…

Monaco 使用 HoverProvider

Monaco 中自定义 Hover&#xff0c;Hover 效果是指当鼠标移动文字上展示出提示效果&#xff0c;就像页面上的 Tooltip 效果。最终页面的显示效果如下&#xff1a; 通过 registerHoverProvider 注册 Hover 触发时的处理方法 接口中提供了 4 个参数&#xff0c;前两个参数比较重…

python学习之闭包与装饰器

一、闭包 闭包允许一个函数访问并操作函数外部的变量&#xff08;即父级作用域中的变量&#xff09;&#xff0c;即使在该函数外部执行。 特性&#xff1a; (1)外部函数嵌套内部函数。 (2)外部函数可以返回内部函数。 (3)内部函数可以访问外部函数的局部变量。 def out()…

【jmeter边界值提取器】

【目的】 从响应头中取token的内容 【方案】 使用后置处理器-边界值提取器 【组件路径】HTTP请求->右键添加->后置处理器->边界提取器 用途&#xff1a;边界提取器(Boundary Extractor)是放在Sample请求之后执行的&#xff0c;用于获取左右边界中间的所有字符&#xf…

Windows配置Qt+VLC

文章目录 前言下载库文件提取文件编写qmakeqtvlc测试代码 总结 前言 在Windows平台上配置Qt和VLC是开发多媒体应用程序的一个重要步骤。Qt作为一个强大的跨平台应用开发框架&#xff0c;为开发人员提供了丰富的GUI工具和库&#xff0c;而VLC则是一个开源的多媒体播放器&#x…

基于STM32的农业大棚温湿度采集控制系统的设计

目录 1、设计要求 2、系统功能 3、演示视频和实物 4、系统设计框图 5、软件设计流程图 6、原理图 7、主程序 8、总结 &#x1f91e;大家好&#xff0c;这里是5132单片机毕设设计项目分享&#xff0c;今天给大家分享的是智能教室。 设备的详细功能见网盘中的文章《8、基…

451.根据字符出现频率排序(中等)

451.根据字符出现频率排序&#xff08;中等&#xff09; 1. 题目描述2.详细题解3.代码实现3.1 Python3.2 Java 1. 题目描述 题目中转&#xff1a;451.根据字符出现频率排序&#xff08;中等&#xff09; 2.详细题解 题目&#xff1a; 347. 前 K 个高频元素&#xff08;中等&am…

2月科研——arcgis计算植被差异

ArcGIS中&#xff0c;设置高于或低于某个值的像元为 -9999&#xff0c;然后将这些地方设为空——目的&#xff1a;去除异常值和黑色背景值 Con(("T_std ano7.tif" > 2) | ("T_std ano7.tif" < - 2), - 9999,"T_std ano7.tif") SetNull(&…

数学基础【俗说矩阵】:初等矩阵和矩阵的初等行变化关系推导

初等矩阵和矩阵的初等行变换 初等矩阵 矩阵的初等行变换 对单位阵E进行一次初等行变化得到的阵叫做初等阵。 这里只能进行一次初等行变换。 置换阵 给矩阵【左乘】一个【置换阵】&#xff0c;相当与对该矩阵进行了一次【置换阵】对应的【置换】初等行变换&#xff1b; 数…

爬取百度图片,想爬谁就爬谁

前言 既然是做爬虫&#xff0c;那么肯定就会有一些小心思&#xff0c;比如去获取一些自己喜欢的资料等。 去百度图片去抓取图片吧 打开百度图片网站&#xff0c;点击搜索xxx&#xff0c;打开后&#xff0c;滚动滚动条&#xff0c;发现滚动条越来越小&#xff0c;说明图片加载…

Wordpress文章分享到微信朋友圈不带图像问题的解决

目录 一、插件选择 二、插件安装 三、获取微信公众号管理信息 1、登录微信公众平台 2、配置“JS接口安全域名” 3、至安全中心设置“IP白名单” 4、获得“开发者ID(AppID)” 5、获得“开发者密码(AppSecret)” 四、配置插件 五、验证 WordPress装配好后&#xff0c;可…

10.11和10.8那个大(各种ai的回答)

问题&#xff1a;10.11和10.8两个数哪个大 腾讯混元 ✔️ chatGPT ❎ 通义千问 ❎ 文心一言 ✔️ 智谱清言 ❎ 讯飞星火 ✔️ C知道 ❎ 豆包 ✔️

matlab 声音信号希尔伯特黄变换

1、内容简介 略 91-可以交流、咨询、答疑 2、内容说明 略 Hilbert-Huang变换&#xff08;HHT&#xff09;是一种基于经验的数据分析方法 方法。它的扩展基础是自适应的&#xff0c;因此它可以从非线性和非平稳过程中产生具有物理意义的数据表示。这个 适应性的优势是有代价…

代码随想录第二天 | 数组 | 双指针法、滑动窗口、螺旋数组

来源 代码随想录数组第二天 有序数组的平方 数组其实是有序的&#xff0c; 只不过负数平方之后可能成为最大数了。 那么数组平方的最大值就在数组的两端&#xff0c;不是最左边就是最右边&#xff0c;不可能是中间。 此时可以考虑双指针法了&#xff0c;i指向起始位置&…

matlab永磁同步电机反馈试验装置的设计和永磁同步电机仿真

1、内容简介 略 85-可以交流、咨询、答疑 2、内容说明 略 摘要&#xff1a;得益于电力电子器件及控制技术的高速发展&#xff0c;使得电机的应用越来越方便及精确&#xff0c;适应了实际应用对电机性能及质量提出的更高要求和标准。同时电机测试技术也因为电力电子技术的发…

c++ primer plus 第16章string 类和标准模板库, 16.3.3 对矢量可执行的其他操作

c primer plus 第16章string 类和标准模板库, 16.3.3 对矢量可执行的其他操作 c primer plus 第16章string 类和标准模板库, 16.3.3 对矢量可执行的其他操作 文章目录 c primer plus 第16章string 类和标准模板库, 16.3.3 对矢量可执行的其他操作16.3.3 对矢量可执行的其他操作…

Idea中git如何进行回退操作

当你的代码已经提交并且推送到远程仓库了如何进行回退 1.首先找到你需要回退到的提交记录 假设你要回退到当前大营销模板位置&#xff0c;右键当前分支然后选中rest 点击后&#xff0c;若需要保留之前提交记录到本地则可以选择max或者soft 选择后进行回退操作&#xff0c;最后将…

全代码 | 随机森林在回归分析中的经典应用

公众号后台记录了发表过文章的各项阅读指标包括&#xff1a;内容标题&#xff0c;总阅读人数&#xff0c;总阅读次数&#xff0c;总分享人数&#xff0c;总分享次数&#xff0c;阅读后关注人数&#xff0c;送达阅读率&#xff0c;分享产生阅读次数&#xff0c;首次分享率&#…