【无标题】


title: Vue基础教程
date: 2022-01-26 21:09:30
tags: [前端框架,Vue]
categories: 前 端
cover:


Vue基础入门

基础知识:

  1. HTML+JavaScript+CSS
  2. Node环境和npm(依赖管理 )
  3. webpack(可选)

官方文档:

  1. 学习任何框架,最好的教程就是官方文档,但是官方文档往往是英文的,可能会劝退:( 建议提升英文:)
  2. 初学者更适合视频学习,等有一定能力便可以向文档进发,因为更加详细:)

DOM是什么?

Document Object Model,简称DOM,中文叫做“文档对象模型

粗略理解就是:

DOM提供了对文档的结构化表述。从HTML或者xml程序中,对其结构进行访问,以及修改文档的结构、样式和内容,也就是可以对文档结构实现读写功能。(web页面与其源码都被称作是文档)

DOM 的实现

要想实现将js代码中的数据呈现到HTML页面上用DOM实现:

要先获取document/DOM,再获取节点,然后再去操作这个DOM节点(也就是在HTML中进行一系列的操作)。而使用Vue可以直接在html程序中绑定数据,当我们改变js中的数据时,就可以直接在页面上呈现出来

Vue相比于DOM的优点

要想实现将js代码中的数据呈现到HTML页面上,采用Vue可以让这个过程简化许多。

先创建Vue实例:

//创建VUE实例
new Vue({
	el:"#app",	//选择器
	data:{
		message:"我喜欢你"
}
})

然后将此实例和HTML中的

绑定到一起

<div id="app">
    <h1>{{meaasge}}</h1>	<!-- 双花括号是表达式的意思 -->
</div>

所以,以后我们要在HTML里面用js的数据,就直接写相应的数据名称就可以了,让数据和页面形成一个绑定,我们只要操作数据,页面自己就会跟着变化。

入门知识点

  1. 文本:双花括号

  2. 属性:v-bind:

    可省略,只写冒号:

  3. 事件:v-on:

    可省略,只写@

    注:如果要在函数里面使用Vue中的数据,可以使用this来访问

举例:

<div id="app">
    <h1>message</h1>
	<img v-bind:src="url"></img>	
	<img :src="url"></img>	
	<button v-on:click=""></button>
	<button @click=""></button>
</div>



<script>
new Vue({
    el:"#app",	<!-- el为元素选择器的意思-->
    data:{
        message="我喜欢你",
    	url="inmages/1.jpg"
    },
    methods:{
        sayLoveYou(){
            alert("Love you!")
        }
        
        //Vue里的函数集合:methods,包含多个函数

				//数据集合:data,包含多个变量数据
    }
})
</script>

小练习:做一个翻页按钮

<body>
    <div id="app">
        <button @click="sub">-</button>
        <span>{{ number }}</span>
        <button @click="add">+</button>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>

    <script>
        new Vue({
            el:"#app",
            data:{
                number:0,
            },
            methods: {
                add(){
                    this.number=this.number+1;
                },
                sub(){
                    if(this.number==0){
                        alert("不可以小于零")
                    }
                
                    else
                        this.number--
                }
            }
        })

    </script>
</body>
</html>

效果:

【无标题】

创建Vue项目

配置开发环境

使用Node.js环境开发,

  1. cmd安装vue/cli
  2. 创建项目hello,建议在对应的目录下创建
  3. 启动服务器
命令:
npm install -g @vue/cli
vue create hello
cd hello
npm run serve

组件化开发概述

什么是组件化呢?

就是我们在html中进经常要用到标签,但是总有我们需要的标签HTML提供不了,所以,组件化开发就是,我们开发的.vue文件(又叫vue组件)作为html中的标签来使用。

例如我们可以开发.vue登录组件或者.vue轮播图组件然后插入到HTML中

优点:简洁与复用

项目结构概述

【无标题】

  1. 后缀.vue是我们上文中提到的组件,
  2. main.js是主文件,用于对应id与对应的组件(App.vue)
  3. components意为组件,一般我们自己开发的,也就是自定义的组件就放在这个目录下

剩余的一些为配置文件,

在这个vue中,我们可以写html、JavaScript、CSS代码,分别对应的是、、

例如:

<template>
<!-- html代码 -->
  <div id="app">
    <h1>I lOVE You</h1>
    <img alt="Vue logo" src="./assets/friend_404.gif">
    <h1>{{message}}</h1>
  
  </div>
</template>

