Vue入门

Vue

1.Vue的两个特性

  • 数据驱动视图
    • 数据的变化会驱动视图自动更新
    • 好处:程序员只管把数据维护好,那么页面的结构会被vue自动渲染出来
  • 双向数据绑定
    • 在网页中,form表单负责采集数据,Ajax负责提交数据
    • js数据的变化,会被自动渲染到页面上
    • 页面上表单采集的数据发生变化时,会被vue自动获取到,并更新到js数据中

注意:数据驱动视图和双向绑定数据的底层实现原理时MVVM(model数据源,view视图,viewmodel就是vue的实例)

2.Vue指令

  • 内容渲染指令
    • v-text指令缺点:会覆盖元素内部原有的内容
    • {{ }}插值表达式:在实际开发中用的最多,只是内容上的占位,不会覆盖原有的内容
    • v-html指令的作用:可以把带有标签的字符串,渲染成真正的HTML内容
<body>
//希望Vue能够控制下面的这个div,帮我们把数据填充到div内部
<div id="app">
<p v-text="username"></p>
<p v-text="gender">性别</p>//会覆盖元素内部原有内容

<hr>

//插值表达式的使用
<p>姓名:{{username}}</p>
<p>性别:{{gender}}</p>

<hr>

<div v-html="info"></div>

</div>

1.导入Vue的库文件,这样在window全局就有了Vue这个构造函数
<script src="./lib/vue.js"></script>

2.创建Vue实例对象
const vm = new Vue({
	//el属性固定的写法,表示当前vm实例要控制页面上的哪个区域,接收的值是一个选择器
	el:'#app',
	//data对象就是要渲染到页面上的数据
	data:{
		username:'zhangsan',
		gender:'女',
		info:'<h4 style="color:red;font-weight:bold;">欢迎</h4>'
	}
})
</script>
<body>
  • 属性绑定指令

注意:插值表达式只能用在元素的内容节点中,不能用在元素的属性节点中

  • 在vue中,可以使用v-bind:指令,为元素的属性动态绑定值,v-bind vue规定v-bind: 指令可以简写为:
<body>
//希望Vue能够控制下面的这个div,帮我们把数据填充到div内部
<div id="app">
<input type="text" :placeholder="tips">
<img v-bind:src="img" alt="图片不能打开的说明文字" style="width: 150px;">

</div>

1.导入Vue的库文件,这样在window全局就有了Vue这个构造函数
<script src="./lib/vue.js"></script>

2.创建Vue实例对象
const vm = new Vue({
	//el属性固定的写法,表示当前vm实例要控制页面上的哪个区域,接收的值是一个选择器
	el:'#app',
	//data对象就是要渲染到页面上的数据
	data:{
		tips:'请输入用户名',
		img:'http://images/logo.svg'
	}
})
</script>
<body>
  • 事件绑定指令
    • v-on可以简写为@
    • 绑定事件的时候可以通过 ()进行传参
<button v-on:click="add(1)">+1</button>	
<button v-on:click="sub">-1</button>	
methods:{
	add(n){
		this.count += n
	},
	sub(){
		this.count -= 1
	}
}
//不传参也会有事件e
<button v-on:click="add">+1</button>
add(e){
	e.target = "button";
}
//此时e不是事件,而是1
<button v-on:click="add(1)">+1</button>
add(e){
	e.target = "button";
}
//参数和事件一起接收
<button v-on:click="add(1,$event)">+1</button>
add(n,e){
	e.target = "button";
}
  • 事件修饰符
//.prevent阻止默认行为,例如阻止a链接的跳转、阻止表单的提交
<a href= "http://www.baidu.com" @click.prevent="show">跳转到百度首页</a>
methods:{
	show() {
		console.log("点击了按钮,但是没有跳转百度首页")
	}
}
//阻止表单默认提交刷新,但是add方法还是正常执行的
<form @click.prevent="add">
</form>

