vue简介及基础语法

vue简介及基础语法

前端编程从最初的html、css、js散件编写页面,到后来ajax异步请求的出现,在不断发展,在Angular框架出现之后,出现了前端工程化的概念,而现在时下最主流的框架就是React、Vue框架,其中Vue在国内的应用较为广泛。

随着框架的发展,未来也可能出现各移动端统一的前端语言或者平台,但是目前来说效率可能会因此折损,所以暂未流行,目前有谷歌Flutter,uni-app等。

vue采取MVVM架构,可以将前端的代码分为三层:

  • M:model数据层,可以理解为js代码提供的数据。
  • V:view视图层,html代码css样式
  • VM:两层之间的中间层,常规是通过js的DOM操作,而vue则可以直接将数据与视图绑定。

vue是渐进式框架,可以单页面开发(spa:single page web application)和组件化开发,不必完整的建立一个vue项目也可以使用vue框架。

用一个helloworld开始

打开pycharm新建一个html文件。

在html文件中中引入vue框架的js文件。

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

编写html代码:

<html>
    <div id="app">
        {{startMsg}}
    </div>
</html>

vue对象传入数据:

<script>
	let app = new Vue({
        el:'#app',
        data:{
            startMsg:'helloworld!'
        }
    })
</script>

我们在用浏览器打开这个html文件,会将我们js代码传入的数据打印在标签上。

简要说明一下,Vue对象可以自动的检测到数据的变化,并用vue语法将数据实时的打印到页面上。

通过vue改变页面上的值

页面中已经有了一个名app的Vue对象,可以直接通过点属性对Vue对象进行操作:

image

在浏览器的控制台console中编写js代码:

>app._data.startMsg
<·helloworld!
    // 等效于
>app.startMsg
<·helloworld!
>app.startMsg="i have changed!"

在Vue对象中,data的优先级被提高了,js代码可以直接通过点属性的方式对数据键值进行操作,并且在发生变化时,页面上绑定的{{startMsg}}也会同时的刷新,十分的方便。

vue插值语法

插值语法基本形式:

  1. 用{{}}在html标签的文本中书写,括号中放入vue对象数据的键,渲染会渲染成对应的数据值。在标签的属性位置等无法处理插值,与dtl的模板语法不一样。
  2. 自定义对象的键(包括vue对象和data的值对象)可以不书写引号,但是注意键名不能含-,一般采取小驼峰体。
  3. vue对象的data值发生变化时,html页面上对应的插值也会同步变化
  4. vue对象创建后,通过一定的格式对标签进行绑定,如下方的div标签,绑定vue对象的标签内部可以调用vue对象中的data数据。
<!---html页面加vue插值语法-->
<div id="app">
    <p>名字:{{name}}</p>
    <p>年龄:{{age}}</p>
    <p>爱好:{{hobby}}----->第一个爱好:{{hobby[1]}}</p>
    <p>妻子:{{wife}}----》妻子的年龄:{{wife.age}}---{{wife['age']}}</p>
    <p>运算:{{10*2+3*4}}</p>
    <p>三目运算符:{{10>90?'大于':'小于'}}</p>
    <p>标签(默认不会渲染成标签):{{a_url}}</p>
    <p>函数执行结果:{{[1, 2].pop()}}</p>
</div>
<!---js代码创建vue对象绑定标签-->
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            name: 'leethon',
            age: 18,
            hobby: ['篮球', '足球', '乒乓球'],
            wife: {name: '久岐忍', age: 20},
            // 运算:可以在{{}}中书写基础运算符执行运算
            // 三目运算符:条件?'符合条件时显示的内容':'不符合时显示的内容'
            a_url: '<a href="http://www.baidu.com">百度一下,你就知道</a>'
            // 函数执行结果
        }
    })
</script>
插值数据类型 补充
基本数据类型-整型、字符串等
数组 可以索引取值
自定义对象 可以键取值(['key'])或属性取值(.key)
运算式 显示运算结果
三目运算符:条件?结果1:结果2 结果的形式可以是上述的所有插值数据类型
函数运行结果 即函数()

vue指令

文本指令和显隐指令

是指令的一种,关于指令,vue的所有指令形式都符合:v-xx

指令写在标签的属性中,代表改标签会执行对应的指令。

而文本指令的形式为:

<p v-text="a_url"></p>   等同于     <p>{{a_url}}</p>

这个p标签对应的vue对象数据a_url的值将会被渲染到p标签的内部。

如果数据的值形式类似于'<a href="http://www.baidu.com">百度一下,你就知道</a>',那么使用v-text指令渲染,则显示的就是这段文本。如果想要将其渲染成一个a标签,那么则需要用:

<p v-html="a_url"></p>

造成两种指令的差异的底层原理其实就是,v-text会将一些特殊字符做转义处理,让它在页面中不会变成标签,如>会处理为&gt

显隐指令

我们通过v-show指令可以让标签显示或隐藏:

<!-- 数据值为布尔值-->
name:"leethon"
is_show: false
<!--含v-show标签-->
<p v-show="is_show">名字:{{name}}</p>
<!--实际渲染出来的标签-->
<p style="display: none;">名字:leethon</p>

属性指令

标签上的属性可以绑定变量,让标签属性的值产生改变。

语法:v-bind:属性名="变量名",可简写为:属性名="变量名"

例子:

<a :href="url">点我有你好看(♥∀♥)</a>

事件指令

诸如点击事件、双击事件等事件都可以通过v-on事件名的方式让标签绑定。

<div id="app">
	<button v-on:click="handlerClick">点击显示</button>
    <p v-show="is_show">名字:{{name}}</p>
</div>
<script>
let vm = new Vue({
    el: '#app',
    data: {
        name: 'leethon',
        is_show: false,
        handlerClick:function() {
                vm.is_show = true
            },
        },
    })
</script>

一些简化和优化:

  • 绑定事件可以使用@事件名='函数键'做简写。
  • 因为事件属于方法,这些函数一般统一放到methods键后的集合中,且不需要有额外的键值
  • 在methods中的方法会自动传入this供使用,值得是绑定vue对象的总软件标签

优化后:

<script>
let vm = new Vue({
    el: '#app',
    data: {
        name: 'leethon',
        is_show: false,
        },
    methods: {
        handlerClick() {
                this.is_show = true
            },
        },
    })
</script>

class和style属性指令

两个都属于属性指令,但由于两者比较泛用,这里单独提一下。

我们可以让:class='变量'中的变量形式进行适当的选择。

class变量选择

class推荐用数组,class_array:['font', 'background']

而实际上,它也可以用字符串,自定义对象这两种数据来作为变量值。

class_str:"font background" class_obj:{font:true,"background":false}

这些形式的变量都会处理成多个属性共存的结果,而实际使用来说数组更适合class的使用。

style变量选择

style推荐用自定义对象,style_obj:{fontSize:"10px","border-left":"5px"}

作为style属性值的自定义对象中,遵循:

  • 键可以采取带引号的原style属性名不带引号的小驼峰属性名
  • 属性值必须是字符串形式的

因为每个属性值的内容是多变的,所以更适合用自定义对象。

逻辑渲染

分支渲染

形式:

  • <标签1 v-if="条件1"><标签2 v-else-if="条件2"><标签3 v-else>

逻辑:

  • 满足条件1时显示标签1,满足条件2时显示标签2,所有条件都不满足则显示标签3
  • 一个v-if到一个v-else是一个分支结构,所有分支中只会有一个(组)标签显示出来
<div id="app">
    成绩:
    <span v-if="score>=90">优秀</span>
    <span v-else-if="score>=80">良好</span>
    <span v-else-if="score>=60">及格</span>
    <span v-else>不及格</span>
</div>
<script>
    let app = new Vue({
        el: '#app',
        data: {
            score: 40
        }
    })
</script>

循环渲染

形式

  • <标签1 v-for="单次循环变量 in 数组/对象/字符串">
        {{单次循环变量只能在v-for标签中的范围内做变量使用}}
    </标签1>
    
  • v-for可以循环的几种方式

    形式 含义
    item in 数组 依次取出数组中的值做item的值
    (item,index) in 数组 对应的索引值放到index中
    item in 自定义对象 依次取自定义对象的属性值放入item
    (item,key) in 自定义对象 取对应的键放入key变量中
    item in 字符串 字符串的单个字符做循环变量
    (item,index) in 字符串 携带字符的位置索引
    item in 数字 从1到指定数字依次取值,也有携带索引的写法
  • js的循环方式回顾

    • for (let i = 0; i < 10; i++){} 设置循环起点终点和迭代处理
    • for (i in 数组){} 每次拿到元素的索引
    • for (item of 数组){} 每次拿到元素本身
    • 数组.forEach(函数) 作为数组的方法,内部函数定义一个形参接收每次循环的元素值
    • $.each(数组/对象, function (index, item){}) jQuery方法,函数两个形参接收索引/键,元素

