vue 基础常用部分总结

  • vue是MVVM框架,MVVM就是我们常说的双向数据绑定,M表示model,V表示view,在MVVM的框架中,model的改变会影响视图view,view视图的改变会反过来影响model.
    vm.$data/vm.$attrs/vm.$el/vm.$emit/vm.$forceUpdate/vm.$nextTick/vm.$options/vm.$parent/vm.$props/vm.$refs/vm.$root/vm.$slots/vm.$watch等
    一、绑定数据
<template>
  <div>
    <h1>{{ message }}</h1>

    <p>绑定对象:{{ userinfo.username }}--{{ userinfo.age }}</p>

    <p>绑定html: <span v-html="h2"></span></p>

  </div>
</template>
<script>
export default {
    data() {
        return {
            message: "vue",
            userinfo: {
                username: "张三",
                age: "20",
            },
            h2: "<h2>vue 我是一个html标签</h2>"
        }
    }
}
</script>

二、绑定属性

<template>
  <div>
    <img v-bind:src="logoSrc" alt="logoSrc" />

    <br />
    <img :src="logoSrc" alt="logoSrc" />

    <br />
    <div title="vue">鼠标放上去试试1</div>

    <br />
    <div :title="title">鼠标放上去试试2</div>
  </div>
</template>
<script>
export default {
    data() {
        return {
            logoSrc: "https://www.itying.com/themes/itying/images/logo.gif",
            title: "自定义属性值"
        }
    }
}
</script>

三、绑定动态属性

<template>
  <div>
    <a v-bind:[myHref]="'http://www.baidu.com'">跳转百度</a>
    <br />

    <a :[myHref]="myLink">跳转到myLink</a>
  </div>
</template>
<script>
export default {
    data() {
        return {
            myHref: "href",
            myLink: "http://www.itying.com"
        }
    }
}
</script>

四、循环遍历数组

<template>
  <div>
    <ul>
        <li v-for="(item, index) in list1" :key="index">
            {{ item }}--{{ index }}
        </li>
    </ul>

    <br />

    <ul>
        <li v-for="(item, index) in list2" :key="index">
            {{ item.title }}
        </li>
    </ul>

    <br />
    <br />
    <ul>
        <li v-for="(item, index) in list3" :key="index">
            {{ item.cate }}
            <ol>
                <li v-for="(i, k) in item.list" :key="k">
                    {{ i.title }}
                </li>
            </ol>
        </li>
    </ul>
  </div>
</template>
<script>
export default {
    data() {
        return {
            list1: ["张三", "李四", "王五"],
            list2: [{
                    title: "张三111",
                },
                {
                    title: "张三2222",
                },
                {
                    title: "张三3333",
                },
                {
                    title: "张三444",
                },
            ],
            list3: [{
                    cate: "国内新闻",
                    list: [{
                            title: "国内新闻11111",
                        },
                        {
                            title: "国内新闻2222",
                        },
                    ],
                },
                {
                    cate: "国际新闻",
                    list: [{
                            title: "国际新闻11111",
                        },
                        {
                            title: "国际新闻2222",
                        },
                    ],
                },
            ],
        }
    }
}
</script>

五、循环遍历对象

<template>
  <div>
    <ul>
        <li v-for="(value, attr, index) in myObject" :key="index">
            {{ attr }}---{{ value }}--{{ index }}
        </li>
    </ul>
  </div>
</template>
<script>
export default {
    data() {
        return {
            myObject: {
                title: "study Vue",
                author: "liang",
                publishedAt: "2021-05-22",
            }
        }
    }
}
</script>

六、绑定事件
// event, $event
// 事件修饰符:stop, prevent, capture, self, once, passive
// 按键修饰符:enter, tab, delete, esc, up, down, left, right
// 鼠标修饰符:left, right, middle
// 精确修饰符:exact

