vue
Vue介绍
vue分为两个版本,开发版本development和生产版本production
开发版本:vue.js
生产版本:vue.js被压缩成了一行,所有不必要的注释/空格/换行等,都被删除,而且删除了所有的提示,目的是为了减小项目体积,使打开页面更快,项目上线时用。
使用Vue
文本差值
js中的数据,展示在界面上,相当于原生js中的innerText方法
原始html
本指令相当于原生js中的html
Attribute 绑定
V-bind来修改标签的属性,简写用:即可。
布尔型Attribute
同时绑定多个Attribute
使用javascript表达式
注意:每个绑定仅支持单一表达式,也就是一段能够被求值的javascript代码(语句不可以)。
调用函数
可以在绑定的表达式里调用函数,但非常不建议这样做,可以使用Math或Data等全局暴露的函数。
<p>生成一个随机数{{Math.random()}}</p>
computed计算属性
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
    <p>{{reverseStr}}</p>
    <ul>
        <li><p>{{text.split('').reverse().join('')}}</p></li>
        <!--上方代码,同样的功能要计算两次,消耗性能,并且导致html代码臃肿,下方的更佳-->
        <li><p>{{reverseStr}}</p></li>
    </ul>
</div>
</body>
</html>
<script>
    const {createApp} = Vue
    createApp({
        data() {
            return {
        text:'hello world'
            }
        },
        computed:{
            reverseStr(){//这里一定要指定this,text,this指的是当前实例,可以理解为data里的数据
                return this.text.split('').reverse().join('')
             }
        }
    }).mount('#app')
</script>
事件处理
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
    <p>{{count}}</p>
    <button v-on:click="add()">+</button>
    <button @click="add()">+</button>
    <button v-on:click="less()">-</button>
    <button @click="less()">-</button>
    <button @click="add(5)">+5</button>
    <button @click="add(6)">+6</button>
    <button @click="less(5)">-5</button>
    <button @click="less(6)">-6</button>
</div>
</body>
</html>
<script>
    const {createApp} = Vue
    createApp({
        data() {
            return {
                count: 0
            }
        },
        computed: {//计算属性
        },
        methods: {//方法
            add(a = 1) {
                // this.count=this.count+a
                this.count += a
            },
            less(a = 1) {
                // this.count=this.count-a
                this.count -= a
            }
        }
    }).mount('#app')
</script>
计算属性vs方法
注意:计算属性和方法,在结果上确实是相同的,然而不同之处在于
计算属性会基于其响应式依赖而被缓存,一个计算属性仅会在其响应式依赖更新时才会被重新计算
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
    <input type="number" v-model="count">
    <p>输入数字乘以2:{{ChengYi2}}</p>
    <p>methods:{{methodChengYi2()}}</p>
</div>
</body>
</html>
<script>
    const {createApp} = Vue
    createApp({
        data() {
            return {
                count: 0
            }
        },
        computed: {//当数据来源被改变,则计算属性重新计算
            ChengYi2() {
                return this.count * 2
            }
        },
        methods: {//方法
            methodChengYi2() {
                return this.count * 2
            }
        }
    }).mount('#app')
</script>
条件渲染
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<ul>
    <li v-if="type==='A'">AAAAAA</li>
<!--    <li v-else-if="type==='B'">BBBBBB</li>-->
    <li v-else>CCCCCC</li>
</ul>
    <p v-show="seen">现在你看得到我</p>
</div>
</body>
</html>
<script>
    const {createApp} = Vue
    createApp({
        data() {
            return {
                type:'B',
                seen:true
            }
        }
    }).mount('#app')
</script>
列表渲染
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<table>
    <thead>
    <tr>
        <th>id</th>
        <th>书名</th>
        <th>价格</th>
    </tr>
    </thead>
    <tbody>
    <tr v-for="{book,index} of books" :key="index">
<!--        key一般是数据库里的数据上的唯一且不重复的主键-即id-->
        <td>{{book.id}}</td>
        <td>{{book.name}}</td>
        <td>{{book.price}}</td>
    </tr>
    </tbody>
</table>
</div>
</body>
</html>
<script>
    const {createApp} = Vue
    createApp({
        data() {
            return {
                books:[
                    {id:0,name:'三体',price:68},
                    {id:1,name:'平凡的世界',price: 89},
                    {id:2,name:'三国演义',price:40}
                ]
            }
        }
    }).mount('#app')
</script>
表单输入绑定
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" :value="text" @input="ipt($event)">
    <input type="text" v-model="text">
    <p>{{text}}</p>