<script>
// js代码、vue代码
export default {  //首先,VUE中的js一定要用export来暴露自己
//其次在以vue为后缀的文件中vue表达数据的书写方式跟在以html为后缀的文件中vue的写法不一样
  data(){
    return{
      message: "Hello world",
    }
  }
    
}
</script>

<style>
/* css代码 */
</style>

引入vue.js文件与Node环境下书写格式的区别

  1. 引入vue.js:

    data:{
    	message:"我喜欢你!"
    }
    
  2. Node环境下:

      data(){
        return{
          message: "Hello world",
        }
    }
    

模板语法

指令

v-开头的

【无标题】

条件判断类:

  1. v-if
  2. v-show

v-if与v-show的异同点:

  • 同:

    都可以隐藏或者显示元素(true:显示、false:不显示)

  • 异:

    if不渲染DOM,如果if为false,在浏览器中不显示

    show渲染DOM,如果show都为false,在浏览器中将元素设置为display:one

显示列表与制表类:

v-for

这个for啊,极有可能是遍历,循环的意思

利用v-for指令显示列表
<template>
<!-- html代码 -->
  <div id="app"> 
    <ul>
        <li v-for="(fruit,index) of fruits" :key="index">
          <p>水果名称:{{fruit}}</p> 
          <p>水果序号:{{index}}</p> 
          <p>水果名称和序号:{{fruit}}序号为{{index}}</p>
        </li>
    </ul>
  </div>
</template>

<script>
// js代码、vue代码
export default {  //首先,VUE中的js一定要用export来暴露自己
//其次在vue中的js代码中的书写方式跟在html中的vue的写法不一样
  data(){
    return{
      fruits:["苹果","芒果","香蕉","原梦"]
    }
  }
}
</script>

显示结果:

【无标题】

可以看出就像是一个遍历呢,

一长串如何记住呢?

v-for="(fruit,index) of fruits" :key="index"

元素索引属于集合,key的值为索引,然后将这个元素放在{{}}中
利用v-for制表
<template>
<!-- html代码 -->
  <div>
      
  <table>
    <!-- 将studens显示在表格里 -->
    <thead>
        <th>序号</th>
        <th>姓名</th>
        <th>年龄</th>
    </thead>
    <tbody>
        <!-- <tr>{{v.n}}</tr> -->
        <tr v-for="(v,i) of students" :key="i">
            <td>{{i + 1}}</td>
            <td>{{v.name }}</td>
            <td>{{v.age}}</td>
        </tr>
        <!-- <tr v-for="(v,i) of students" :key="i">{{v.age}}</tr> -->
    </tbody>
  </table>

  </div>
</template>

<script>
// js代码、vue代码

export default {  //首先,VUE中的js一定要用export来暴露自己
                  //其次在vue中的js代码中的书写方式跟在html中的vue的写法不一样
  components:{Hello,MenuList},
  data(){
    return{
      students:[
        {name:"张三 ",age:13},
        {name:"罗翔 ",age:12},
        {name:"John ",age:18}
        ]
    }
  }
  
}
</script>

<style>
/* css代码 */
</style>

演示效果:

【无标题】

组件嵌套

组件A想要用组件B 的功能,然后需要把组件B嵌套在A中。

三步走:命名、注册、传值

组件命名

B组件命名要首字母大写(小写可能会很HTML标签冲突,不建议这样写),大驼峰式,后缀.vue

注册组件

在B组件中暴露自己,在A组件中引入B组件

import B from "./components/B.vue";

在A中注册组件B,需要在A中写

components:{
	B:B
}

最后就是将B组价作为A组件的标签,放入A中:

<B>
</B>

组件传值

父子级的概念是,A组件如果包含B组件标签,则称A是B 的父级。

父级向子级传递数据

格式是属性传递(所以用双花括号来表达数据,用:来绑定标签)

首先需要在父级中单向引入子级

然后需要在子级中加入props属性

props是个字符串数组,里面的值为父级传过来的属性名

App.vue为父级
Child.vue为子级

<template>
<!-- html代码 -->
  <div>
    <h1>I lOVE You</h1>
    <Child :msg="message"></Child>
    <Child :mag="message1"></Child>
  </div>
</template>

<script>

import Child from "./components/Child.vue"
export default {

  components:{Child},

    data(){
        return{
            message:"这里是Vue的数据,我要传到Child组件中,也就是父传子",
            message1:"我是Vue的二号数据"
        }
    }

}
</script>

<style>
/* css代码 */
</style>
<!--==============上面为App.vue=================下面为Child.vue====================-->

<template>
<div>
    <h1>{{msg}} {{mag}}</h1>