<template>
  <div>
    <h3>{{title}}</h3>
    <button v-on:click="setTitle('111')">设置Title的值1</button>
    <br>
    <br>
    <button v-on:click="setTitle('2222')">设置Title的值2</button>
    <button v-on:click="changeClass()">改变class</button>
    <br />
    <button @click="changeClass()">改变class</button>
    <br />
    <div :class="myClass"></div>

    <button @click="run()">执行run方法实现方法调用方法</button>
    <br>
    <button data-aid="123" @click="eventFn($event)">事件对象</button>
    <br>
    <br>
    <button @click="warn('传入的参数', $event)">
        Submit
    </button>
    <br>
    <br>
    <button @click="one(),two(),changeClass()">
        点击按钮一次执行多个方法
    </button>
    <br>
    <br>
    <a href="http://www.baidu.com" target="_blank" @click="afn1($event)">跳转链接1</a>
    <br><br>
    <a href="http://www.baidu.com" target="_blank" @click.prevent="afn2()">跳转链接2</a>

    <br>
    <br>
    <input type="text" @keyup="doSearch1($event)">
    <br> <br>
    <input type="text" @keyup.enter="doSearch2()" />
  </div>
</template>
<script>
export default {
    data() {
        return {
            myClass: "red",
            msg: "学习vue",
            title: "我是一个标题"
        }
    },
    methods: {
        getMsg() {
            alert(this.msg)
        },
        setTitle(data) {
            this.title = data;
        },
        changeClass() {
            this.myClass = "blue";
        },
        run() {
            this.changeClass()
        },
        eventFn(e) {
            console.log(e);
            e.srcElement.style.background = "red";
            //获取自定义属性
            console.log(e.srcElement.dataset.aid);

            // e.preventDefault();
            // e.stopPropagation();
        },
        warn(message, event) {
            console.log(event);
            if (event) {
                event.preventDefault()
            }
            alert(message)
        },
        one() {
            console.log("one");
        },
        two() {
            console.log("two");
        },
        afn1(e) {
            e.preventDefault();
        },
        afn2() {

        },
        doSearch1(e) {
            console.log(e)
            console.log(e.keyCode)
            if (e.keyCode == 13) {
                alert("按了回车键")
            }
        },
        doSearch2() {
            alert("按了回车键")
        },
    },
}
</script>

七、class、style绑定多个动态属性

<template>
  <div>
    <div :class="{ active: isActive, red: isRed }">div</div>

    <div class="blue" :class="{ active: isActive }">div</div>

    <br />

    <div :class="[errorClass, baseClass]">div</div>

    <br />

    <div :class="[flag ? baseClass : errorClass]">三目运算绑定class</div>
    <h2>绑定多个style</h2>

    <br>
    <div :style="'color:'+color">
        绑定style
    </div>
    <br>

    <div :style="{'color':activeColor,'fontSize':fontSize}">
        绑定多个style
    </div>
    <br>
    <div :style="styleObject">
        绑定多个style
    </div>
    <br>
    <br>

    <div :style="[baseStyles,orangeStyle]">
        绑定多个style
    </div>
    <br>
    <ul>
        <li v-for="(item,index) in list" :key="index" :class="{'aaa':index==0,'bbb':index==1}">
            {{item}}
        </li>
    </ul>
    <br>

    <ul>
        <li v-for="(item,index) in list" :key="index" :style="[index==0?styleRed:null,index==1?styleBlue:null]">
            {{item}}
        </li>
    </ul>
  </div>
</template>
<script>
export default {
    data() {
        return {
            isActive: true,
            isRed: false,
            errorClass: "error",
            baseClass: "base",
            flag: true,
            color: "red",
            activeColor: "blue",
            fontSize: "20px",
            styleObject: {
                color: 'red',
                fontSize: '43px'
            },
            baseStyles: {
                 "100px",
                height: "100px",
                fontSize: '18px'
            },
            orangeStyle: {
                background: "orange"
            },
            list: ['张三', '李四', '王五', '张三1', '李四1', '王五1'],
            styleRed: {
                color: 'red',
            },
            styleBlue: {
                color: 'blue',
            },
        }
    },
    methods: {
        changeClass() {
            this.myClass = "blue";
        },
    },
}
</script>
<style scope>
.base {
     300px;
    height: 300px;
}

.active {
    display: block;
    font-size: 30px;
    color: orange;
}

.error {
    background: orange;
    font-size: 30px;
    color: red;
}

.red {
    background: red;
     100px;
    height: 100px;
}

.blue {
    background: blue;
     100px;
    height: 100px;
}

.aaa {
    color: red;
}

.bbb {
    color: blue;
}
</style>

八、ref和双向数据绑定
// input, textarea, checkbox, radio, select
// 修饰符 lazy, number, trim