</div>
</body>
</html>
<script>
    const {createApp} = Vue
    createApp({
        data() {
            return {
            text:'hello world'
            }
        },
        // methods:{
        //     ipt(event){
        //         this.text=event.target.value
        //     }
        // }
    }).mount('#app')
</script>
多行文本
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
    <textarea v-model="message" placeholder="add multiple lines"></textarea>
<!--    多行文本,即换行符,可以被v-module实时修改数据-->
    <p style="white-space: pre-line;">{{ message}}</p>
<!--    此css属性可以展示字符串中的换行符-->
</div>
</body>
</html>
<script>
    const {createApp} = Vue
    createApp({
        data() {
            return {
                message: ''
            }
        },
    }).mount('#app')
</script>
数据单项绑定
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<label for="ipt"></label>
    <input type="checkbox" id="ipt" :checked="checked">打篮球
<!--    数据单项绑定,data驱动ui,ui不可修改data-->
    <p>{{checked}}</p>
</div>
</body>
</html>
<script>
    const {createApp} = Vue
    createApp({
        data() {
            return {
                checked:false
            }
        },
    }).mount('#app')
</script>
数据双项绑定
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<label for="ipt"></label>
    <input type="checkbox" id="ipt" v-model="checked">打篮球
<!--    数据单项绑定,data驱动ui,ui不可修改data-->
    <p>{{checked}}</p>
</div>
</body>
</html>
<script>
    const {createApp} = Vue
    createApp({
        data() {
            return {
                checked:false
            }
        },
    }).mount('#app')
</script>
将多个复选框绑定到同一个数组或集合
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
    <h2>选中的人是:{{checkedNames}}</h2>
    <input type="checkbox" v-model="checkedNames" value="Jack">
    <input type="checkbox" v-model="checkedNames" value="John">
    <input type="checkbox" v-model="checkedNames" value="Mike">
</div>
</body>
</html>
<script>
    const {createApp} = Vue
    createApp({
        data() {
            return {
                checkedNames:[]
            }
        },
    }).mount('#app')
</script>
单选框
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
    <h2>选中的人是:{{picked}}</h2>
    <input type="radio" v-model="picked" value="1">男
    <input type="radio" v-model="picked" value="0">女
    <input type="radio" v-model="picked" value="-1">自定义
</div>
</body>
</html>
<script>
    const {createApp} = Vue
    createApp({
        data() {
            return {
                picked:1
            }
        },
    }).mount('#app')
</script>
选择器
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
    <div>Selected: {{ selected }}</div>
    <select v-model="selected">
        <option disabled value="">Please select one</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
    </select>
</div>
</body>
</html>
<script>
    const {createApp} = Vue
    createApp({
        data() {
            return {
                selected:''
            }
        },
    }).mount('#app')
</script>
注意
如果
v-model表达式的初始值不匹配任何一个选择项,<select>元素会渲染成一个“未选择”的状态。在 iOS 上,这将导致用户无法选择第一项,因为 iOS 在这种情况下不会触发一个 change 事件。因此,我们建议提供一个空值的禁用选项,如上面的例子所示。
多选
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
    <div>Selected: {{ selected }}</div>
    <select v-model="selected" multiple>
<!--        <option disabled value="">Please select one</option>-->
        <option>A</option>
        <option>B</option>
        <option>C</option>
    </select>
</div>
</body>
</html>
<script>
    const {createApp} = Vue
    createApp({
        data() {
            return {
                selected:''
            }
        },
    }).mount('#app')
</script>
修饰符 lazy number trim
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
    <input type="text" v-model="message">
    <input type="text" v-model.lazy="message">
    <input type="text" v-model.number="message">
    <input type="text" v-model.trim="message">
    <p>{{message}}</p>
</div>
</body>
</html>
<script>
    const {createApp} = Vue
    createApp({
        data() {
            return {
                message: ''
            }
        },
    }).mount('#app')
</script>
生命周期
侦听器
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../node_modules/vue/dist/vue.global.js"></script>
    <style>
        @keyframes zhuan {
            0%{transform: rotate(0)}
            100%{transform: rotate(360deg)}
        }
        .active{animation: zhuan 10s linear infinite}
    </style>
</head>
<body>
<div id="app">
<p>{{message}}</p>
    <input type="text" v-model="message">
    <p>{{name}}</p>
</div>
</body>
</html>
<script>
    const {createApp} = Vue
    const vm=createApp({
        data() {
            return {
                message:'1111',
                name:'xxxx'
            }
        },
        watch:{
            message(){//要监听哪个数据,就对应哪个
                // console.log('message changed')
                if (this.message.length>=10) alert('long')
            }
        }
    }).mount('#app')
