VUE笔记
目录
一、生命周期
- 每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数 。
二、模板语法
- 语法起步1
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<h1>vue语法</h1>
<div id="app">
<p>{{str}}</p> <!--vue语法-->
<p>{{url}}</p> <!--www.baidu.com-->
<p>{{strD(str)}}</p> <!--vue语法测试1vue语法测试2-->
</div>
<script>
var vue1=new Vue({
el: "#app", <!--绑定-->
<!--定义属性-->
data: {
str: "vue语法",
url: "www.baidu.com"
},
<!--用于定义的函数-->
methods:{
strD:function(str1){
return str1+"测试1"+this.str+"测试2";
}
}
})
document.write(vue1.str===data.str) <!--true-->
<!--影响vue1.str值-->
vue1.str="修改过的"
</script>
</body>
</html>
- 语法起步2
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<h1>vue语法</h1>
<div id="app">
<p>{{str}}</p> <!--vue语法-->
<p>{{url}}</p> <!--www.baidu.com-->
</div>
<script type="text/javascript">
var data1={
str: "vue语法",
url: "www.baidu.com"
}
var vue1=new Vue({
el: "#app",
data: data1
})
document.write(vue1.str===data1.str) <!--true-->
<!--影响vue1.str值-->
vue1.str="修改过的"
document.write("<br/>")
document.write("data1的值:"+data1.str) <!--data1的值:修改过的-->
data1.str="修改过的2"
document.write("<br/>")
document.write("vue1的值:"+vue1.str) <!--vue1的值:修改过的2-->
</script>
</body>
</html>
-
模板语法1(v-html)
插入html语法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app3">
<div v-html="data1"></div>
<p>{{data1}}</p>
</div>
<script>
new Vue({
el: "#app3",
data:{
data1: '<h1>菜鸟教程</h1>'
}
})
</script>
</body>
</html>
-
v-bind
对标签内属性赋值时可以使用data中的变量(会动态改变)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app3">
<input type="button" value="按键" v-bind:title="tx" />
</div>
<script>
new Vue({
el:"#app3",
data:{
tx:"v-bind测试"
}
})
</script>
</body>
</html>
-
v-model
用来在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app3">
<input type="button" value="按键" v-bind:title="tx" v-model="tx"/>
</div>
<script>
var a= new Vue({
el:"#app3",
data:{
tx:"v-bind测试",
}
})
</script>
</body>
</html>
控制台修改tx1,v-mode绑定数据也会改变
三、计算属性和侦听器
-
初识计算属性
字符反转
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app6">
<p>{{data1}}</p>
<p>{{re}}</p>
<!-- 字符反转
转反符字 -->
</div>
<script>
var a6=new Vue({
el:"#app6",
data:{
data1:"字符反转"
},
computed:{
re:function(){
return this.data1.split("").reverse().join("")
}
}
})
</script>
</body>
</html>
-
深入学习
计算属性与方法的区别
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app6">
<p>{{data1}}</p>
<p>{{re}}</p>
<!-- 字符反转
转反符字 -->
<p>{{re1()}}</p>
<!--转反符字 -->
</div>
<script>
var a6=new Vue({
el:"#app6",
data:{
data1:"字符反转"
},
computed:{
re:function(){
return this.data1.split("").reverse().join("")
}
},
methods:{
re1:function(){
return this.data1.split("").reverse().join("")
}
}
})
</script>
</body>
</html>
-
再深入
computed 属性默认只有 getter ,不过在需要时你也可以提供一个 setter
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app6">
<p>{{site}}</p>
</div>
<script>
var a6=new Vue({
el:"#app6",
data:{
data1:"字符反转",
data2:{
name:"乌合之众",
url:"www.123.com"
}
},
computed:{
re:function(){
return this.data1.split("").reverse().join("")
},
site:{
get:function(){
return this.data2.name+" "+this.data2.url
},
set:function(newData2){
var str=newData2.split(" ")
this.data2.name=str[0]
this.data2.url=str[str.length-1]
}
}
},
methods:{
re1:function(){
return this.data1.split("").reverse().join("")
}
}
})
a6.site="大众心理 www.abc.com"
document.write('name: ' + a6.data2.name);
document.write('<br>');
document.write('url: ' + a6.data2.url);
</script>
</body>
</html>
<!-- 大众心理 www.abc.com
name: 大众心理
url: www.abc.com -->
四、class与style绑定
- class
<div class="static"
v-bind:class="{ 'active' : isActive, 'text-danger' : hasError }">
</div>
渲染后
<div class="static active text-danger"></div>
- style
<div id="app">
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">菜鸟教程</div>
</div>
渲染后
<div style="color: green; font-size: 30px;">菜鸟教程</div>
五、条件渲染
- v-if
v-if 指令将根据表达式 seen 的值(true 或 false )来决定是否插入 p 元素。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app4">
<p v-if="seen">可以看到我了吧</p>
</div>
<script>
var a1 = new Vue({
el:"#app4",
data:{
seen: true
}
})
</script>
</body>
</html>
- v-else
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app4">
<p v-if="seen">可以看到我了吧</p>
<p v-else>你看的是假的</p> <!--seen为false显示-->
</div>
<script>
var a1 = new Vue({
el:"#app4",
data:{
seen: true
}
})
</script>
</body>
</html>
- v-else-if
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app4">
<p v-if="type=='a'">可以看到的是a</p>
<p v-else-if="type=='b'">可以看到的是b</p>
<p v-else="type=='c'">可以看到的是c</p>
</div>
<script>
var a1 = new Vue({
el:"#app4",
data:{
seen: true,
type: "c"
}
})
</script>
</body>
</html>
- v-show
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app4">
<p v-show="seen">可以看到v-show</p>
</div>
<script>
var a1 = new Vue({
el:"#app4",
data:{
seen: true,
type: "c"
}
})
</script>
</body>
</html>
六、列表渲染
- v-for
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app5">
<ol>
<li v-for="da in data1">
{{da}}
</li>
<li v-for="da2 in data2">
{{da2.name}}
</li>
</ol>
</div>
<script>
var a5=new Vue({
el: "#app5",
data:{
data1:[
"第一级",
"第二级",
"第三级"
],
data2:[
{name:"张三"},
{name:"张四"},
{name:"张五"}
]
}
})
</script>
</body>
</html>
- 迭代对象
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app5">
<ul>
<li v-for="da3 in data3">
{{da3}}
</li>
</ul>
</div>
<script>
var a5=new Vue({
el: "#app5",
data:{
data3:{
name: "黑子",
url: "www.baidu.com",
title: "测试"
}
}
})
</script>
</body>
</html>
黑子
www.baidu.com
测试
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app5">
<ul>
<li v-for="(da3,index,key) in data3">
{{index}}:{{da3}}:{{key}}
</li>
</ul>
<!-- name:黑子:0
url:www.baidu.com:1
title:测试:2 -->
</div>
<script>
var a5=new Vue({
el: "#app5",
data:{
data3:{
name: "黑子",
url: "www.baidu.com",
title: "测试"
}
}
})
</script>
</body>
</html>
- 迭代整数
<ul>
<li v-for="(n,index) in 5">
{{index}}:{{n}}
</li>
</ul>
<!-- 0:1
1:2
2:3
3:4
4:5 -->
七、事件处理
- 简单使用
加一处理
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app7">
<button v-on:click="data2+=1">加一</button>
<p>{{data2}}</p>
</div>
<script>
var a7=new Vue({
el:"#app7",
data:{
data1:"测试",
data2:0
}
})
</script>
</body>
</html>
- 复杂事件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app7">
<button v-on:click="ch">按键</button>
<button v-on:click="ch1('按键1')">按键1</button>
<button v-on:click="data2+=1">加一</button>
<p>{{data2}}</p>
</div>
<script>
var a7=new Vue({
el:"#app7",
data:{
data1:"测试",
data2:0
},
methods:{
ch:function(){
alert("事件测试")
},
ch1:function(str){
alert(str)
}
}
})
</script>
</body>
</html>
八、表单输入绑定
九、组件基础
- 概念图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pyJ7BF91-1631154754003)(C:\Users\MGL\Nutstore.nutstore_MjM4MDA5Mjg5NkBxcS5jb20=\我的坚果云\学习笔记\vue\vue图片\组件1.png)]
- 简单使用
局部组件和全局组件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app8">
<re1></re1>
</div>
<div id="app81">
<!-- 只能在这里用 -->
<re2></re2>
<re3></re3>
</div>
<script>
Vue.component("re1",{
template:"<p>自定义全局组件</p>"
})
//这里上下不能相反
var a8=new Vue({
el:"#app8"
})
var Child={
template:"<p>自定义局部组件</p>"
}
var a81=new Vue({
el:"#app81",
components:{
"re2":Child,
"re3":{
template:"<p>自定义局部组件2</p>"
}
}
})
</script>
</body>
</html>
-
Prop
prop 是子组件用来接受父组件传递过来的数据的一个自定义属性。
父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 "prop
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app9">
<re4 da="传值"></re4>
</div>
<div id="app91">
<re5 v-bind:c1="cc91[0]" v-bind:c2="cc91[1]"></re5>
</div>
<!-- 自定义全局组件|||传值
局部组件||王者||荣耀 -->
<script>
Vue.component("re4",{
props:["da"],
template:"<p>自定义全局组件|\|\|{{da}}</p>"
})
//这里上下不能相反
var a9=new Vue({
el:"#app9"
})
var c91={
props:["c1","c2"],
template:"<p>局部组件||{{c1}}||{{c2}}</p>"
}
var a91=new Vue({
el:"#app91",
components:{
"re5":c91
},
data:{
cc91:["王者","荣耀"]
}
})
</script>
</body>
</html>
<!-- <div id="app">
<ol>
<todo-item v-for="item in sites" v-bind:todo="item"></todo-item>
</ol>
</div>
<script>
Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
})
new Vue({
el: '#app',
data: {
sites: [
{ text: 'Runoob' },
{ text: 'Google' },
{ text: 'Taobao' }
]
}
})
</script> -->
-
自定义事件(v-on)
- 使用
$on(eventName)
监听事件 - 使用
$emit(eventName)
触发事件
- 使用
十、vue环境
-
安装node.js
-
使用淘宝的镜像
npm install -g cnpm –registry=https://registry.npm.taobao.org
- 全局安装 vue cli,vue cli 是一个脚手架工具,用于生成一个基础的vue应用
npm install vue-cli -g
- x
十一、第一个vue程序
-
什么是MVVM
MVVM 源自于经典的MVC (ModI-View-Controller) 模式。MVVM的核心是ViewModel层,负责转换Model中的数据对象来让数据变得更容易管理和使用,其作用如下:
-
该层向上与视图层进行双向数据绑定
-
向下与Model层通过接口请求进行数据交互
-
-
为什么使用MVVM
MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有几大好处:
- 低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的
View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。 - 可复用:你可以把一些视图逻辑放在一个ViewModel里面,让很多View重用这段视图逻辑。
- 独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
- 可测试:界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。
- 低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的
-
Vue 是 MVVM 模式的实现者
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qI08BLdD-1631154754006)(C:\Users\MGL\Nutstore.nutstore_MjM4MDA5Mjg5NkBxcS5jb20=\我的坚果云\学习笔记\vue\vue图片\MVVM2.png)]
- Model : 模型层,在这里表示JavaScript对象
- View : 视图层,在这里表示DOM (HTML操作的元素)
- ViewModel : 连接视图和数据的中间件,Vue.js就是MVVM中的ViewModel层的实现者在MVVM架构中,是不允许数据和视图直接通信的,只能通过ViewModel来通信,而ViewModel就是定义了一个Observer观察者
- ViewModel 能够观察到数据的变化,并对视图对应的内容进行更新
- ViewModel 能够监听到视图的变化,并能够通知数据发生改变
-
g
十二、Axios通信
- s
<script>
export default{
data(){
return{
userId:666,
token:'',
}
},
created(){
this.$axios({
method:'post',
url:'api',
data:this.qs.stringify({ //这里是发送给后台的数据
userId:this.userId,
token:this.token,
})
}).then((response) =>{ //这里使用了ES6的语法
console.log(response) //请求成功返回的数据
}).catch((error) =>
console.log(error) //请求失败返回的数据
})
}
}
</script>
// 为给定 ID 的 user 创建请求
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// 上面的请求也可以这样做
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
unction getUserAccount() {
return axios.get('/user/12345');
}
function getUserPermissions() {
return axios.get('/user/12345/permissions');
}
axios.all([getUserAccount(), getUserPermissions()])
.then(axios.spread(function (acct, perms) {
// 两个请求现在都执行完成
}));
- cc
十三、路由
- Content.vue
<template>
<div>
<h1>内容页</h1>
</div>
</template>
<script>
export default{
name:"Content"
}
</script>
<style>
</style>
- Main.vue
<template>
<div>
<h1>首页</h1>
</div>
</template>
<script>
// 导出
export default{
name:"Main"
}
</script>
<style>
</style>
- router(新建)/index.js
import Vue from "vue"
import VueRouter from "vue-router"
//导入vue
import Content from "../components/Content.vue"
import Main from "../components/Main.vue"
//使用路由
Vue.use(VueRouter)
export default new VueRouter({
routes:[
{
// 路径
path:"/content",
name:"c",
// 跳转的组件
component: Content
},
{
path:"/main",
name:"m",
component: Main
}
]
})
- App.vue
<template>
<div id="app">
<router-link to="/content">内容页</router-link>
<router-link to="/main">首页</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
-
成果
-
路由嵌套
test可以在content使用
在其他地方使用的话就会跳到content下
import Vue from "vue"
import VueRouter from "vue-router"
//导入vue
import Content from "../components/Content.vue"
import Main from "../components/Main.vue"
import Test from "../components/test.vue"
//使用路由
Vue.use(VueRouter)
export default new VueRouter({
routes:[
{
// 路径
path:"/content",
name:"c",
// 跳转的组件
component: Content,
// 路由嵌套
children:[
{
path:"/user/test",
name:"t",
component: Test
}
]
},
{
path:"/main",
name:"m",
component: Main
}
]
})
十四、参数传递与重定向
-
s
<template> <div> <h1>内容页</h1> <router-link >test连接</router-link> <router-view></router-view> <div> <p>{{id}}</p> <br /> <p>{{name1}}</p> <p>{{$route.params.id}}</p> </div> </div> </template> <script> // 导出 export default{ props:["id","name1"], name:"Content" } </script> <style> </style>
import Vue from "vue"
import VueRouter from "vue-router"
//导入vue
import Content from "../components/Content.vue"
import Main from "../components/Main.vue"
import Test from "../components/test.vue"
//使用路由
Vue.use(VueRouter)
export default new VueRouter({
routes:[
{
// 路径
path:"/content:id/:name1",
name:"c",
// 跳转的组件
component: Content,
props:true,
// 路由嵌套
children:[
{
path:"/user/test",
name:"t",
component: Test
}
]
},
{
path:"/main",
name:"m",
component: Main
}
]
})
- 重定向
{
//path: "/goHome",
redirect:"/main"
}
十五、插槽(slot)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app11">
<!-- h4>书籍</h4>
<ul>
<li>java</li>
<li>linux</li>
<li>c++</li>
</ul> -->
<todo>
<title-do slot="title-do" v-bind:title="title"></title-do>
<content-do slot="content-do" v-for="item in content" v-bind:item="item"></content-do>
</todo>
<!-- 书籍信息
java
pyton
linux -->
</div>
<script>
Vue.component("todo",{
template:'<div>\
<slot name="title-do"></slot>\
<ul>\
<slot name="content-do"></slot>\
</ul>\
</div>'
})
Vue.component("title-do",{
props:["title"],
template:"<h4>{{title}}</h4>"
})
Vue.component("content-do",{
props:["item"],
template:"<li>{{item}}</li>"
})
new Vue({
el:"#app11",
data:{
title: "书籍信息",
content:["java","pyton","linux"]
}
})
</script>
</body>
</html>