Vue快速入门

2022-08-19 19:36:48 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

迫于无奈还得学下前端的东西,虽然本人学的是后端,但是很早也就听过了Vue很火,所以这里花一天时间学一些基础的Vue知识,至少保证能看懂吧!

1 Node和NPM

NPM是Node提供的模块管理工具,可以非常方便的下载安装很多前端框架,包括Jquery、AngularJS、VueJs都有,所以我们先安装node及NPM工具。

Node下载地址 Node下载地址

下载完后下一步下一步地安装即可,安装完成Node自带了NPM了

下载完后看看是否有npm,控制台查看下npm版本

代码语言:javascript复制
C:Users12706>npm -v
6.4.1

npm默认的仓库地址是在国外网站,速度较慢,建议设置到淘宝镜像。但是切换镜像是比较麻烦的。推荐一款切换镜像的工具:nrm 我们首先安装nrm,这里-g代表全局安装,然后查看下仓库列表,*表示当前使用的

代码语言:javascript复制
C:Users12706>npm install nrm -g
npm WARN deprecated coffee-script@1.7.1: CoffeeScript on NPM has moved to "coffeescript" (no hyphen)
C:Users12706AppDataRoamingnpmnrm -> C:Users12706AppDataRoamingnpmnode_modulesnrmcli.js
  nrm@1.1.0
added 324 packages from 564 contributors in 22.949s

C:Users12706>nrm ls

* npm ---- https://registry.npmjs.org/
  cnpm --- http://r.cnpmjs.org/
  taobao - https://registry.npm.taobao.org/
  nj ----- https://registry.nodejitsu.com/
  npmMirror  https://skimdb.npmjs.com/registry/
  edunpm - http://registry.enpmjs.org/

注意到npm当前使用的是国外的是国外的仓库地址,速度会比较慢,我们切换到淘宝镜像,顺便测试下速度

代码语言:javascript复制
C:Users12706>nrm use taobao
                         verb config Skipping project config: C:Users12706/.npmrc. (matches userconfig)

   Registry has been set to: https://registry.npm.taobao.org/


C:Users12706>nrm test npm

  npm ---- 1211ms

注意:安装完后重启下电脑

2 Vue项目创建与安装

接下来就准备使用Vue了,首先创建工程,这里使用的开发工具是idea,由于第一次使用,所以全部进行了截图。

使用npm安装Vue

直接使用idea的中端来安装

代码语言:javascript复制
Microsoft Windows [版本 10.0.10586]
(c) 2015 Microsoft Corporation。保留所有权利。

D:my-vue>cd vue-demo

D:my-vuevue-demo>npm init -y   #初始化  此时项目会多个package.json文件夹
Wrote to D:my-vuevue-demopackage.json:

{
  "name": "vue-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}



D:my-vuevue-demo>npm install vue --save   #只针对该应用进行安装
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN vue-demo@1.0.0 No description
npm WARN vue-demo@1.0.0 No repository field.

  vue@2.6.10
added 1 package from 1 contributor and audited 1 package in 2.624s
found 0 vulnerabilities

注意:

代码语言:javascript复制
npm init -y   #初始化  此时项目会多个package.json文件夹
npm install vue --save   #只针对该应用进行安装  此时会多个node_modules文件夹,下面是Vue的源代码这些

最终就是下面这个样子

代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hello vue</title>
</head>
<body>
<div id="app">
    <h1>
        {
  
  {name}} 很帅
    </h1>
</div>
<script src="node_modules/vue/dist/vue.js"></script>

<script>
    const app = new Vue({
        el: "#app",
        data:{
            name: "King"
        }
    });
</script>

</body>
</html>

浏览器访问

  • 首先通过 new Vue()来创建Vue实例
  • 然后构造函数接收一个对象,对象中有一些属性:
    • el:是element的缩写,通过id选中要渲染的页面元素,本例中是一个div
    • data:数据,数据是一个对象,里面有很多属性,都可以渲染到视图中
      • name:这里我们指定了一个name属性
  • 页面中的h1元素中,我们通过{ {name}}的方式,来渲染刚刚定义的name属性。

双向绑定

代码语言:javascript复制
<div id="app">
    <input type="text" v-model="num"><button @click="num  "> </button>
    <h1>
        {
  
  {name}} 很帅<br>
        {
  
  {num}}位女性为其着迷!
    </h1>
</div>
<script src="node_modules/vue/dist/vue.js"></script>

<script>
    const app = new Vue({
        el: "#app",
        data:{
            name: "King",
            num: 1
        }
    });
</script>
  • 我们在data添加了新的属性:num
  • 在页面中有一个input元素,通过v-modelnum进行绑定。
  • 同时通过{ {num}}在页面输出

每次点击” ”,数值都会变化,比如我点了三次加号效果如下 注意:需要安装Vue Devtools才会有那个Vue视图

我们可以观察到,输入框的变化引起了data中的num的变化,同时页面输出也跟着变化。

  • input与num绑定,input的value值变化,影响到了data中的num值
  • 页面{ {num}}与数据num绑定,因此num值变化,引起了页面效果变化。

定义方法

前面vue中是定义了属性name和num,这里定义方法

页面添加按钮

代码语言:javascript复制
//div中
 <button @click="handleClick">快来点我</button>
 
//vue添加
const app = new Vue({
    el: "#app",
    data:{
        name: "King",
        num: 1
    },
    methods:{
        handleClick(){
            console.log("hello world!")
        }
    }
});

@click帮点了方法handleClick

点击按钮后控制台输出 hello world!

钩子函数

例如:created代表在vue实例创建后;我们可以在Vue中定义一个created函数,代表这个时期的构造函数:

代码语言:javascript复制
const app = new Vue({
        el: "#app",
        data:{
            name: "King",
            num: 1
        },
        methods:{
            handleClick(){
                console.log("hello world!")
            }
        },
        created(){
            setTimeout(()=>this.name="King真的",1000)//this指向app
        }
    });

1秒后页面由 King很帅 变成了 King真的很帅

v-text和v-html

说明:

  • v-text:将数据输出到元素内部,如果输出的数据有HTML代码,会作为普通文本输出
  • v-html:将数据输出到元素内部,如果输出的数据有HTML代码,会被渲染

使用{ {属性}}来输出存在一个问题,如果网速很慢,那么用户体验户会很不好,下面做个简单测试。

首先,浏览器进行网络设置,改为3G网,同时刷新的时候选择清空缓存并硬性加载

效果如下:

一段时间后恢复正常,但是用户看到这样的页面是非常不友好的,所以考虑使用v-text和v-html来替换。

代码语言:javascript复制
<h1>
        <span v-text="name"></span>很帅<br>
        {
  
  {num}}位女性为其着迷!<br>
        <span v-html="name" style="color: red"></span>很帅<br>
    </h1>

页面上就不会有那种不友好的展示了。

但是v-text和v-html有什么区别呢?我们将钩子函数修改以下

代码语言:javascript复制
created(){
   //setTimeout(()=>this.name="King真的",1000)//this指向app
    this.name="<font style='color: red'>King真的</font>"
}

此时刷新页面查看

区别就不言而喻了。

v-model

刚才的v-text和v-html可以看做是单向绑定,数据影响了视图渲染,但是反过来就不行。接下来学习的v-model是双向绑定,视图(View)和模型(Model)之间会互相影响。

既然是双向绑定,一定是在视图中可以修改数据,这样就限定了视图的元素类型。目前v-model的可使用元素有:

  • input
  • select
  • textarea
  • checkbox
  • radio
  • components(Vue中的自定义组件)

基本上除了最后一项,其它都是表单的输入项。下面拿checkbox来举例

代码语言:javascript复制
	<h1>请挑选课程:</h1>
    <input type="checkbox" value="Java" v-model="lessons">Java<br>
    <input type="checkbox" value="C  " v-model="lessons">C  <br>
    <input type="checkbox" value="Python" v-model="lessons">Python<br>

    <h1>
        挑选了以下课程:{
  
  {lessons.join(",")}}
    </h1>
    //vue中data添加lessons属性
    data:{
            name: "King",
            num: 1,
            lessons:[]
        },
  • 多个CheckBox对应一个model时,model的类型是一个数组,单个checkbox值是boolean类型
  • radio对应的值是input的value值
  • inputtextarea 默认对应的model是字符串
  • select单选对应字符串,多选对应也是数组

v-on与事件修饰符

v-on指令用于给页面元素绑定事件。

语法:

代码语言:javascript复制
v-on:事件名="js片段或函数名"

注意:v-on:click之前是缩写成了@click,效果是一样的

代码语言:javascript复制
	<div style="width: 100px;height: 100px;background-color: red;" @click="print('div')">
        <button @click="print('button')">点我试试</button>
    </div>
	//vue的方法中添加print方法
	methods:{
            handleClick(){
                console.log("hello world!")
            },
            print(message){
                console.log(message)
            }
        },

点击 “点我试试”按钮后,注意到同时输出了div和button,这是因为事件传播导致的,因为button是div的函数,点击了button就相当于点击了div,使用vue可以使用.stop阻止传播

代码语言:javascript复制
<button @click.stop="print('button')">点我试试</button>

点击“点我试试”按钮后不再输出div

另外使用a标签的使用,使用@click.prevent可以阻止跳转

代码语言:javascript复制
<a href="www.baidu.com" @click.prevent="print('百度')">百度以下,你就傻了!</a>

点击后并不会跳转到 www.baidu.com

v-for

v-for可以很简单的进行数组或者对象的遍历,添加属性users,下面先遍历数组后遍历对象

代码语言:javascript复制
	data:{
            name: "King",
            num: 1,
            lessons:[],
            users:[
                {name:'柳岩', gender:'女', age: 21},
                {name:'虎哥', gender:'男', age: 30},
                {name:'范冰冰', gender:'女', age: 24},
                {name:'刘亦菲', gender:'女', age: 18},
                {name:'古力娜扎', gender:'女', age: 25}
            ],
        },

使用v-for

代码语言:javascript复制
	<ul>
        <li v-for="(u,i) in users">{
  
  {i}} {
  
  {u.name "," u.gender "," u.age}}</li>
    </ul>

u取出数组中对象,i表示下标

再来遍历users中的第一个对象

代码语言:javascript复制
	<ul>
        <li v-for="(val,key,idx) in users[0]">{
  
  {idx}} {
  
  {key ":" val}}</li>
    </ul>

甚至可以迭代数字

代码语言:javascript复制
	<ul>
        <li v-for="i in 5">{
  
  {i}}</li>
    </ul>

注意是从1到5而不是0到4

v-if

很简单的使用if,对1-5进行奇偶数区分

代码语言:javascript复制
	<ul>
        <li v-for="i in 5">
            <span v-if="i%2==0">我是偶数:{
  
  {i}}</span>
            <span v-else style="color: red">我是奇数:{
  
  {i}}</span>
        </li>
    </ul>

另外还有 “v-else-if”就不举例了。

v-show

v-show的作用跟v-if 是一样的,均是做条件判断

data中添加属性

代码语言:javascript复制
show: true

v-show的使用,点击 “点我切换按钮”后show的值在true和false间切换

代码语言:javascript复制
	<button @click="show=!show">点我切换</button>
    <h1 v-if="show">
        Are you ok?
    </h1>
    <h1 v-show="show">
        Are you ok?
    </h1>

接着我们点击按钮,两个 “Are you ok”会消失,查看页面属性

代码

代码语言:javascript复制
<h1 v-if="show">
        Are you ok?
    </h1>

直接擦除吊了,而带v-show的那部分成了 display:none,只是隐藏。也就是说不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display

第一部分学完了,完整代码如下

代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hello vue</title>
</head>
<body>
<div id="app">
    <!--vue的基本使用-->
    <input type="text" v-model="num"><button @click="num  "> </button>
    <h1>
        <span v-text="name"></span>很帅<br>
        {
  
  {num}}位女性为其着迷!<br>
        <span v-html="name" style="color: red"></span>很帅<br>
    </h1>
    <button @click="handleClick">快来点我</button>

    <!--v-model-->
    <h1>请挑选课程:</h1>
    <input type="checkbox" value="Java" v-model="lessons">Java<br>
    <input type="checkbox" value="C  " v-model="lessons">C  <br>
    <input type="checkbox" value="Python" v-model="lessons">Python<br>

    <h1>
        挑选了以下课程:{
  
  {lessons.join(",")}}
    </h1>
    <!--v-on-->
    <div style="width: 100px;height: 100px;background-color: red;" @click="print('div')">
        <button @click.stop="print('button')">点我试试</button>
        <a href="www.baidu.com" @click.prevent="print('百度')">百度以下,你就傻了!</a>
    </div>
    <!--v-for-->
    <ul>
        <li v-for="(u,i) in users">{
  
  {i}} {
  
  {u.name "," u.gender "," u.age}}</li>
    </ul>
    <ul>
        <li v-for="(val,key,idx) in users[0]">{
  
  {idx}} {
  
  {key ":" val}}</li>
    </ul>
    <ul>
        <li v-for="i in 5">{
  
  {i}}</li>
    </ul>
    <!--v-if-->
    <ul>
        <li v-for="i in 5">
            <span v-if="i%2==0">我是偶数:{
  
  {i}}</span>
            <span v-else style="color: red">我是奇数:{
  
  {i}}</span>
        </li>
    </ul>
    <button @click="show=!show">点我切换</button>
    <h1 v-if="show">
        Are you ok?
    </h1>
    <h1 v-show="show">
        Are you ok?
    </h1>
</div>
<script src="node_modules/vue/dist/vue.js"></script>

<script>
    const app = new Vue({
        el: "#app",
        data:{
            name: "King",
            num: 1,
            lessons:[],
            users:[
                {name:'柳岩', gender:'女', age: 21},
                {name:'虎哥', gender:'男', age: 30},
                {name:'范冰冰', gender:'女', age: 24},
                {name:'刘亦菲', gender:'女', age: 18},
                {name:'古力娜扎', gender:'女', age: 25}
            ],
            show: true
        },
        methods:{
            handleClick(){
                console.log("hello world!")
            },
            print(message){
                console.log(message)
            }
        },
        created(){
            //setTimeout(()=>this.name="King真的",1000)//this指向app
            this.name="<font style='color: red'>King真的</font>"
        }
    });
</script>

</body>
</html>

v-bind与class属性绑定

假如我们想动态的修改页面元素的属性,比如class属性,这样写是错误的:

代码语言:javascript复制
<div class="{ 
    {isAcctive}}"></div>