</script>
vue中的dom操作
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../node_modules/vue/dist/vue.global.js"></script>
    <style>#test{width: 100px;height: 100px;background: red}</style>
</head>
<body>
<div id="app">
<div id="test" ref="test"></div>
    <button @click="big">变大div</button>
    <input type="text" ref="ipt">
</div>
</body>
</html>
<script>
    const {createApp} = Vue
    const vm =createApp({
        data() {
            return {
            }
        },
        methods:{
            big(){
                //原始js方法,极不推荐
                /*const test=document.getElementById('test')
                test.style.width='200px'*/
                console.log(this.$refs)
                this.$refs.test.style.width='200px'
            }
        },
        setup(){console.log(this.$refs())},
        beforeCreate(){console.log(this.$refs)},
        created(){console.log(this.$refs)},
        beforeMount(){console.log(this.$refs)},
        mounted(){this.$refs.ipt.focus()}
    }).mount('#app')
</script>
vue脚手架
vue-cli
安装
#首先,确保已安装node和npm node-v npm -v #其次,确保npm镜像地址是国内的淘宝镜像(有梯子除外) npm config get registry #如果结果是:https://registry.npmirror.com/则说明是淘宝镜像 #否则就输入: npm config set registry https://registry.npmirror.com/ #再次安装vue-cli: npm i -g @vue/cli #查看版本 vue -V
基于vue-cli创建vue3.0项目
vue create hello-world #项目名必须是小写英文字母 Manally select features #手动选择分支 Bable #仅选择Bable (上下切换,空格选择/取消,回车确认) choose aversion for Vue? #3.X where do you? #in dedicate config files 保存到本地文件 Save this as a preset #no,不保存为未来分支 cd hello-world npm run serve #复制网址到浏览器打开即可
基于vue-cli vueUI创建项目
非常不建议使用,丢人现眼。
基于Vite创建Vue项目
基于vite,不需要安装,只要有node和npm即可,但是node版本要在15.0以上
$npm init vue
项目目录
vue-project ----.vscode 配置vscode 没用 ----node_modules ----public ----src 关键,程序员写代码都在这里面 ------assets 项目所需的静态文件,图片,css,等 ------components 组文件夹 ------App.vue 根组件 ------main.js ----.gitignore git上传时,不要的文件配置 ----index.html 页面,仅包含一个#app ----package.json ----package-lock.json ----README.md ----vite.config.js vite配置文件
组件
组件是vue中框架的基石,是最重要的部分。

新建组件
在vite创建项目中创建组件:
在components文件夹下,右键新建.vue文件,就是一个组件
<template>
<p>这里面写标签
    外层的template仅做辅助编译,将来生成的html界面中,不存在template标签</p>
<div>
    在过去,vue2中,这里的根标签必须仅能有一个(即template的亲儿子只能有一个),vue3不做限制
    </div>
</template>
<script>
//这里面写js
    export default {//对外暴露,ES6模块化的语法,等同于node中commonJs中的module.exports
        name: "HelloWorld",
        data() {
            return {
                message: ''
            }
        }
    }
</script>
<style scoped>
/*这里是css
    这里的scoped,通过给被选中的标签生成独一无二的随机属性名来让当前css仅在本组中生效*/
</style>
引入组件
在组建中引入组件
<template>
</template>
<script>
    import HelloWorld from './components/HelloWorld.vue'
    //编辑器可能会把.vue省略掉,vite中一定要加上
    //如果在vue-cli中,可以不加.vue后缀
    export default {
        name: "Header-1",
    }
</script>
<style scoped>
</style>
注册组件
注册组件分两种,分别为注册局部组件和注册全局组件。
注册局部组件(常用)
<template>
</template>
<script>
    import HelloWorld from './components/HelloWorld.vue'
    //编辑器可能会把.vue省略掉,vite中一定要加上
    //如果在vue-cli中,可以不加.vue后缀
    export default {
        name: "Header-1",
        components:{
            //HelloWorld:HelloWorld
            HelloWorld
        }//注册组件
    }
</script>
<style scoped>
</style>
全局注册组件
main.js
import {createApp} from 'vue'
import App from './App.vue'
import Header1 from './components/Header-1.vue'//引入
createApp(App).component('Header1',Header1)//全局注册
    .mount('#app')
使用组件
父组件
<template> <HelloWorld></HelloWorld> <HelloWorld/> <hello-world></hello-world> <hello-world/> </template>
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号