</div>
</template>

<script>
export default {
    props: ["msg","mag"],   //props是一个数组的字符串,值为传过来的属性名msg
    data(){
        return{
            
        }
    }
}
</script>

效果图:

【无标题】

子级向父级传递数据

格式是事件传递(@来绑定标签)

比如说我现在想写一个功能,一个子级的按钮button,点击它的时候,把子级的数据传递给父级,然后父级的数据变成子级的一个数据。

先在父级中定义一个自定义事件,然后在子级定义一个按钮,然后绑定点击按钮(@click)发生的方法,在子级中定义这个方法,然后在这个方法中调用方法

this.$emit("toParent", this.msg);

其中

//$emit方法可以触发父级(App.vue)的自定义事件,也就是进行了绑定,向自定义事件toParent传递数据 
//$emit方法需要两个参数,1、要绑定的父级中的自定义事件,2、所要传递是数据
//可以这样理解,因为我在App中的Child标签中自定义了事件toParent
//然后我又在Child中的调用了方法this.$emit,所以App就通过Chlid联系起来了

然后,分别在子级,父级中定义变量,用来存放数据(一般都充当容器的作用),子级的变量用来存放要给父级传递的数据,父级的变量用来接收子级传来的数据。

<template>
  <div>
    <div>我是父组件</div>
    <div>我即将接收第二组件传值是:{{child2Msg}}</div>
    <div>
      <div>
        <Child @toParent="getMag" />
      </div>
    </div>
  </div>
</template>

<script>
import Child from "./components/Child.vue";

export default {
  components: {
    Child

},
  data() {
    return {
      child2Msg: ""
    };
  },
  methods: {
    getMag(msg) {
      this.child2Msg = msg;
    }
  }
};
</script>

<!--==============上面为App.vue=================下面为Child.vue====================-->

<template>
  <div>
    <div>我是第二个子组件</div>
    <div>我要发送给父组件的值:{{msg}}</div>
    <button @click="toParent">向父组件发送信息</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      msg: "我是第二组件,我要给父组件传值",
    };
  },
  methods: {
    toParent() {
      this.$emit("toParent", this.msg);
    }
  }
};
</script>

效果图:

点击前

【无标题】

点击后

【无标题】

一个父传子,子传父的综合例子:

  1. 分析过程:

    首先我们创建三个组件App.vue、Carts.vue、Counter.vue,然后

  2. 代码:

    <template>
      <div>
    	<Carts></Carts>
      </div>
    </template>
    
    <script>
    import Carts from "./components/Carts.vue"
    
    export default {
    	components:{
    		Carts
    	},
    	data(){
    		return{
    			msg:""
    		}
    	}
    }
    </script>
    <!--==============上面为App.vue=================下面为Carts.vue====================-->
    
    <template>
        <div>
         <h1>购物车</h1>
          <ul>
    		<li v-for="(v,i) of cars" :key="i">
    			{{v.name}} 单价:{{v.price}} 
    			<Counter 
    			:qu="v.qu"
    			:index="i"
    			@sub="sub"
    			@add="add"
    			></Counter>
    		</li>
          </ul>
        </div>
    </template>
    
    <script>
    import Counter from "./Counter.vue"
    export default {
    	components:{Counter},
    	data(){
    		return{
    			qu:0,
    			cars:[
    				{name:"兰博基尼",price:10000,qu:0},
    				{name:"宝马",price:2000,qu:0},
    				{name:"奔驰",price:4000,qu:0},
    				{name:"特斯拉",price:5000,qu:0},
    			]
    		}
    	},
    	methods:{
    		sub(index){
    			if(this.cars[index].qu==0){
    				alert("数量不可为0哦!")
    			}
    			else{
    				this.cars[index].qu--;
    			}
    			
    		},
    		add(index){
    			this.cars[index].qu++;
    		}
    	}
    }
    </script>
    
    <!--============================下面为Counter.vue===============================-->
    
    <template>
      <span>
    	<button @click="sub">-</button>
    	<span>{{qu}}</span>
    	<button @click="add">+</button>
      </span>
    </template>
    
    <script>
    export default {
    	props:["qu","index"],
    	data(){
    		return{
    			
    		}
    	},
    	methods:{
    		sub(){
    			this.$emit("sub",this.index);
    		},
    		add(){
    			this.$emit("add",this.index);
    		}
    	}
    }
    </script>
    
    <style>
    	
    
    	
    
    </style>
    

效果图:

【无标题】

总结:

非子级之间传递数据

