赞
踩
M:Model模型层,包括数据和一些基本操作。
V:Viem视图层,视图页面渲染结果。
VM:Viem-Model,模型与视图的双向操作,无需开发人员干涉。
在MVVM之前,开发人员从后端获取需要的数据模型,然后要通过DOM操作Model渲染到View中。而后当用户操作视图,我们还需要通过DOM获取View中的数据,然后同步到Model中。
MVVM中的VM要做的事情就是把DOM操作完全封装起来,开发人员不用再关心Model和View之间是如何互相影响的。
MVVM支持双向绑定,意思就是当M层数据进行修改时,VM层会监测到变化,并且通知V层进行相应的修改,反之修改V层则会通知M层数据进行修改,以此也实现了视图与模型层的相互解耦;
Vue : 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
npm init -y //初始化项目
npm install vue //安装vue
引入vue
<script src="./node_modules/vue/dist/vue.js"></script>
//1、vue声明式渲染 let vm = new Vue({ el: "#app",//绑定元素 data: { //封装数据 name: "张三", num: 1 }, methods:{ //封装方法 cancle(){ this.num -- ; }, hello(){ return "1" } } }); //2、双向绑定,模型变化,视图变化。反之亦然。 //3、事件处理 //v-xx:指令 //1、创建vue实例,关联页面的模板,将自己的数据(data)渲染到关联的模板,响应式的 //2、指令来简化对dom的一些操作。 //3、声明方法来做更复杂的操作。methods里面可以封装方法。
差值表达式
1.格式:{{ }}
只能用在标签体中
可以直接获取Vue实例中定义的数据或函数;
该表达式支持js语法,可以使用js内置函数(必须有返回值例如:let a=1+1不能使用差值表达式);
2.差值闪烁:使用{{}}方式在网速较慢时会出现的在数据未加载完成时,页面会显示原始的{{value}}加载完才显示正确数据我们称为差值闪烁
v-text、v-html指令(单向绑定)
v-text绑定文本 v-html绑定html
使用{{name}} 就是v-text的缩写
注意:如果标签没有text属性该绑定失效 比如你在一个文本框上使用v-text是没有效果的
<div id="app"> {{msg}} {{1+1}} {{hello()}}<br/> <span v-html="msg"></span> <br/> <span v-text="msg"></span> </div> <script> new Vue({ el:"#app", data:{ msg:"<h1>Hello</h1>", link:"http://www.baidu.com" }, methods:{ hello(){ return "World" } } }) </script>
<!-- 给html标签的属性绑定 --> <div id="app"> <a v-bind:href="link">gogogo</a> <!-- vue对class,style进行增强 当isActive为true时span标签的calss属性中才有active, style的属性与color1双向绑定--> <span v-bind:class="{active:isActive,'text-danger':hasError}" :style="{color: color1,fontSize: size}">你好</span> </div> <script> let vm = new Vue({ el:"#app", data:{ link: "http://www.baidu.com", isActive:true, hasError:true, color1:'red', size:'36px' } }) </script>
<!-- 表单项,自定义组件 --> <div id="app"> 精通的语言: <input type="checkbox" v-model="language" value="Java"> java<br/> <input type="checkbox" v-model="language" value="PHP"> PHP<br/> <input type="checkbox" v-model="language" value="Python"> Python<br/> 选中了 {{language.join(",")}} </div> <script> let vm = new Vue({ el:"#app", data:{ language: [] } }) </script>
<div id="app"> <!--事件中直接写js片段--> <button v-on:click="num++">点赞</button> <!--事件指定一个回调函数,必须是Vue实例中定义的函数;v-on可以直接简写成@--> <button @click="cancle">取消</button> <h1>有{{num}}个赞</h1> <!-- 事件修饰符 :--> <div style="border: 1px solid red;padding: 20px;" v-on:click.once="hello"> 大div <!-- @click.stop阻止事件冒泡到父元素(当点击小div时会弹框两次,使用该修饰符会阻止冒泡,只弹框一次) --> <div style="border: 1px solid blue;padding: 20px;" @click.stop="hello"> 小div <br /> <!-- @click.prevent.stop阻止默认事件发生并调用hello函数 --> <a href="http://www.baidu.com" @click.prevent.stop="hello">去百度</a> </div> </div> <!-- 按键修饰符:v-on:keyup.up="num+=2"每按↑键一次num就会加2, @click.ctrl="num=10"按ctrl键num变为10 --> <input type="text" v-model="num" v-on:keyup.up="num+=2" @keyup.down="num-=2" @click.ctrl="num=10"><br /> 提示: </div> <script src="../node_modules/vue/dist/vue.js"></script> <script> new Vue({ el:"#app", data:{ num: 1 }, methods:{ cancle(){ this.num--; }, hello(){ alert("点击了") } } }) </script>
<div id="app"> <ul> <li v-for="(user,index) in users" :key="user.name" v-if="user.gender == '女'"> <!-- 1、显示user信息:v-for="item in items" --> 当前索引:{{index}} ==> {{user.name}} ==> {{user.gender}} ==>{{user.age}} <br> <!-- 2、获取数组下标:v-for="(item,index) in items" --> <!-- 3、遍历对象: v-for="value in object" v-for="(value,key) in object" v-for="(value,key,index) in object" --> 对象信息: <span v-for="(v,k,i) in user">{{k}}=={{v}}=={{i}};</span> </li> </ul> <ul> <!-- 4、遍历的时候都加上:key(被遍历的元素中的唯一标识如user.id)来区分不同数据,提高vue渲染效率 下例使用索引区分, --> <li v-for="(num,index) in nums" :key="index"></li> </ul> </div> <script> let app = new Vue({ el: "#app", data: { users: [{ name: '柳岩', gender: '女', age: 21 }, { name: '张三', gender: '男', age: 18 }, { name: '范冰冰', gender: '女', age: 24 }, { name: '刘亦菲', gender: '女', age: 18 }, { name: '古力娜扎', gender: '女', age: 25 }], nums: [1,2,3,4,4] }, }) </script>
<!-- v-if,顾名思义,条件判断。当得到结果为true时,所在的元素才会被渲染。 v-show,当得到结果为true时,所在的元素才会被显示,。 --> <div id="app"> <button v-on:click="show = !show">点我呀</button> <!-- 1、使用v-if显示 ,标签直接消失--> <h1 v-if="show">if=看到我....</h1> <!-- 2、使用v-show显示,本质是改变display属性为none隐藏 --> <h1 v-show="show">show=看到我</h1> </div> <script> let app = new Vue({ el: "#app", data: { show: true } }) </script>
<div id="app"> <button v-on:click="random=Math.random()">点我呀</button> <span>{{random}}</span> <h1 v-if="random>=0.75"> 看到我啦?! >= 0.75 </h1> <h1 v-else-if="random>=0.5"> 看到我啦?! >= 0.5 </h1> <h1 v-else-if="random>=0.2"> 看到我啦?! >= 0.2 </h1> <h1 v-else> 看到我啦?! < 0.2 </h1> </div> <script> let app = new Vue({ el: "#app", data: { random: 1 } }) </script>
<div id="app"> <ul> <li>西游记; 价格:{{xyjPrice}},数量:<input type="number" v-model="xyjNum"> </li> <li>水浒传; 价格:{{shzPrice}},数量:<input type="number" v-model="shzNum"> </li> <li>总价:{{totalPrice}}</li> {{msg}} </ul> </div> <script src="../node_modules/vue/dist/vue.js"></script> <script> new Vue({ el: "#app", data: { xyjPrice: 99.98, shzPrice: 98.00, xyjNum: 1, shzNum: 1, msg: "" }, //某些结果是基于之前数据实时计算出来的, //我们可以利用计算属性computed来完成,当computed中使用到的任意属性发生变化都会重新计算。 computed: { totalPrice(){ return this.xyjPrice*this.xyjNum + this.shzPrice*this.shzNum } }, // watch可以让我们监控一个值的变化。 //放在 data 中的对象,一旦发生改变就会执行相应的操作,当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。 watch: { xyjNum(newVal,oldVal){ if(newVal>=3){ this.msg = "库存超出限制"; this.xyjNum = 3 }else{ this.msg = ""; } } }, }) </script>
<!-- 过滤器常用来处理文本格式化的操作。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 --> <div id="app"> <ul> <li v-for="user in userList"> {{user.id}} ==> {{user.name}} ==> {{user.gender == 1?"男":"女"}} ==> {{user.gender | genderFilter}} ==> {{user.gender | gFilter}} </li> </ul> </div> <script> // 全局过滤器:可以在任何vue实例中使用 Vue.filter("gFilter", function (val) { if (val == 1) { return "男~~~"; } else { return "女~~~"; } }) let vm = new Vue({ el: "#app", data: { userList: [ { id: 1, name: 'jacky', gender: 1 }, { id: 2, name: 'peter', gender: 0 } ] }, filters: { // filters 定义局部过滤器,只可以在当前vue实例中使用(局部的只能在当前Vue实例中使用) genderFilter(val) { if (val == 1) { return "男"; } else { return "女"; } } } }) </script>
在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航。
但如果每个页面都独自开发,是很废程序员的。多以我们会把页面的不同部分拆分成独立的组件,然后再在不同页面就可以共享这些组件,避免重复开发。
<div id="app"> <button v-on:click="count++">我被点击了 {{count}} 次</button> <!-- 全局组件引入 --> <counter></counter> <!-- 局部组件引入 --> <button-counter></button-counter> </div> <script> //1、全局声明注册一个组件 Vue.component("counter", { template: `<button v-on:click="count++">我被点击了 {{count}} 次</button>`, data() { return { count: 1 } } }); //2、局部声明一个组件 const buttonCounter = { template: `<button v-on:click="count++">我被点击了 {{count}} 次~~~</button>`, data() { return { count: 1 } } }; new Vue({ el: "#app", data: { count: 1 }, // 将局部声明的组件注册到vue实例中 components: { 'button-counter': buttonCounter } }) </script>
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
<div id="app"> <span id="num">{{num}}</span> <button @click="num++">赞!</button> <h2>{{name}},有{{num}}个人点赞</h2> </div> <script> let app = new Vue({ el: "#app", data: { name: "张三", num: 100 }, methods: { show() { return this.name; }, add() { this.num++; } }, beforeCreate() { console.log("=========beforeCreate============="); console.log("数据模型未加载:" + this.name, this.num); console.log("方法未加载:" + this.show()); console.log("html模板未加载:" + document.getElementById("num")); }, created: function () { console.log("=========created============="); console.log("数据模型已加载:" + this.name, this.num); console.log("方法已加载:" + this.show()); console.log("html模板已加载:" + document.getElementById("num")); console.log("html模板未渲染:" + document.getElementById("num").innerText); }, beforeMount() { console.log("=========beforeMount============="); console.log("html模板未渲染:" + document.getElementById("num").innerText); }, mounted() { console.log("=========mounted============="); console.log("html模板已渲染:" + document.getElementById("num").innerText); }, beforeUpdate() { console.log("=========beforeUpdate============="); console.log("数据模型已更新:" + this.num); console.log("html模板未更新:" + document.getElementById("num").innerText); }, updated() { console.log("=========updated============="); console.log("数据模型已更新:" + this.num); console.log("html模板已更新:" + document.getElementById("num").innerText); } }); </script>
npm install webpack -g
2.全局安装vue脚手架
npm install -g @vue/cli-init
3.初始化vue项目
vue init webpack appname
使用webpack模板初始化一个appname项目,并进行项目相关设置
初始化项目时错误
对应解决方案(进入c盘以管理员身份打开Windows PowerShell)
输入set-ExecutionPolicy RemoteSigned再输入Y即可。
4.根据模板初始化的提示运行项目
cd vue-model
npm run dev
5.项目文件结构介绍(我们这里只关注src里面的内容)
build文件夹打包工具有关代码
config配置信息,例如端口号,信息等
node_model 当前项目安装的所有依赖
src编写代码的文件夹
src/main.js项目主程序
static静态资源文件如图片字体
index.html首页内容
package.json npm依赖包配置信息
package-lock.json npm依赖包详细配置信息
1.npm 安装ElementUI它能更好地和 webpack 打包工具配合使用
npm i element-ui
2.导入ElementUI组件库(即可使用element提供的各种组件参考官网文档
)
import ElementUI from ‘element-ui’;
import ‘element-ui/lib/theme-chalk/index.css’;
Vue.use(ElementUI);
3.使用elementUI快速搭建后台管理系统的页面
elementUI官网找到Container布局容器:将实例的代码复制到src下的App.vue文件中并将组件用标签包裹
4.vsCode代码模板的使用
新建全局用户代码片段vue.json
给出一个模板实例,将示例复制到新建的代码片段中
{ "Print to console": { "prefix": "vue", "body": [ "<template>", " <div>", " </div>", "</template>", "", "<script>", "export default {", " // 组件名称", " name: 'demo',", " // 组件参数 接收来自父组件的数据", " props: {},", " // 局部注册的组件", " components: {},", " // 组件状态值", " data () {", " return {}", " },", " // 计算属性", " computed: {},", " // 侦听器", " watch: {},", " // 组件方法", " methods: {},", " // 在实例初始化之后,组件属性计算之前,如data属性等", " beforeCreate () { },", " // 组件实例创建完成,属性已绑定,但DOM还未生成,$ el属性还不存在", " created () { },", " // 在挂载开始之前被调用:相关的 render 函数首次被调用。", " beforeMount () { },", " // el 被新创建的 vm.$ el 替换,并挂载到实例上去之后调用该钩子。", " // 如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$ el 也在文档内。", " mounted () { },", " // 数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。", " // 你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。", " beforeUpdate () { },", " // 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。", " // 当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。", " updated () { },", " // keep-alive 组件激活时调用。 仅针对keep-alive 组件有效", " activated () { },", " // keep-alive 组件停用时调用。 仅针对keep-alive 组件有效", " deactivated () { },", " // 实例销毁之前调用。在这一步,实例仍然完全可用。", " beforeDestroy () { },", " // Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,", " // 所有的事件监听器会被移除,所有的子实例也会被销毁。", " destroyed () { }", "}", "</script>", "", "<!--使用了scoped属性之后,父组件的style样式将不会渗透到子组件中,-->", "<!--然而子组件的根节点元素会同时被设置了scoped的父css样式和设置了scoped的子css样式影响,-->", "<!--这么设计的目的是父组件可以对子组件根元素进行布局。-->", "<style scoped>", "", "</style>", "$2" ], "description": "Log output to console" } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。