<template>
    <div>
        <h2>人员登记系统</h2>

        <!-- <div class="people_list">
            <ul>
                <li>姓 名: <input type="text" id="username" /></li>

                <li>年 龄: <input type="text" ref="age" /></li>
            </ul>

            <button @click="doSubmit()" class="submit1">获取表单的内容</button>
        </div> -->

        <div class="people_list">
            <ul>
                <li>姓 名: <input type="text" v-model="userinfo.username" /></li>

                <li>年 龄: <input type="text" v-model="userinfo.age" /></li>

                <li>性 别:
                    <input type="radio" name="sex" id="sex1" value="1" v-model="userinfo.sex"> <label for="sex1">男</label>

                    <input type="radio" name="sex" id="sex2" value="2" v-model="userinfo.sex"> <label for="sex2">女</label>

                </li>

                <li> 城 市:

                    <select v-model="userinfo.city">
                        <option v-for="(item,index) in userinfo.cityList" :key="index" :value="item">{{item}}</option>
                    </select>
                </li>
                <li> 爱 好:
                    <span v-for="(item,index) in userinfo.hobby" :key="index">
                        <input type="checkbox" :id="'ch_'+index" v-model="item.checked" />
                        <label :for="'ch_'+index">{{item.title}}</label>
                    </span>

                </li>
                <li> 备注:
                    <textarea cols="30" rows="4" v-model="userinfo.mark"></textarea>

                </li>

            </ul>

            <button @click="doSubmit()" class="submit">获取表单的内容</button>

            <br>
            <br>
            <pre>{{userinfo}}</pre>
        </div>

    </div>
</template>
<script>
export default {
    name: "Register",
    props: {},
    data() {
        return {
            username: "zhangsan",
            userinfo: {
                username: "",
                age: "",
                sex: "1",
                cityList: ["北京", "上海", "深圳"],
                city: "上海",
                hobby: [
                    {
                        title: "吃饭",
                        checked: false
                    },
                    {
                        title: "睡觉",
                        checked: false
                    },
                    {
                        title: "写代码",
                        checked: true
                    }
                ],
                mark: ""
            }
        }
    },
    methods: {
        // doSubmit1() {
        //     // 原生js
        //     var usernameObj = document.querySelector("#username")
        //     console.log(usernameObj.value)
        //     /**
        //      * 1、定义ref <iniput type="text" ref="age"
        //      * 2、this.$refs.名称
        //      */
        //     console.log(this.$refs)
        //     console.log(this.$refs.age.value)
        // }

        doSubmit() {
            console.log(this.userinfo)
        }
    }
}
</script>
<style scope>
ul {
    list-style-type: none;
}

h2 {
    text-align: center;
}

.people_list {
     400px;
    margin: 40px auto;
    padding: 40px;
    border: 1px solid #eee;
}

.people_list li {
    height: 50px;
    line-height: 50px;
}

.submit {
    float: right;
    margin-top: 10px;
}
</style>

九、JavaScript表达式、条件判断、计算属性、watch侦听
computed 和 method 都能实现的一个功能,建议使用 computed,因为有缓存
computed 和 watcher 都能实现的功能,建议使用 computed 因为更加简洁

<template>
    <div>
        <h3>1、Vue3.x模板中使用JavaScript表达式</h3>

        <div>
            {{ a + 3 }}
            <br />
            {{ a * 3 }}
            <br />
            {{ a - 3 }}
            <br />
            {{ flag ? "this is true" : "this is false" }}
            <br />
            {{ flag ? name1 : name2 }}
            <br />
            {{ message.split("").reverse().join("") }}
        </div>

        <h3>2、 v-if v-else v-else-if v-show</h3>

        <div>
            <div v-if="flag == true">this is true</div>
            <br>

            <span v-if="flag == true">this is true</span>
            <span v-else>this is false</span>

            <br>

            <span v-if="Math.random()>0.5">
                大于0.5
            </span>
            <span v-else>
                小于0.5
            </span>

            <br>
            <div v-if="type=='A'">A</div>
            <div v-else-if="type=='B'">B</div>
            <div v-else-if="type=='C'">C</div>
            <div v-else>Not A/B/C</div>

            <br>
            <template v-if="flag">
                <hr>
                <span>这是一个sapn</span>
                <div>这是一个div</div>
                <hr>
            </template>
        </div>

        <h3>4、 计算属性</h3>

        <div>
            {{reverseMsg}}
            <br>
            <button @click="setMsg()">改变msg的值</button>

            <br>
            <hr>
            <input type="text" v-model="keyword" placeholder="请输入关键词" />
            <ul>
                <li v-for="(item,index) in searchData" :key="index">{{item}}</li>
            </ul>
        </div>

        <h3>5、 watch监听数据变化</h3>

        <div>
            <input type="text" v-model="firstName" placeholder="firstName">
            <br>
            <input type="text" v-model="lastName" placeholder="lastName">
            <br>
            {{fullName}}

            <br>
        </div>

    </div>