//.stop阻止事件冒泡,阻止了外层的点击
<div @click="divclick">
<button @click.stop="btnclick"></button>
</div>
methods:{
	divclick(){
		console.log("点击了"divclick")
	},
	btnclick(){
		console.log("点击了"btnclick")
	}
}
  • 按键修饰符
//esc清空内容,enter提交内容
<input type="text" @keyup.esc="clearInput" @keyup.enter="commit">

methods: {
	clearInput(e){
		e.target.value = ''
	},
	commit(){
		console.log("点击了enter按键")
	}
}
  • v-model(双向绑定)
    • input输入框
      • type=“radio”
      • type=“checkbox”
      • type=“xxx”
    • textarea
    • select
为了方便对用户输入的内容进行处理,vue为v-model指令提供了三个修饰符
.number 自动将用户输入的值转换为数值类型 <input v-model.number="age">
.trim 自动过滤用户输入的首尾空白字符 <input v-model.trim="msg">
.lazy 在"change"时而非"input"时更新
  • 条件渲染指令
    • v-show原理:动态为元素添加和移除display:none样式,来实现元素的显示和隐藏
      • 如果频繁的切换元素的显示状态,用v-show性能会更好
    • v-if原理:每次动态创建和移除元素,实现元素的显示和隐藏
      • 如果刚进入页面的时候,某些元素默认不被展示,而且后期很肯能也不需要被展示,此时的v-if性能更好

实际开发中,使用v-if

  • 列表渲染指令

    • v-for用法 v-for=“(item,index) in list” :key=“item.id”
  • label的for属性:放大可操作区域

3.过滤器

//私有过滤器语法结构
<div id="app">
<p>message的值是{{ message | capi }}<p>
</div>

<script>
//过滤器函数与data同级,必须被定义到filters节点下
//过滤器本质是函数
data: {
el: "#app",
message: 'hello vue'
},
filters: {
	//val是管道符|前面的值
	capi(val){
		//强调:过滤器中,一定要有一个返回值
		return 'abc' 	
	}
}
</script>

//全局过滤器语法结构
<script>
Vue.filter('capi',function(str){
	const first = chartAt(0).toUpperCase
	const other = str.slice(1)
	return first + other
})
</script>

  • 过滤器的注意点
    • 要定义到filters节点下,本质是一个函数
    • 在过滤器的函数中,一定要有return值
    • 在过滤器的形参中,可以获取到管道符前面待处理那个值
    • 如果全局过滤器和私有过滤器名字一样,此时按照就近原则,调用私有过滤器
    • 过滤器可以串联的使用,第一个过滤的return值作为第二个过滤器的形参(开发很少使用过滤器串联)
    • 可以给过滤器传参 ,参数从第二个位置接收
    • Vue3.x不支持过滤器
<p>{{ message | filterA(arg1,arg2) }}</p>
<script>
	Vue.filter('filterA',(msg,arg1,arg2){
		return xxx
	})
</script>

4.监听器

//与data同级
data:{
	username:''
},
//新值在前,旧
watch:{
	//对象格式侦听器
	username(){
		handler(newVal, oldVal){
			conslole.log(newVal,oldVal)
		},
		immediate: true //默认为false,当设置为true时,控制侦听器自动触发一次
        
	}
	//方法格式侦听器,不能控制侦听器进入界面自动触发一次
	username(newVal, oldVal){
		conslole.log(newVal,oldVal)
	}
}
  • 如果监听对象,可以使用deep选项,监视对象里面的属性变化,也可以使用对象.属性的方式进行监听
watch: {
	info: {
		handler(newVal){
			console.log(newVal)
		},
		//开启深度监听,只要对象中的任何一个属性变化了,都会触发对象的侦听器
		deep: true
	}
	'info.username'(newVal) {
		console.log(newVal)
	}
}

5.使用计算属性computed

  • 定义的时候,要被定义为方法
  • 在使用计算属性的时候,当成普通的属性使用即可
  • 实现了代码复用,只要计算属性中依赖的数据源变化了,则计算属性会自动重新求值
//计算属性在定义的时候,要定义成方法格式
computed: {
	//rgb作为一个计算属性,被定义成了方法格式
	//最终,在这个方法中,要返回一个生成好的rgb(x,x,x)的字符串
	rgb() {
		return `rgb(${this.r},${this.g},${this.b})`
	}
}

6.axios

  • axios是一个专注于网络请求的库
//axios基本用法
<script src="./lib/axios.js"></script>
<script>

//1.用axios方法得到的返回值是Promise对象
axios({
	method: 'GET',
	url: 'http://www.baidu/3306/api/getbooks'
}).then(function(result)){
	console.log(result.data)
}

</script>
  • axios发起get请求
<script src="./lib/axios.js"></script>
<script>

//1.用axios方法得到的返回值是Promise对象
axios({
	method: 'GET',
	url: 'http://www.baidu/3306/api/getbooks',
	params: {
		id: 1
	}
	
}).then(function(result)){
	console.log(result.data)
}
</script>
  • axios发起post请求
<button id = "btnPost">发起POST请求</button>
<script src="./lib/axios.js"></script>
<script>

document.querySelector('#btnPost').addEventListener('click',function()) {
axios({
	method: 'POST',
	url: 'http://www.baidu/3306/api/post',
	data: {
		name: 'zs',
		age: 20
	}
	
    }).then(function(result)){
        console.log(result	)
   }
}

</script>
  • async和await调用axiso
//如果调用某个方法的返回值是Promise实例,则前面可以添加await
//await只能用在被async修饰的方法中
<script>

document.querySelector('#btnPost').addEventListener('click',async function()) {
const result = await axios({
	method: 'POST',
	url: 'http://www.baidu/3306/api/post',
	data: {
		name: 'zs',
		age: 20
		}	
    })
    console.log(result)
}

</script>
  • 使用解构赋值
<script>
//解构赋值的时候,使用:进行重命名
//1.调用axiso之后,可以使用await和async进行简化
//2.使用解构赋值,从axiso封装的大对象中,把data属性解构出来
//3.把解构出来的data属性,使用冒号进行重命名,一般重命名为{ data: res}
document.querySelector('#btnGet').addEventListener('click',async function()) {
const {data: res} = await axios({
	method: 'Get',
	url: 'http://www.baidu/3306/api/getBooks'
	
	})
	console.log(res.data)
</script>
  • 可以使用axios.get()和axiso.post()

7.vue.cli的使用

  • 创建项目命令
vue create 项目名称(不要有中文)
  • src目录构成
asserts文件夹:存放项目中用到的静态资源文件,例如css样式表、图片资源
components文件夹:程序员封装的、可复用的组件,都要放到components目录下
main.js是项目的入口文件。整个项目的运行,首先要执行main.js
APP.vue是项目的根组件
  • vue项目的执行流程

在工程化的项目中,vue要做的事情很单纯:通过main.js把App.vue渲染到index.html的指定区域中

new Vue({
  store,
  render: h => h(App)
}).$mount('#app')
.$mount('#app')的作用等同于el: '#app'

8.组件的三个组成部分

<template>
<div class="test-box">
    <h3>这是自定义的Test.vue---{{username}}</h3>
</div>
</template>
<script>
//默认导出,固定写法
export default{
    //data数据源
    //注意.vue中组件中的data必须是一个函数
    data() {
        return{
            username: 'admin'
            
        }
    }
}
</script>
<style>

9.在组件中定义methods方法

<template>
<div class="test-box">
    <h3>这是自定义的Test.vue---{{username}}</h3>
    <button @click="changeUsername">修改用户名</button>
</div>
</template>
<script>
//默认导出,固定写法
export default{
    //data数据源
    //注意.vue中组件中的data必须是一个函数
    data() {
        return{
            username: 'admin'
            
        }
    },
    methods: {
        changeUsername() {
            this.username = '哇哈哈'
        } 
    },
    //当前组件的侦听器
    watch: {

    },
    //当前组件的计算属性
    computed: {

    },
    //当前组件的过滤器
    filters: {

    }

}
</script>
<style>
.test-box {
    background-color: pink;
}
</style>
  • 只能有一个根节点
<template>
	<div>
	
	</div>
</template>
  • 启用less
//<style默认lang是css>
<style lang="less">
.test-box {
    background-color: pink;
    h3{
        color: red;
    }
}
</style>

10.组件的使用

  • 步骤1:使用import语法导入需要的组件
  • 步骤2:使用components节点注册组件(使用component注册的是私有子组件)
  • 步骤3:以标签形式使用刚才注册的组件

11.全局组件的使用

  • 在main.js中导入需要被全局使用的组件
import Count from '@/components/Count.vue'
  • 使用Vue.component()函数进行全局注册
Vue.component('MyCount',Count)

12.组件的props

  • props是组件的自定义属性,在封装通用组件的时候,合理的使用props可以提高组件的复用性
export default{
	//组件的自定义属性
	props: ['自定义属性A','自定义属性B','init'],
	//组件的私有属性
	data() {
		return{
		
		}
	}

}
//在不同的父组件中可以给子组件自定义属性赋不同的值
<MyCount init="6"></Mycount>
<MyCount init="9"></Mycount>
//注意,此时的6和9是字符串,如过要赋数字,需要加v-bind绑定
<MyCount :init="6"></Mycount>
<MyCount :init="9"></Mycount>
  • props是可读了,对props中自定义的属性进行修改,vue会报警告,如果要修改props中的值,可以把props的值转存到data中
//父组件给init一个初值
<MyCount :init="6"></Mycount>
export default{
	//组件的自定义属性
	props: ['init'],
	//组件的私有属性
	data() {
		return{
		count: this.init
		}
	}
}
  • props-default、type、required属性
数组方式不能定义props属性的初始值,需要转换为对象形式
props: {
	init: {
		default: 0,
		//父组件传的init类型必须是Number数字
		type: Number,
		//必填项
		required: true
	}
}

13.scoped使用及底层原理

//方式组件的样式冲突问题
<style scoped lang="less">
.footer {
	padding:30rpx 20rpx;
	box-sizing:border-box;
	background:#fff;
	width:100%;
}
</style>
  • 底层原理

在UI的标签中会生成data-v-xxx的标识,目的是当前界面的样式只能标识当前界面的UI

14./deep/

  • 使用/deep/在父组件中修改子组件中的样式
  • 使用场景:当使用第三方组件库的时候,如果有修改第三方组件默认样式,需要用到/deep/
/deep/ h5{
	...
}

15.生命周期

  • 组件创建阶段
beforeCreated(){
//开发用不到
},
created(){
//生命周期函数,非常常用
//经常在它里面,调用methonds方法,请求服务器的数据
//并且,把请求到的数据,转存到data中,供template模板渲染的时候使用
this.initBooks()
},
beforeMounted(){
//开发用不到
},
mounted(){
//如果要操作当前组件的dom,最早只能在mounted阶段执行
const dom = document.querySelector('#myh3')
console.log(dom)
},

  • 组件更新阶段
beforeUpdate(){

},
updated(){
	//当数据发生变化时,为了能操作到最新的DOM结构,必须把代码写到updated生命周期函数中	
}

16.组件传值

  • 父组件像子组件共享数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R3mOgy8j-1669866387367)(C:\Users\YunFa\AppData\Roaming\Typora\typora-user-images\image-20221201103934826.png)]

  • 子组件像父组件共享数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hKQ1qcsb-1669866387368)(C:\Users\YunFa\AppData\Roaming\Typora\typora-user-images\image-20221201111829593.png)]

  • 组件之间的共享
    • 创建eventBus.js模块,并向外共享一个Vue的实例对象
    • 在数据发送方,调用bus.$emit(‘事件名称’,要发送的数据)方法触发自定义事件
    • 在数据接收方,调用bus.$on(‘事件名称’,事件处理函数)方法注册一个自定义事件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ncdQBVej-1669866387368)(C:\Users\YunFa\AppData\Roaming\Typora\typora-user-images\image-20221201112807473.png)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值