逻辑

  • 含v-for标签及内含标签会根据数组元素个数进行循环
  • 标签内可以插值使用单次循环变量,也可以使用指令
  • 循环的边界在v-for标签的属性框中。

例子

<!--属性值采用了v3版本的bootstrap表格-->
<div id="app">
    <div class="row">
        <div class="col-md-4 col-md-offset-4">
            <table class="table table-hover">
                <thead>
                    <tr>
                        <th>#</th>
                        <th>姓名</th>
                        <th>地址</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="item in items" :class="item.background">
                        <td>{{item.id}}</td>
                        <td>{{item.name}}</td>
                        <td>{{item.address}}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>
<script>
    let app = new Vue({
        el: '#app',
        data: {
            items: [
                {id: "1", name: "leethon", address: "安徽", background: "success"},
                {id: "2", name: "zhanghong", address: "山西", background: "danger"},
                {id: "3", name: "dragon-Y", address: "河南", background: "warning"}
            ]
        }
    })
</script>

效果:

image

v-for优化

加装了v-for的标签,可以在加以个key属性,这个属性是由vue提供的,再用属性指令绑定一个变量,这样就可以在每个由v-for产生的重复标签打上一个唯一的标识,这样的做的好处就是,如果再次在数组中插入一个元素进行实时监测渲染时,不必完整的再渲染一次列表而只需要将刚放入的元素进行单独的渲染即可。

 <div v-for="item in 8" :key="item">...内容...</div>

渲染监测

我们在对循环对象进行更改时,如对象新增键值对,会发现页面并没有实时变化,这时,我们要将设置键值对的语句更改为:

Vue.set(this.info, '键', '值')

而在对循环数组进行修改时,一般都可以被监测并实时渲染。

练习:点击按钮快速刷新图片,点击图片定住,并弹出相关信息

参考:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>dianji</title>
    <script src="js/vue.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
    <div id="app">
        <br>
        <div style="height: 400px;width: 800px;overflow: hidden;margin: auto;box-shadow: 3px 3px 3px gray">
            <img :src="url" alt="" style="width: 100%" @click="clickImg">
        </div>
        <br>
        <p class="text-center"><button class="btn btn-primary btn-lg" @click="clickButton">点击我开始滚动</button></p>
    </div>
</div>
<script>
    let changeTask
    let isTaskSet = false
    let num = 0
    let app = new Vue({
        el: '#app',
        data: {
            url: '2c09c340e57a4963ba60fdc0d809db8b.jpg',
            img_url_array: [
                {img_url: '2c09c340e57a4963ba60fdc0d809db8b.jpg', detail: '每当你凝望深渊'},
                {img_url: '576f6ce564b844fb82fbb9155135d74a.jpg', detail: '大冷天的也不怕舌头冻上'},
                {img_url: 'b0fced9bf8864e88bb35b437b72f0c14.jpg', detail: '五十岁以上的!出列!'},
                {img_url: 'b3eb9d03e5704f619f3fe55d809568ce.jpg', detail: '我不会编码,你怎么不信呢?'},
                {img_url: 'c8049b9b880411ebb6edd017c2d2eca2.jpg', detail: '其实我不需要还原,每一个状态都是最好的样子'},
            ],

        },
        methods: {
            changeImg() {
                num = Math.round(Math.random() * (app.img_url_array.length - 1))
                this.url = this.img_url_array[num].img_url
            },
            clickButton() {
                if (!isTaskSet) {
                    changeTask = setInterval(this.changeImg, 300)
                    isTaskSet = true
                }
            },
            clickImg() {
                clearInterval(changeTask)
                isTaskSet = false
                alert(this.img_url_array[num].detail)
            }
        }
    })
</script>
</body>
</html>
posted @ 2023-02-14 19:38  leethon  阅读(176)  评论(0编辑  收藏  举报