因为插值表达式不能用在属性的值中。我们可以传给 v-bind:class (可以简写为:class)一个对象,以动态地切换 class。新创建个html文件 ,完整代码如下

代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hello vue</title>
    <style type="text/css">
        div#box {
            width: 100px;
            height: 100px;
            color: darkgray;
        }
        .red{
            background-color: red;
        }
        .blue {
            background-color: blue;
        }
    </style>
</head>
<body>
<div id="app">
    <!--class属性-->
    <button @click="isRed=!isRed">点我换颜色</button>
    <div id="box" :class="{red:isRed,blue:!isRed}">
        来看我的颜色
    </div>
</div>
<script src="node_modules/vue/dist/vue.js"></script>

<script>
    const app = new Vue({
        el: "#app",
        data:{
            isRed: true
        }
    });
</script>

</body>
</html>

点击按钮后

计算属性

在插值表达式中使用js表达式是非常方便的,而且也经常被用到。

但是如果表达式的内容很长,就会显得不够优雅,而且后期维护起来也不方便,例如下面的场景,我们有一个日期的数据,但是是毫秒值:

代码语言:javascript复制
data:{ 
   
    birthday:1529032123201 // 毫秒值
}

我们在页面渲染,希望得到yyyy-MM-dd的样式:

代码语言:javascript复制
<h1>您的生日是:{
  
  {
    new Date(birthday).getFullYear()   '-'  new Date(birthday).getMonth()  '-'   new Date(birthday).getDay()
    }}
