Vue 基础语法相关特性

Vue 官方文档

点击这里跳转 

文本传值 demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test_vue</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    {{ message }}
</div>
</body>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "hello yangtuo"
        }
    })
</script>
</html>

展示示例

简单解析

id 作为 el 的绑定标识, 从而让 vue 对标签进行识别,

让 data 里面的数据可以在对应的标签里面的模板展示出来

data 里面的数据属性可以直接进行使用

此处的绑定为双向绑定, 在控制台进行修改后页面上也会实时更新

元素传值 demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test_vue</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app" v-bind:title="message">
    让我看看悬浮
</div>
</body>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "看吧看吧"
        }
    })
</script>
</html>

展示示例

悬浮没法截图, 意思就是这样

简单解析

v-bind 可以在标签元素的属性中进行传递, 同样是双向绑定

条件循环 demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test_vue</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <p v-if="message">我出来了</p>
    <p v-else>我不见了</p>


    <p v-if="mess === 'A'">A</p>
    <p v-else-if="mess === 'B'">B</p>
    <p v-else>Other</p>
</div>
</body>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: true,
            mess: "A"
        }
    })
</script>
</html>

展示示例

简单解析

v-if / v-elseif / v-else 类似 python 中的 if / eilf / else 

列表循环 demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test_vue</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <li v-for="item in items">
        {{item.message}}
    </li>
</div>
</body>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            items: [
                {message: "爬啊爬"},
                {message: "滚啊滚"},
                {message: "游啊游"}
            ]
        }
    })
</script>
</html>

展示示例

简单解析

v-for 循环控制 x in xs , xs 为 vue 的绑定值, x 为形参

同样具备双向绑定影响

事件处理 demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test_vue</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <button v-on:click="greet">点我</button>
</div>
</body>
<script>
    var app = new Vue({
        el: "#app",
        // 在 methods 中定义方法
        data:{
          message: "yang"
        },
        methods: {
            // 通过 this 可以拿到 data 里面的值
            greet: function () {
                alert("hello yangtuo " + this.message)
            }
        }
    })


</script>
</html>

展示示例

简单解析

v-on 进行绑定事件处理, 事件处理的函数需要在 methods 对象里面进行定义方法

methods 里面拿  data 里面的值得时候通过 this 即可拿到

异步通信 demo

相同路径下准备一个文件 data.json

{
  "name": "test",
  "version": "0.1.0",
  "private": true,
  "url": "www.test.com"
}

demo 文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test_vue</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
    <p>名字: {{info.name}} </p>
    <p>url: {{info.url}} </p>
</div>
</body>
<script>
    var app = new Vue({
        el: "#app",
        data() {
            return {info: {name: "", url: ""}}
        },
        mounted() {
            axios.get('data.json').then(response => this.info = response.data)
        }
    })


</script>
</html>

展示示例

简单解析

vue 中采用 Axios 进行异步通信, 同时在 vue 的生命周期中

存在一个 mounted 的钩子函数可以进行重写从而便于进行一系列操作

axios 拿到的数据放入提前在 data 里面声明的变量里面

从而再从标签中使用

表单输入绑定 demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test_vue</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>
<body>
<div id="app">
    <input type="text" v-model="message" value="不生效的初始值"> // value 会无法显示
    <p>输入: {{message}}</p>
</div>

</body>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "初始值的说"
        }
    })
</script>
</html>

展示示例

输入框中输入什么, 下面的 p 标签就展示什么进行同步更新

简单解析

v-model 作为 vue 的语法糖对输入表单进行双向绑定, 从而实现实时联动展示数据

但是注意:

  1. v-model 会让标签内本身定义的 value , checked , selected 等默认值属性失效

  2. v-model 对下拉框的展示在 ios 中会有 bug 导致第一个选择会无法被选择

    2.1 处理方法: 在下拉框中的第一个位置展示一个值为空的禁用选项, 比如置灰的 "请选择" 

组件使用 demo

此 demo 为 js 的形式来实现组件, 开发中并不会使用此种方式

目前仅作为便于理解进行简单展示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test_vue</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>
<body>
<div id="app">
    <ul>
        <my-component-li></my-component-li>
    </ul>
</div>
</body>
<script>
    Vue.component("my-component-li", {
        template:"<li>hello cibo</li>>"
    })
    var app = new Vue({
        el: "#app"
    })
</script>
</html>

展示示例

简单解析

组件可以理解为 vue 中可以重复使用的一组模板

可以通过 Vue.component 进行定义 ("名字", { template: "内容" })

然后 名字的 标签使用的地方就可以进行复用, 通常不会使用此方法

而且 li 一般用于循环, 这里改动一下代码

这里红色的 items 是通过 v-for 直接在 data 里面就可以拿到的

绿色的 item 是在组件里面 props 里面定义拿到的

红色和绿色彼此是互不干涉的, 因此需要 v-bind 进行绑定 (蓝色部分)

