第一章—Vue核心01
文章目录
是什么
构建用户界面的渐进式JS框架,Vue可以自底向上构建应用
特点
- 组件化模式
- 声明式编码,无需直接操作DOM
- 虚拟DOM+DIFF算法,复用性强
搭建环境
- 引入本地vue.js
- 下载开发者工具
- 浏览器安装
- 关闭提醒,使用vue.config全局配置
<body>
<script type="text/javascript"> Vue.config.productionTip = false //阻止vue在启动时生成生产提示 </script>
</body>
Hello
- 准备一个容器div,就是vue模板
- 创建Vue实例。容器变化的值放在实例中,动态变化
- 在容器中使用插值,实例中data对象添加变量
<!--容器-->
<div id="hello">
<p>hello,{
{name}}</p>
</div>
<script type="text/javascript"> Vue.config.productionTip = false //阻止vue在启动时生成生产提示 // 实例 new Vue({
el: '#hello', // 指定实例为哪个容器服务 data: {
//data存储数据,供指定容器使用 name: 'lili' } }); </script>
一个容器只能被一个实例对应
{
{xxx}}xxx中要写js表达式,xxx可以自动获取data中得所有属性
区分js表达式和js代码
- 表达式:一个表达式会生成一个值,可以放在任何一个需要值得地方
- a
- a+b
- demo(1)
- 三元表达式
- js代码
- if(){}
- for(){}
模板语法
v-bind:动态绑定,简写为:
<div id="hello">
<p>hello,{
{name}}</p>
<a v-bind:href="url">百度</a>
</div>
- 插值语法:
- 解析标签体语法
- {
{}},可以读取到data所有属性
- 指令语法
- 解析标签(属性,标签体内容,绑定事件)
多级绑定
<!--容器-->
<div id="hello">
<p>hello,{
{name}}</p>
<a v-bind:href="url">百度</a>
<p>hello,{
{school.name.toUpperCase()}}</p>
</div>
<script type="text/javascript"> Vue.config.productionTip = false //阻止vue在启动时生成生产提示 // 实例 new Vue({
el: '#hello', // 指定实例为哪个容器服务 data: {
//data存储数据,供指定容器使用 name: 'lili', url: 'https://www.baidu.com/', school: {
name: 'iii' } } }); </script>
数据绑定
页面中的值和data中的值
单向:数据只能从data流向页面
<div id="hello">
单向数据绑定:<input type="text" v-bind:value="name">
双向数据绑定:<input type="text" v-model:value="name">
</div>
- v-model一般应用在表单类元素(输入类元素)
- v-model:value可以简写为v-model,v-model默认收集value值
简写
单向数据绑定:<input type="text" :value="name">
双向数据绑定:<input type="text" v-model="name">
el和data的两种写法
const vue = new Vue({
// el: '#hello', // 指定实例为哪个容器服务
data: {
//data存储数据,供指定容器使用
name: 'lili'
}
});
vue.$mount('#hello') // 挂载
// 实例
const vue = new Vue({
el: '#hello', // 指定实例为哪个容器服务
// 1. 对象式
/*data: { //data存储数据,供指定容器使用 name: 'lili' }*/
// 2.函数式,组件必须使用这种方式
// data:function (){
data(){
return{
name: 'aaa'
}
}
});
Vue管理的函数,不要写箭头函数,写了箭头函数,this就不是vue的实例
MVVM
M:模型,data中的数据
V:视图,模板
VM:视图模型,Vue实例对象
vm作为变量表示vue实例
- data中所有属性,最后都出现在vm上
- vm身上所有的属性及vue原型上所有的属性,在vue模板中都可以直接使用
数据代理
Object.DefineProperty
let number = 12
let person={
name: '张三',
}
Object.defineProperty(person,'age',{
// value:12,
// enumerable: true,// 设置属性可以枚举
// writable: true,// 设置属性可以修改
// configurable: true,// 设置属性可以被删除
// 有人读取person属性的age属性式,get函数就会被调用,返回age的值
get:function (){
return 'hello'
},
set(value){
number = value
}
})
console.log(person)
数据代理:通过一个对象代理另一个对象中属性的操作(读/写)
vm._data=options.data=data
<p>hello,{
{
_data.name}}</p>
<p>hello,{
{
address}}</p>
// 实例
let data={
//data存储数据,供指定容器使用
name: 'lili',
address: 'beibei'
}
const vm = new Vue({
el: '#hello', // 指定实例为哪个容器服务
data
});
- 通过vm对象来代理data对象中属性的操作
- 原理
- 通过Object.DefineProperty把data对象中所有竖向添加到vm上
- 为每一个属性,都指定一个getter和setter,在内部去操作data中对应的属性
事件处理
箭头函数,没有自己的实例,window实例
所有被vue管理的方法不要
- 使用v-on或者@绑定事件
- 事件的回调需要配置在methods对象中,最终会在vm上
- methods中配置的函数,不要用箭头函数,否则this不是vm
- methods中配置的函数,都是被Vue管理的函数,this的指向是vm(或组件实例对象)
<!--容器-->
<div id="hello">
<p>hello,{
{_data.name}}</p>
<p>hello,{
{address}}</p>
<button v-on:click="showInfo">点点点</button>
<button @click="showInfo($event)">点点</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false //阻止vue在启动时生成生产提示
// 实例
let data={ //data存储数据,供指定容器使用
name: 'lili',
address: 'beibei'
}
const vm = new Vue({
el: '#hello', // 指定实例为哪个容器服务
data,
methods: {
showInfo(event){
console.log(event.target)
alert("eee")
}
}
});
事件修饰符
- prevent:阻止默认事件
- stop:阻止事件冒泡
- once:事件触发一次
- capture:使用事件的捕获模式
- self:只有event.target是当前操作的元素是才触发事件
- passive:事件的默认行为立即执行,无需等待事件回调执行完毕
<a href="https://www.baidu.com" @click.prevent= "showInfo">点我</a>
<button @click.once="showInfo($event)">点点</button>
键盘事件
- Vue常见的按键别名:enter,delete,esc,space(空格),tab,up,down,left,right
- 未提供别名的按键,可以使用按键原始key值绑定,转为kebab-case短横线命名
- 系统修饰键:ctrl,alt,shift,meta
- 配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发
- 配合keydown,正常触发事件
- Vue.config.keyCodes.自定义键名 = 键码
计算属性
// 实例
let data={
//data存储数据,供指定容器使用
name: 'lili',
address: 'beibei',
firstName: '张',
lastName: '三'
}
const vm = new Vue({
el: '#hello', // 指定实例为哪个容器服务
data,
methods: {
showInfo(event){
console.log(event.key+" "+event.keyCode)
},
fullName(){
return this.firstName+this.lastName;
}
}
});
每次数据值变化时,模板中的方法都会重新变化,资源消耗较大
// 实例
let data={
//data存储数据,供指定容器使用
name: 'lili',
address: 'beibei',
firstName: '张',
lastName: '三'
}
const vm = new Vue({
el: '#hello', // 指定实例为哪个容器服务
data,
methods: {
showInfo(event){
console.log(event.key+" "+event.keyCode)
},
// fullName(){
// return this.firstName+this.lastName;
// }
},
computed:{
fullName: {
// 当读取fullName,get被调用,返回值作为fullName的值
// get有缓存机制
// get调用时间?1.初次读取时 2.锁依赖的数据发生变化时
get(){
return this.firstName+this.fullName;
}
}
}
});
- 定义:要用的属性不存在,通过已有属性计算得到
- 原理:底层借助了Object.defineProperty方法提供的getter和setter
- 内部有缓存机制,效率高,调试方便
- 计算属性最终会出现在vm上,直接读取使用
- 计算属性修改使用set方法
// 简写
fullName(){
return this.firstName+this.lastName;}
<p>今天天气很{
{
info}}</p>
<button @click="changeWeather">改变天气</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false //阻止vue在启动时生成生产提示
// 实例
new Vue({
el: '#hello', // 指定实例为哪个容器服务
data: {
//data存储数据,供指定容器使用
name: 'lili',
url: 'https://www.baidu.com/',
school: {
name: 'iii'
},
isHot: true,
},
computed:{
info(){
return this.isHot?'炎热':'凉爽';
}
},
methods:{
changeWeather(){
this.isHot = !this.isHot;
}
}
});
监视属性
watch:{
isHot:{
immediate:true, //初始化时让handler调用
// isHot改变时
handler(newValue,oldValue){
console.log(newValue,oldValue)
}
}
}
});
vm.$watch('isHot',{
handler(newValue,oldValue){
console.log(newValue,oldValue)
}
})
- 当被监视的属性发生变化时,回调函数自动调用,进行相关操作
- 监视的属性必须存在,才能进行监视
- 监视的两种写法
- new Value时传入watch配置
- 通过vm.$watch监视
深度监视
- Vue中的watch默认不监视对象内部值的改变(一层)
- 配置deep:true可以监测对象内部值的改变(多层)
- Vue自身可以监测对象内部值的改变,Vue提供的watch默认不可以
- 使用watch时根据数据的具体结构,决定是否采用深度监视
<p>a的值是:{
{numbers.a}}</p>
<p>b的值是:{
{numbers.b}}</p>
<button @click="numbers.a++">点我a+1</button>
<button @click="numbers.b++">点我b+1</button>
'numbers.a': {
handler(newValue, oldValue) {
console.log('a值发生改变')
}
}
// 简写
'numbers.a'(){
console.log("a的值发生改变")
}
numbers: {
deep:true,
handler(newValue, oldValue) {
console.log('值发生改变')
}
}
计算属性和监视属性的区别
// 实例
let data={
//data存储数据,供指定容器使用
name: 'lili',
address: 'beibei',
firstName: '张',
lastName: '三',
fullName: '张三'
}
const vm = new Vue({
el: '#hello', // 指定实例为哪个容器服务
data,
methods: {
showInfo(event){
console.log(event.key+" "+event.keyCode)
},
},
computed:{
// 简写
/*fullName(){ return this.firstName+this.lastName; }*/
},
watch:{
firstName(val) {
this.fullName = val + this.lastName;
},
lastName(val){
this.fullName = this.firstName+val;
}
}
});
- computed能完成的功能,watch也可以实现
- watch能实现的功能,computed不一定能够实现。watch可以进行异步操作
- 所有被vue管理的函数,最好写成普通函数,this的指向才会是vm或式组件实例对象
- 所有不被vue管理的函数(定时器的回调函数,ajax的回调函数等),最好写成箭头安徽念书,这样this的指向才是vm或者组件实例对象
绑定class样式
<!--容器-->
<div id="hello">
<div :class="mood" @click="change">{
{
name}}</div>
</div>
<script type="text/javascript">
Vue.config.productionTip = false //阻止vue在启动时生成生产提示
// 实例
const vue = new Vue({
el: '#hello', // 指定实例为哪个容器服务
data(){
return{
name: 'aaa',
mood: 'basic'
}
},
methods:{
change(){
this.mood = 'a'
}
}
});
条件渲染
v-show
<!--容器-->
<div id="hello">
<div :class="mood" @click="change">{
{name}}</div>
<p v-show="mood === 'basic'">欢迎</p>
</div>
<script type="text/javascript">
Vue.config.productionTip = false //阻止vue在启动时生成生产提示
// 实例
const vue = new Vue({
el: '#hello', // 指定实例为哪个容器服务
data(){
return{
name: 'aaa',
mood: 'basic',
show: true
}
},
methods:{
change(){
/*if(this.mood === 'a'){
this.mood = 'basic';
}else{
this.mood = 'a'
}*/
this.mood = this.mood === 'a'?'basic':'a'
}
},
watch:{
}
});
使用频率高使用v-show,低使用v-if(DOM节点的删除添加)
v-if
<p v-show="mood === 'basic'">欢迎show</p>
<p v-if="mood === 'basic'">欢迎if</p>
<p v-else-if="mood === 'a'">欢迎ifa</p>
<p v-else="mood === 'b'">欢迎ifa</p>
alt可以选择多行
template和v-if配合使用
使用v-if的时候,元素可能无法获取到,使用v-show一定可以获取到
文章评论