vue
Posted lizeqian1994
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue相关的知识,希望对你有一定的参考价值。
""" 1.什么是Vue? js框架(前端框架) 渐进式框架:可以控制html中一个标签,可以控制一块标签,可以控制一个页面标签,可以控制整个项目 --Vue采用的是原生html、css、js(es6语法) --js大部分使用es6语法,最终都会被解析打包成es5语法交给浏览器来执行. --为什么不使用es5语法? --es6语法比es5语法支持的会多一些,并且简洁规范开发效率高 2.为什么学习Vue? 前端三大框架:Angular(谷歌) React(facebook) Vue(一手文档全是中文,吸取了前两个的优点) 项目设计模式:MVVM MTV MVC Django采用的是MTV(M数据层,T页面层,V业务逻辑层) vue采用的是MVVM MVVM与MTV都是从MVC(M数据层,V视图层,C业务逻辑层)模式演变过来的 可以完全脱离服务器端,以前端代码复用的方式渲染整个页面:组件化开发 3.特点 单页面web应用 数据驱动 数据的双向绑定 虚拟DOM(文档对象模型) """
<div id=‘app‘> {{}} </div> <!--使用--> //导入Vue框架 <script src="js/vue.js"></script> <script> //创建vue对象 new Vue({ //挂到指定页面标签 el:‘#app‘ }) </script> // 一个实例控制一个挂载点 // 一个页面中可以出现多个实例对应多个挂载点 // 实例只操作挂载点内部内容 //规范挂载点使用id来标识
<div id=‘app‘> {{ msg }} </div> <script> var app = new Vue({ el: ‘#app‘, data: { msg: ‘数据‘, } }) console.log(app.$data.msg); console.log(app.msg); </script> <!-- data为插件表达式中的变量提供数据 --> <!-- data中的数据可以通过Vue实例直接或间接访问-->
//给事件指令提供具体的实现方法
<div id="app"> <input type="text" v-model="firstName"> <input type="text" v-model="lastName"> <div> {{ name }} </div> </div> <script> new Vue({ el: "#app", data: { firstName: "", lastName: "", }, computed: { name: function() { // this代表该vue实例 if(this.firstName || this.lastName){ return this.firstName + this.lastName; } return "姓名" } } }) </script> 一个属性值依赖于多个属性值,该属性不要赋初值,我们可以给其绑定一个方法,从这个方法的返回值中拿值,上述操作完成了对姓名的替换 特殊点: data绑定的属性值是固定的, computed绑定的属性值是动态的(函数的返回值)
<div id="app"> <p> <input type="text" v-model="name"> </p> <p> <input type="text" v-model="firstName"> </p> <p> <input type="text" v-model="lastName"> </p> </div> <script> //多个变量依赖于一个变量,都要赋初值 new Vue({ el: ‘#app‘, data: { name: "", fistName: "", lastName: "", }, watch: { //为name该属性绑定了一个监听事件 //name属性值一旦改变,绑定的监听事件就会被调用 name: function () { // 逻辑根据需求而定 f_l = this.name.split(‘ ‘); this.firstName = f_l[0]; this.lastName = f_l[1]; } } }) </script>
<div id=‘app‘> ${ msg } </div> <script> new Vue({ el: ‘#app‘, data: { msg: ‘message‘ }, delimiters: [‘${‘, ‘}‘] }) </script> 总结:逗号左边‘${‘和右边‘}‘与被渲染的数据左边以及右边一致才可以解析,否则不能解析
vue指令: 就是标签的全局属性,但是这些属性是以 "v-" 开头
只要被vue能识别的指令绑定,指令后面的变量不代表字符串,需要在vue对象中初始化
插值表达式:{{ msg }} 用{{}}包裹vue的变量 v-text v-html v-once:本身通过插值表达式来渲染数据,标签中的内容一旦确定就无法改变 <p v-text="txt"></p> <p v-html="hml"></p> <script> new Vue({ el: ‘#app‘, data: { txt: "vue的text指令", hml: "<b>vue的html指令</b>", } }); </script>
<style> [v-cloak] { display: none; } </style> <div id="app" v-cloak> {{ msg }} </div> <script src="js/vue.js"></script> <script> new Vue({ el: "#app", data: { msg: "message" } }) </script> <!-- 避免页面闪烁-->
事件指令: v-on:事件名 简写 @事件名 整体语法: v-on:事件名="事件绑定的变量名" 事件绑定的变量名 由methods来提供具体的方法实现 <body> <div id="app"> <p v-on:click="action" v-text="msg"></p> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el:‘#app‘, data:{ msg:‘点击事件‘, }, methods:{ action:function () { alert(‘你再点!‘) } } }) </script>
属性指令: v-bind:属性名 简写 :属性名 整体语法: v-bind:属性名="属性绑定的变量名" 属性绑定的变量名 由data来提供具体的方法实现 <!--href属性--> <body> <div id="app"> <a v-bind:href=" ‘/static/article/‘ + aid">前往第{{aid}}篇文章</a> <button @click="btnClick" >获取第100篇文章的id</button> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el:‘#app‘, data:{ aid:10, }, methods:{ btnClick:function () { this.aid=100 } } }) </script> <!--样式属性--> <body> <div id="app"> <p :style="a"></p> <p @click="btnClick" :style="{width:‘200px‘,height:h ,backgroundColor:‘red‘}">变高</p> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el:‘#app‘, data:{ a:{ width:‘200px‘, height:‘200px‘, backgroundColor:‘red‘ }, h:‘200px‘ }, methods:{ btnClick:function () { this.h = ‘300px‘ } } }) </script> <!--class属性--> <p v-bind:class="c1"></p> <!--[]语法 多类名--> <p v-bind:class="[c2, c3]"></p> <!--{}语法 c4为类命,后面的值可以为true | false,代表c4是否起作用--> <p v-bind:class="{c4: true|false|var}"></p> <p v-bind:class="[{c5: true}, {c6: flase}]"></p>
表单指令要绑定表单元素的value:v-model:value=‘变量名‘ 只对value进行绑定 可以简写成v-model=‘变量名‘ <div id="app"> <!-- v-model针对于表单元素 --> <form action="" method="get"> <!-- 1、双向绑定:服务于文本输入框 --> <!-- v-model存储的值为输入框的value值 --> <div> <input type="text" name="usr" v-model="in_val"> <input type="password" name="ps" v-model="in_val" > <textarea name="info" v-model="in_val"></textarea> </div> <!-- 2、单选框 --> <div> <!-- 单选框是以name进行分组,同组中只能发生单选 --> <!-- v-model存储的值为单选框的value值 --> 男:<input type="radio" name="sex" value="男" v-model="ra_val"> 女:<input type="radio" name="sex" value="女" v-model="ra_val"> {{ ra_val }} </div> <!-- 3、单一复选框 --> <!-- v-model存储的值为true|false --> <!-- 或者为自定义替换的值 --> <div> <input type="checkbox" v-model=‘sin_val‘ true-value="选中" false-value="未选中" /> {{ sin_val }} </div> <!-- 4、多复选框 --> <!-- v-model存储的值为存储值多复选框value的数组 --> <div> <input type="checkbox" value="喜好男的" name="cless" v-model=‘more_val‘ /> <input type="checkbox" value="喜好女的" name="cless" v-model=‘more_val‘ /> <input type="checkbox" value="不挑" name="cless" v-model=‘more_val‘ /> {{ more_val }} </div> </form> </div> <script type="text/javascript"> new Vue({ el: ‘#app‘, data: { in_val: ‘‘, // 默认值可以决定单选框默认选项 ra_val: ‘男‘, // 默认值为true,单一复选框为选中,反之false为不选中 sin_val: ‘‘, // 数组中存在的值对应的复选框默认为选中状态 more_val: [‘喜好女的‘,‘不挑‘] } }) </script>
<div id="app"> <button @click="toggle">显隐切换</button> <!-- v-if --> <div class="box r" v-if="isShow"></div> <!-- v-show --> <div class="box o" v-show="isShow"></div> <!-- 1.条件渲染的值为true|false --> <!-- 2.true代表标签显示方式渲染 --> <!-- 3.false v-if不渲染到页面,v-show以display:none渲染到页面,但也不会显示 --> <!-- v-if v-else-if v-else 案例 --> <!-- 事件绑定函数, 可以加括号(), 一旦加()就代表要传入参数, 系统就不再传入事件参数 --> <!--如果想传入事件参数, 1:不加括号 2.加括号需用$event--> <ul> <li @mouseover="changeWrap(0)">red</li> <li @mouseover="changeWrap(1)">green</li> <li @mouseover="changeWrap(2)">blue</li> </ul> <!-- red页面逻辑结构 --> <div class="wrap red" v-if="tag == 0" key="0">...</div> <!-- green页面逻辑结构 --> <div class="wrap green" v-else-if="tag == 1" key="1">...</div> <!-- blue页面逻辑结构 --> <div class="wrap blue" v-else key="2">...</div> <!-- v-if相关分支操作,在未显示情况下,是不会被渲染到页面中 --> <!-- 通过key全局属性操作后,渲染过的分支会建立key对应的缓存,提高下一次渲染速度 --> <!-- v-show 案例 --> <ul> <li @mouseover="changeMain(0)">red</li> <li @mouseover="changeMain(1)">green</li> <li @mouseover="changeMain(2)">blue</li> </ul> <!-- red页面逻辑结构 --> <div class="main red" v-show="whoShow(0)">...</div> <!-- green页面逻辑结构 --> <div class="main green" v-show="whoShow(1)">...</div> <!-- blue页面逻辑结构 --> <div class="main blue" v-show="whoShow(2)">...</div> </div> <script type="text/javascript"> new Vue({ el: "#app", data: { isShow: false, tag: 0, flag: 0 }, methods: { toggle () { this.isShow = !this.isShow; }, changeWrap (num) { this.tag = num; }, changeMain (num) { // this.flag num this.flag = num; }, whoShow (num) { // this.flag num return this.flag == num; } } }) </script>
<div id="app"> <h1>{{ msg }}</h1> <!-- v-for="item in items" --> <!-- 遍历的对象: 数组[] 对象(字典){} --> <ul> <li>{{ list[0] }}</li> <li>{{ list[1] }}</li> <li>{{ list[2] }}</li> <li>{{ list[3] }}</li> <li>{{ list[4] }}</li> </ul> <!-- n为遍历的元素值 --> <ul> <li v-for="n in list">{{ n }}</li> </ul> <!-- 一般列表渲染需要建立缓存 --> <!--全局属性key的缓存机制,一定要保证整个项目中key值得唯一性--> <!-- 列表渲染是循环,需要赋值变量给key,使用key需要v-bind:处理 --> <!-- v-for变量数组[]时,接收两个值时,第一个为元素值,第二个为元素索引 --> <ul> <li v-for="(n, i) in list" :key="i">value:{{ n }} | index: {{ i }}</li> </ul> <ul> <li>{{ dic[‘name‘] }}</li> <li>{{ dic.age }}</li> <li>{{ dic.gender }}</li> </ul> <!-- v-for变量对象{}时,接收三个值时,第一个为元素值,第二个为元素键,第三个为元素索引 --> <ul> <li v-for="(v, k, i) in dic" :key="k">value:{{ v }} | key:{{ k }} | index: {{ i }}</li> </ul> <!-- 遍历的嵌套 --> <div v-for="(person, index) in persons" :key="index" style="height: 21px;"> <div v-for="(v, k) in person" :key="k" style="float: left;">{{ k }} : {{ v }}</div> </div> </div> <script> new Vue({ el: "#app", data: { msg: "循环指令", list: [1, 2, 3, 4, 5], dic: { name: ‘zero‘, age: 88888, gender: ‘god‘ }, persons: [ {name: "zero", age: 8}, {name: "egon", age: 78}, {name: "liuXX", age: 77}, {name: "yXX", age: 38} ] } }) </script>
<div id="app"> <div> <input type="text" v-model="val"> <button type="button" @click="submitMsg">留言</button> </div> <ul> <li v-for="(v, i) in list" :key="i" @click="removeMsg(i)">{{ v }}</li> </ul> {{ list }} </div> <script type="text/javascript"> new Vue({ el: "#app", data: { val: "", list: [] }, methods: { submitMsg () { if (this.val) { //push:在后面添加 unshift:在前面添加 pop:从尾部删除 shift:从头部删除 this.list.push(this.val); //往list里面加值,在后面添加 this.val = "" } }, removeMsg(index) { //删除指定位置的参数 this.list.splice(index, 1) } } }) </script>
表示一个vue实例从创建到销毁的这个过程,将这个过程的一些时间节点赋予了对应的钩子函数
钩子函数: 满足特点条件被回调的方法
new Vue({
el: "#app",
data: {
msg: "message"
},
beforeCreate () {
console.log("实例刚刚创建");
console.log(this.msg);
},
created () {
console.log("实例创建成功, data, methods已拥有");
console.log(this.msg);
},
mounted () {
console.log("页面已被vue实例渲染, data, methods已更新");
}
// 拿到需求 => 确定钩子函数 => 解决需求的逻辑代码块
})
// 全局属性key的缓存机制,一定要保证整个项目中key值得唯一性
// vue完成的是单页面应用,页面更换的是组件,不是页面刷新
1.每一个组件都是一个vue实例,可以有多种创建组件的方式(根组件,局部组件,全局组件)
2.每个组件均具有自身的模板template,根组件也可以有template模块,但是不建议写,根组件的模板就是挂载点
3.每个组件模板只能拥有一个根标签,每个组件的template只能解析其模块下的第一个根标签.
4.子组件的数据具有作用域(用函数方法返回字典形式数据),以达到组件的复用
<div id="app"> <h1>{{ msg }}</h1> </div> <script type="text/javascript"> // 通过new Vue创建的实例就是根组件(实例与组件一一对应,一个实例就是一个组件) // 每个组件组件均拥有模板,template var app = new Vue({ // 根组件的模板就是挂载点 el: "#app", data : { msg: "根组件" }, // 模板: 由""包裹的html代码块,出现在组件的内部,赋值给组件的$template变量 // 显式书写模块,就会替换挂载点,但根组件必须拥有挂载点 template: "<div>显式模板</div>" }) // app.$template </script> 总结:1.根组件可以拥有template模块,但是一般不使用,根组件的模块直接使用挂载点el. 2.在template中书写代码块 3.template就是一个组件的实体代码块,在template中书写的代码块会直接替换掉挂载点. 4.每个组件的template模板中只能解析第一个根标签.
<div id="app"> <!--使用局部组件--> <local-tag></local-tag> </div> <script src="js/vue.js"></script> <script> var localTag={ //子组件必须拥有自身template template:` <div id="localTag"> <h2>我是局部组件</h2> <p style="color: red">我是局部组件的文本解释</p> <p @click="btnClick">我被点击了{{num}}下</p> </div> `, //子组件的data为方法的返回值字典 data:function () { return{ num:0 } }, methods:{ btnClick:function () { this.num++ } } }; //如果想在页面中看到子组件,需要在根组件中使用该子组件 //如果根组件要使用局部组件,需要提前注册 new Vue({ el:‘#app‘, data:{ }, //在根组件中注册局部组件 components:{ //localTag:localTag //‘localTag‘:localTag //‘local-tag‘:localTag localTag } }) </script> 总结:1.子组件(局部组件和全局组件)拥有自身的template 2.子组件的数据具有作用域,其为方法的返回值字典 3.要想在页面中看到子组件必须使用该组件(在挂载点中使用) 如果要使用的是局部组件,必须提前注册,局部组件在挂载点中的引用直接使用<local-tag></local-tag> 但是在根组件中注册的可以用多种方式:①localTag:localTag ②‘localTag‘:localTag ③localTag ④‘local-tag‘:localTag 4.组件不能绑定系统事件(click,dblclick,mouseenter等),但可以绑定自定义事件
<div id="app"> <!--使用全局组件--> <global-tag></global-tag> </div> <script src="js/vue.js"></script> <script> Vue.component(‘globalTag‘,{ template:` <div> <h2>我是全局组件</h2> <p style="color: red">我是全局组件的文本解释</p> <p @click="btnClick">我被点击了{{num}}下</p> </div> `, data:function () { return{ num:0 } }, methods:{ btnClick:function () { this.num++ } } }); new Vue({ el:‘#app‘, data:{ }, }) </script> 总结:1.全局组件与局部组件的不同点:全局组件不用注册 2.全局组价用Vue.conponebt()来声明定义,两个参数 第一个组件名,第二个组件内容,写在template模块中
<div id="app"> <global-tag :sup_data1=‘data1‘ :sup_data2=‘data2‘></global-tag> </div> <script type="text/javascript"> Vue.component(‘global-tag‘, { props:[‘sup_data1‘, ‘sup_data2‘], template: ‘<div>{{ sup_data1 }} {{ sup_data2 }}</div>‘ }) new Vue({ el: ‘#app‘, data: { data1: ‘数据1‘, data2: ‘数据2‘ } }) </script> 总结:父组件传送给子组件 步骤:1.将父组件数据绑定给属性 2.在子组件中通过props:[自定义属性1属性名,自定义属性2属性名,...]获取父组件的数据.
<div id="app"> <global-tag @send_action=‘receiveInfo‘></global-tag> </div> <script type="text/javascript"> Vue.component(‘global-tag‘, { data:function { return { sub_data1: "数据1", sub_data2: ‘数据2‘ } }, template: ‘<div @click="sendInfo">发送</div>‘, methods: { sendInfo:function () { this.$emit(‘send_action‘, this.sub_data1, this.sub_data2) } } }) new Vue({ el: ‘#app‘, methods: { receiveInfo:function (v1, v2) { console.log(v1, v2) } } }) </script> 总结:子组件传送给父组件 步骤:1.在子组件中定义一个点击事件,点击以后通过自定义发送事件将数据发送出去 2.自定义发送事件 this.$emit(自定义事件名,子组件中的数据) 3.在父组件中给自定义发送事件绑定一个方法,在父组件methods中调用该方法就会得到子组件中的数据
<div id="app"> <div> <input type="text" v-model="val"> <button type="button" @click="submitMsg">提交</button> </div> <ul> <!-- <li v-for="(v, i) in list" :key="i" @click="removeMsg(i)">{{ v }}</li> --> <todo-list v-for="(v, i) in list" :key="i" :v="v" :i="i" @delect_action="delect_action"></todo-list> </ul> </div> <script type="text/javascript"> Vue.component("todo-list", { template: "<li @click=‘delect_action‘><span>第{{ i + 1 }}条: </span><span>{{ v }}</span></li>", props: [‘v‘, ‘i‘], methods: { delect_action () { this.$emit("delect_action", this.i) } } }) new Vue({ el: "#app", data: { val: "", list: [] }, methods: { submitMsg () { // 往list中添加input框中的value if (this.val) { this.list.push(this.val); this.val = "" } }, delect_action(index) { this.list.splice(index, 1) } } }) </script>
官网下载安装包,傻瓜式安装:https://nodejs.org/zh-cn/
如果报错2502或2503
1、以管理员身份运行cmd命令 (Win + X, A)
2.在该安装包所正的目录下输入:msiexec /package + 安装包名 进行安装
可以在cmd中输入node --version查看版本信息
安装cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
安装脚手架
cnpm install -g @vue/cli
清空缓存处理
npm cache clean --force
vue create 项目名
// 要提前进入目标目录(项目应该创建在哪个目录下)
// 选择自定义方式创建项目(Manually select features)
// 选取 Babel,Router, Vuex,inter / Formatter插件
// Use history mode for router? Y
// Save this as a preset for future projects? N
启动/停止项目
npm run serve / ctrl+c
// 要提前进入项目根目录
打包项目
npm run build
// 要在项目根目录下进行打包操作
dist: 打包的项目目录(打包后会生成)
node_modules: 项目依赖
public: 共用资源
src: 项目目标,书写代码的地方
-- assets:资源
-- components:组件
-- views:视图组件
-- App.vue:根组件
-- main.js: 入口js
-- router.js: 路由文件
-- store.js: 状态库文件
vue.config.js: 项目配置文件(没有可以自己新建)
配置文件:vue.config.js
module.exports={
devServer: {
port: 8888
}
}
// 修改端口,选做
main.js
new Vue({
el: "#app",
router: router,
store: store,
render: function (h) {
return h(App)
}
})
.vue文件
<template> <!-- 模板区域 --> </template> <script> // 逻辑代码区域 // 该语法和script绑定出现 export default { } </script> <style scoped> /* 样式区域 */ /* scoped表示这里的样式只适用于组件内部, scoped与style绑定出现 */ </style>
{ path: ‘/‘, name: ‘home‘, // 路由的重定向 redirect: ‘/home‘ } { // 一级路由, 在根组件中被渲染, 替换根组件的<router-view/>标签 path: ‘/one-view‘, name: ‘one‘, component: () => import(‘./views/OneView.vue‘) } { // 多级路由, 在根组件中被渲染, 替换根组件的<router-view/>标签 path: ‘/one-view/one-detail‘, component: () => import(‘./views/OneDetail.vue‘), // 子路由, 在所属路由指向的组件中被渲染, 替换该组件(OneDetail)的<router-view/>标签 children: [{ path: ‘show‘, component: () => import(‘./components/OneShow.vue‘) }] }
<!-- router-link渲染为a标签 --> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> | <router-link :to="{name: ‘one‘}">One</router-link> | <!-- 为路由渲染的组件占位 --> <router-view />
a.router-link-exact-active {
color: #42b983;
}
// router的逻辑转跳
this.$router.push(‘/one-view‘)
// router采用history方式访问上一级
this.$router.go(-1)
vuex
// 在任何一个组件中,均可以通过this.$store.state.msg访问msg的数据
// state永远只能拥有一种状态值
state: {
msg: "状态管理器"
},
// 让state拥有多个状态值
mutations: {
// 在一个一个组件中,均可以通过this.$store.commit(‘setMsg‘, new_msg)来修改state中的msg
setMsg(state, new_msg) {
state.msg = new_msg
}
},
// 让mutations拥有多个状态值
actions: {
}
vue-cookie
// 安装cookie的命令
// cmd在自己创建的项目下安装
// npm install vue-cookie --save
// 为项目配置全局vue-cookie
import VueCookie from ‘vue-cookie‘
// 将插件设置给Vue原型,作为全局的属性,在任何地方都可以通过this.$cookie进行访问
Vue.prototype.$cookie = VueCookie
// 持久化存储val的值到cookie中
this.$cookie.set(‘val‘, this.val)
// 获取cookie中val字段值
this.$cookie.get(‘val‘)
axios
// 安装 axios(ajax)的命令
// cmd在自己创建的项目下安装
// npm install axios--save
//报错:Not Found: [email protected]
•删除node_modules整个文件夹
•安装axios npm install --save axios
•安装其它项目依赖包,执行npm install
// 为项目配置全局axios
import Axios from ‘axios‘
Vue.prototype.$ajax = Axios
let _this = this
this.$ajax({
method: ‘post‘,
url: ‘http://127.0.0.1:5000/loginAction‘,
params: {
usr: this.usr,
ps: this.ps
}
}).then(function(res) {
// this代表的是回调then这个方法的调用者(axios插件),也就是发生了this的重指向
// 要更新页面的title变量,title属于vue实例
// res为回调的对象,该对象的data属性就是后台返回的数据
_this.title = res.data
}).catch(function(err) {
window.console.log(err)
})
# 用pycharm启动该文件模拟后台 from flask import Flask, request, render_template from flask_cors import CORS app = Flask(__name__) CORS(app, supports_credentials=True) @app.route(‘/‘) def index(): return "<h1>主页</h1>" @app.route(‘/loginAction‘, methods=[‘GET‘, ‘POST‘]) def test_action(): # print(request.args) # print(request.form) # print(request.values) usr = request.args[‘usr‘] ps = request.args[‘ps‘] if usr != ‘abc‘ or ps != ‘123‘: return ‘login failed‘ return ‘login success‘ if __name__ == ‘__main__‘: app.run()
以上是关于vue的主要内容,如果未能解决你的问题,请参考以下文章