v-bind 前面穿的值是当前组件的一个属性, 这个属性在 组件的 porps中进行了定义

v-bind 后面穿得值是属性的赋值, 这里用了 v-for 循环的形参 

结果展示

计算属性 demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test_vue</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>
<body>
<div id="app">
    <p>当前时间方法: {{getCurrentTime()}}</p>
    <p>当前时间属性: {{getCurrentTime1}}</p>
</div>
</body>
<script>
    var app = new Vue({
        el: "#app",
        methods: {
            getCurrentTime: function () {
                return Date.now();
            }
        },
        computed: {
            getCurrentTime1: function () {
                return Date.now();
            }
        }
    })
</script>
</html>

展示示例

可以看到计算属性出来的数据是不会发生变化的

而方法计算的数据是每次使用都重新计算的

简单解析

通过 computed 进行定义, 然后计算函数放入, 将计算函数的结果缓存

避免下次使用此值得时候再次进行计算, 从而避免了额外的开销

本质上是将一个动态的运行结果转化为一个静态的属性

插槽 demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test_vue</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>
<body>
<div id="app">
    <todo>
        <todo-title slot="todo-title" v-bind:title='title'></todo-title>
        <todo-context slot="todo-context" v-for='context in contexts' v-bind:context='context'></todo-context>
    </todo>
</div>
</body>
<script>
    Vue.component("todo", {
        template: "<div>" +
            "<slot name='todo-title'></slot>" +
            "<ul>" +
            "<slot name='todo-context'></slot>" +
            "</ul>" +
            "</div>"
    })
    Vue.component("todo-title", {
        props: ["title"],
        template: "<div>{{title}}</div>"
    })
    Vue.component("todo-context", {
        props: ["context"],
        template: "<li>{{context}}</li>"
    })

    var app = new Vue({
        el: "#app",
        data: {
            title: "标题",
            contexts: ["a", "b", "c"]
        }
    })
</script>
</html>

展示示例

简单解析

插槽是作为组件放入的位置进行定义的

大组件里面经常会放入小组件, 小组件在大组件的摆放的预留位置则是插槽

本次示例中大组件 todo 里面有 两个小组件 todo-title 和 todo-context

使用 solt 在大组价中预留位置

组件的传值依旧是定义 props 里面属性, 然后使用的地方 bind 绑定外部的 数据进行映射

自定义事件 demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test_vue</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

</head>
<body>
<div id="app">
    <todo>
        <todo-title slot="todo-title" :title='title'></todo-title>
        <todo-context
                slot="todo-context"
                v-for='(context, index) in contexts'
                :context='context' // v-bind: 的简写
                :index='index'
                v-on:remove="removeContexts"></todo-context>
    </todo>
</div>
</body>
<script>
    Vue.component("todo", {
        template: "<div>" +
            "<slot name='todo-title'></slot>" +
            "<ul>" +
            "<slot name='todo-context'></slot>" +
            "</ul>" +
            "</div>"
    })
    Vue.component("todo-title", {
        props: ["title"],
        template: "<div>{{title}}</div>"
    })
    Vue.component("todo-context", {
        props: ["context", "index"],
        template: "<li>{{index}} --> {{context}} <button v-on:click='remove'>删除</button></li>",
        methods: {
            remove: function () {
                this.$emit("remove");
            }
        }
    })

    var app = new Vue({
        el: "#app",
        data: {
            title: "标题",
            contexts: ["a", "b", "c"]
        },
        methods: {
            removeContexts: function (index) {
                this.contexts.splice(index, 1);
                alert(123)
            }
        }
    })
</script>
</html>

展示示例

点击删除按钮后会将此行删除掉

 

简单解析

基于上一个示例,  在每行后面加一个删除按钮, 点击后删除本行

首先确认三个事实:

  1. 每一行都是根据数据for出来的, 因为数据绑定, 删数据即可实现删行

  1. 组件定义的地方里面是没有数据的, 数据是组件被渲染的时候外部穿进去展示的

  2. 标签里面是没法调用到组件内的方法的, 标签本质是最外部最终展示的结果

基于这两个因素

  1. 组件里面直接删除数据不可行

  2. 组件里面定义删除方法, 外面调不到也不行

但是

  1. 数据是在外面 data 里面定义的. 因此在外面就可以删掉

  2. 通过组件内自定义方法 $emit("方法名") 指定后即可在标签内调用外部的方法

    2.1 v-on:remve(自定义方法名):removeContext(外部方法名) 

    2.2 因为这里的 v-on 和 v-for 和组件 都是基于 Vue 内部, 可以省略参数的传递

最终的流程图

外部定义删除方法删除数据, 组件自定义方法, 标签内通过 v-on 将两方法链接

参数的传递标签内和组件内可以省略, 参数要和外部绑定起来让外部的函数能拿到

但是外部的方法必须该有的不能少 (毕竟这里是真正的计算逻辑少了参数怎么行)

原文地址:https://www.cnblogs.com/shijieli/p/14851323.html