需要定义一个.js文件,里面存放有两个子级文件都需要操作的全局数据与调用的方法,然后在两个子级文件中分别引入这个.js文件。需要注意的是,如何在两个子级文件中表示对js文件中数据与方法的使用。

<template>
  <div>

	<Brother></Brother>
	<Sister></Sister>
  </div>
</template>

<script>

import Brother from "./components/Brother"
import Sister from "./components/Sister"

export default {
	components:{Carts,Brother, Sister},
	data(){
		return{
			
		}
	}
};
</script>
<!--==============上面为App.vue===============下面为Brother.vue====================-->
<template>
<div>
	<h1>brother <button @click="changeData">改变数据</button></h1>
	<p>{{bro.message}}</p>
</div>
</template>

<script>
import store from "../store.js"
	export default{
	data(){
		return{
			bro:store.state
		}
	},
	methods:{
		changeData(){
			store.setStateMessage("brother data")
		}
	}
}
</script>

<style>
</style>
<!--============================下面为Sister.vue===============================-->
<template>
<div>
<h1>sister</h1>
<p>{{sis.message}}</p>
</div>
</template>

<script>
import store from "../store.js"
	export default{
		data(){
			return{
				sis:store.state
			}
		}
	}
</script>

<style>
</style>
<!--============================下面为store.js===============================-->
export default {
	state:{
		message:"Hello Vue"
	},
	setStateMessage(str){
		this.state.message = str;
	}
} 

在Brother中定义变量bro,然后将js文件中的数据赋值给它,使用时使用bro.message,因为在store.js中已经定义了message,Sister中同理。

在Brother中调用store.js的setStateMessage方法的调用格式为:store.setStateMessage()

计算属性与监听器

计算属性:computed

计算属性要解决的问题就是:

我有一个非常复杂的计算表达式,直接将这个表达式放在标签里显得很乱,很复杂。我们为了简洁好看,将这个表达式用花括号{}包装起来,然后给它起个名字,加个参数,它就变成了一个方法了,然后把这个方法放在computed:{ }里面,然后在标签里面如何调用这个非常复杂的计算表达式呢?那就是在双花括号里面写入方法的名字{{方法名}}。

下面这个例子计算:总价=单价×数量×折扣

<template>
<div id="app">
	<h1>{{message}}</h1>
	<p>单价{{price}}</p>
	<p>数量
	<button @click="sub">-</button>
	<span>{{quatity}}</span>
	<button @click="add">+</button>
	</p>
	<p>	折扣 {{discount}}</p>
	<h2>总价:{{totalPrice}}</h2>
</div>
</template>

<script>
export default{
	data(){
		return{
			message:"Hello world",
			price:99,
			quatity:0,
			discount:0.5
		}
	},
	computed:{
		totalPrice(){
			return this.price*this.quatity*this.discount
		}
	},

	methods:{
		sub(){
			this.quatity--
		},
		add(){
			this.quatity++
		}
	}
}
</script>

<style>

</style>

监听器:watch

监听器就是监听一个值,然后把这个值变化之后的值传到一个方法里面,方法的名字就是这个值的名字,方法的内容往往是对这个值变化之后的值进行一系列的计算。

例如:监听器要监听value的值,然后就把val变化之后的值传到value(val){ },其中val是value变化后的值。

<template>
<div id="app">
	<h1>{{message}}</h1>
	<p>单价{{price}}</p>
	<p>数量
	<button @click="sub">-</button>
	<span>{{quatity}}</span>
	<button @click="add">+</button>
	</p>
	<p>	折扣 {{discount}}</p>
	<h2>总价:{{totalPrice}}</h2>
</div>
</template>

<script>
export default{
	data(){
		return{
			message:"Hello world",
			price:99,
			quatity:0,
			discount:0.5,
			totalPrice:0
		}
	},
	// computed:{
	// 	totalPrice(){
	// 		return this.price*this.quatity*this.discount
	// 	}
	// },
	watch:{
		quatity(qu){
			this.totalPrice = this.price * qu * this.discount
		}
	},
	methods:{
		sub(){
			this.quatity--
		},
		add(){
			this.quatity++
		}
	}
}
</script>

<style>

</style>

计算属性与监听器的区别

多个值改变,为了得到一个值的结果,一般用计算属性(computed)

一个值的改变,会引起多个值的改变,一般用监听器(watch)

实际开发中,大部分时候用computed属性,性能也比较好

但是在用到路由的时候,只能用监听器。

上一篇:export default 与 export const 区别


下一篇:MySQL 数据库 表 字段编码