</h1>

虽然能得到结果,但是非常麻烦。Vue中提供了计算属性,来替代复杂的表达式:

代码语言:javascript复制
<!--计算属性  定义的时候似乎是方法,实际上是属性-->
    <h1>
        我的生日是:{
  
  {myBirth}}<br>
        我的生日是:{
  
  {myBirth}}<br>
        我的生日是:{
  
  {myBirth}}
    </h1>
</div>
<script src="node_modules/vue/dist/vue.js"></script>

<script>
    const app = new Vue({
        el: "#app",
        data:{
            isRed: true,
            birthday: 1345032504930,
        },
        computed:{//计算属性
            myBirth(){
                console.log("hello");
                const day = new Date(this.birthday);
                return day.getFullYear() "年" day.getMonth() "月" day.getDay() "日";//需要返回
            }
        }
    });
</script>

只输出了一次”hello”,说明这个方法其实只被调用了一次。

  • 计算属性本质就是方法,但是一定要返回数据。然后页面渲染时,可以把这个方法当成一个变量来使用。

watch

watch可以让我们监控一个值的变化。从而做出相应的反应。

代码语言:javascript复制
	<input type="text" v-model="num">
    <h1>num:{
  
  {num}}</h1>
代码语言:javascript复制
	const app = new Vue({
        el: "#app",
        data:{
            isRed: true,
            birthday: 1345032504930,
            num: 1
        },
        computed:{//计算属性
            myBirth(){
                console.log("hello");
                const day = new Date(this.birthday);
                return day.getFullYear() "年" day.getMonth() "月" day.getDay() "日";//需要返回
            }
        },
        watch:{
            num(val,oldVal){
                console.log(val,oldVal);
            }
        }
    });

补充:深度监视?