</template>
<script>
export default {
    data() {
        return {
            a: 12,
            flag: false,
            message: "三国演义",
            name1: "张三",
            name2: "李四",
            type: "N",
            listData: ["apple", "banana", "orange", "pear"],
            keyword: "",
            firstName: "",
            lastName: "",
            fullName: ""
        }
    },
    methods: {
        setMsg() {
            this.message = "大家好"
        }
    },
    computed: {
        reverseMsg() {
            return this.message.split("").reverse().join("")
        },
        searchData() {
            var tempArr = []
            this.listData.forEach((value) => {
                if (value.indexOf(this.keyword) !== -1 && this.keyword !== "") {
                    tempArr.push(value)
                }
            })
            console.log(tempArr)
            return tempArr
        }
        // fullName() {
        //     return this.firstName + " " + this.lastName
        // }
    },
    watch: {
        firstName: function (value) {
            this.fullName = value + " " + this.lastName
        },
        lastName: function (value) {
            this.fullName = this.firstName + " " + value
        }
    }
}
</script>

<style scope>
</style>

十、插槽

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>study</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  // slot 插槽
  // slot 中使用的数据,作用域的问题
  // 父模版里调用的数据属性,使用的都是父模版里的数据
  // 子模版里调用的数据属性,使用的都是子模版里的数据
  // 具名插槽
  const app = Vue.createApp({
    template: `
      <layout>
        <template v-slot:header>
          <div>header</div>
        </template>
        <template v-slot:footer>
          <div>footer</div>
        </template>
      </layout>
    `
  });

  app.component('layout', {
    template: `
      <div>
        <slot name="header"></slot>
        <div>content</div>
        <slot name="footer"></slot>
      </div>
    `
    // 或 <slot #header></slot>
  });

  const vm = app.mount('#root');
</script>
</html>

作用域插槽

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>study</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  // 作用域插槽
  const app = Vue.createApp({
    template: `
      <list v-slot="{item}">
        <div>{{item}}</div>
      </list>
    `
  });

  app.component('list', {
    data() {return {list: [1, 2, 3]}},
    template: `
      <div>
        <slot v-for="item in list" :item="item" />
      </div>
    `
  });

  const vm = app.mount('#root');
</script>
</html>

十一、异步组件

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>study</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  // 动态组件: 根据数据的变化,结合 compoent 这个标签,来随时动态切换组件的现实
  // 异步组件: 是异步执行某些组件的逻辑,这叫做异步组件

  const app = Vue.createApp({
    template: `
      <div>
        <common-item />
        <async-common-item />
      </div>
    `
  });

  app.component('common-item', {
    template: `<div>hello world</div>`
  });

  app.component('async-common-item', Vue.defineAsyncComponent(() => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({
          template: `<div>this is an async component</div>`
        })
      }, 4000)
    })
  }))

  const vm = app.mount('#root');
</script>
</html>

十二、其它

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>study</title>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="root"></div>
</body>
<script>
  // v-once 让某个元素标签只渲染一次
  // ref 实际上是获取 Dom 节点 / 组件引用 的一个语法
  // provide / inject
  const app = Vue.createApp({
    data() {
      return { count: 1}
    },
    provide() {
      return {
        count: this.count,
      }
    },
    template: `
      <div>
        <child :count="count" />
        <button @click="count += 1">Add</button>
      </div>
    `
  });

  app.component('child', {
    template: `<child-child />`
  });

  app.component('child-child', {
    inject: ['count'],
    template: `<div>{{count}}</div>`
  });

  const vm = app.mount('#root');
</script>
</html>

十三、

持续更新中......

砥砺前行
原文地址:https://www.cnblogs.com/lhongsen/p/14798627.html