代码语言:javascript复制
const app = new Vue({
        el: "#app",
        data:{
            isRed: true,
            birthday: 1345032504930,
            num: 1,
            person:{
                name:"Jack",
                age:22
            }
        },
        computed:{//计算属性
            myBirth(){
                console.log("hello");
                const day = new Date(this.birthday);
                return day.getFullYear() "年" day.getMonth() "月" day.getDay() "日";//需要返回
            }
        },
        watch:{
            num(val,oldVal){
                console.log(val,oldVal);
            },
            person:{//监视person对象的变化
                deep:true,
                handler(obj){
                    console.log(obj.age)
                }
            }
        }
    });

点击几次 号后控制台查看

完整代码如下:

代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hello vue</title>
    <style type="text/css">
        div#box {
            width: 100px;
            height: 100px;
            color: darkgray;
        }
        .red{
            background-color: red;
        }
        .blue {
            background-color: blue;
        }
    </style>
</head>
<body>
<div id="app">
    <!--class属性-->
    <button @click="isRed=!isRed">点我换颜色</button>
    <div id="box" :class="{red:isRed,blue:!isRed}">
        来看我的颜色
    </div>

    <!--计算属性  定义的时候似乎是方法,实际上是属性-->
    <h1>
        我的生日是:{
  
  {myBirth}}<br>
        我的生日是:{
  
  {myBirth}}<br>
        我的生日是:{
  
  {myBirth}}
    </h1>

    <!--watch-->
    <input type="text" v-model="num"/>
    <h1>
        {
  
  {num}}
    </h1>
</div>
<script src="node_modules/vue/dist/vue.js"></script>

<script>
    const app = new Vue({
        el: "#app",
        data:{
            isRed: true,
            birthday: 1345032504930,
            num: 1,
            person:{
                name:"Jack",
                age:22
            }
        },
        computed:{//计算属性
            myBirth(){
                console.log("hello");
                const day = new Date(this.birthday);
                return day.getFullYear() "年" day.getMonth() "月" day.getDay() "日";//需要返回
            }
        },
        watch:{
            num(val,oldVal){
                console.log(val,oldVal);
            },
            person:{
                deep:true,
                handler(obj){
                    console.log(obj.age)
                }
            }
        }
    });
</script>

</body>
</html>

全局组件

在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航。

但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。

我们通过Vue的component方法来定义一个全局组件。

代码语言:javascript复制
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>hello</title>

</head>
<body>
<div id="app"><!--使用全局组件  定义好的组件,可以任意复用多次:-->
    <counter></counter>
</div>

<script src="node_modules/vue/dist/vue.js"></script>
<script>
    // 定义全局组件,两个参数:1,组件名称。2,组件参数
    Vue.component("counter",{
       template:"<button @click='count  '>你点了我{
  
  {count}}次</button>",
        data(){
           return {
               count:0
           }
        }
    });
    const app = new Vue({
        el:"#app"
    });
</script>
</body>
</html>

点两次按钮后

  • 组件其实也是一个Vue实例,因此它在定义时也会接收:data、methods、生命周期函数等
  • 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有el属性。
  • 但是组件渲染需要html模板,所以增加了template属性,值就是HTML模板
  • 全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名称来使用组件了。
  • data的定义方式比较特殊,必须是一个函数。

局部组件

代码语言:javascript复制
//局部组件
    const v = {
        template:"<button @click='count  '>你点了我{
  
  {count}}次</button>",
        data(){
            return{
                count:0
            }
        }
    };
    const app = new Vue({
        el: "#app",
        data:{

        },
        components: {//使用局部组件
            counter:v
        }
    })

效果同上

完整代码如下:

代码语言:javascript复制
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>hello</title>

</head>
<body>
<div id="app">
    <counter></counter>
</div>

<script src="node_modules/vue/dist/vue.js"></script>
<script>
    // 定义全局组件,两个参数:1,组件名称。2,组件参数
    // Vue.component("counter",{
    //    template:"<button @click='count  '>你点了我{
  
  {count}}次</button>",
    //     data(){
    //        return {
    //            count:0
    //        }
    //     }
    // });
    // const app = new Vue({
    //     el:"#app"
    // });
    //局部组件
    const v = {
        template:"<button @click='count  '>你点了我{
  
  {count}}次</button>",
        data(){
            return{
                count:0
            }
        }
    };
    const app = new Vue({
        el: "#app",
        data:{

        },
        components: {//使用局部组件
            counter:v
        }
    })
</script>
</body>
</html>

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/136072.html原文链接:https://javaforall.cn

0 人点赞