vue-学习笔记2
Vue核心知识点

Vue核⼼知识点⼀、vue.config.js 基本配置module.exports = {// 基本路径 cli3.3以前版本⽤baseUrlpublicPath: '/',// 输出⽂件⽬录outputDir: 'dist',// ⽤于嵌套⽣成的静态资源assetsDir: '',// ⽣产环境sourMapproductionSourceMap: false,// webpack配置configureWebpack: () => {},chainWebpack: () => {},// css相关配置css: {// 启动css modulesmodules: false,// 是否使⽤css分离插件extract: true,// 开启 css sourcemaps?sourceMap: false,// css 预处理器配置项loaderOptions: {}},// webpack-dev-server 相关配置devServer: {host: '0.0.0.0',port: 8080,proxy: {} // 设置代理},// 第三⽅插件配置pluginOptions: {// ...}}⼆、vue组件间传值1. ⽗⼦组件传值(1) props(⽗传⼦) / $emit(⼦传⽗)(2) $parent / $children// App => Father => Child// Father.vuemounted () {console.log(this.$children[0].val) // 访问⼦组件 Child 的某个数据(⼦传⽗)console.log(this.$parent.val) // 访问⽗组件 App 的某个数据(⽗传⼦)console.log(this.$parent.handleClick) // 也可以是某个⽅法}(3) $refs(访问具体DOM节点)ref 后⾯⾃定义节点名称,从⽽实现在 js 中访问,访问的⽅式是 this.$refs.⾃定义名称 。
vue-element-admin学习笔记--登陆功能

vue-element-admin学习笔记--登陆功能没有按照vue-element-admin的⽅式设计登陆,先简单的实现⼀个登陆功能登陆功能完成功能思路如下:router⾥配置访问后的BasicLayout路由及404⽤户点击登录按钮,将参数值提交到后台使⽤vuex实现参数提交vuex中通过request(封装axios)模拟mock请求,返回token及⾓⾊(admin、guest、user)登陆成功返回到BasicLayout的页⾯,登陆失败返回404页⾯配置devServer及mock⽂件夹router中配置import Vue from "vue";import VueRouter from "vue-router";import NotFound from "@/views/404.vue";/*** 重写路由的push⽅法*/const routerPush = VueRouter.prototype.push;VueRouter.prototype.push = function push(location) {return routerPush.call(this, location).catch(error => error);};e(VueRouter);const routes = [{path: "/",name: "Home",component: () =>import(/* webpackChunkName: "layout" */ "@/layouts/BasicLayout.vue")},{path: "/about",name: "About",// route level code-splitting// this generates a separate chunk (about.[hash].js) for this route// which is lazy-loaded when the route is visited.component: () =>import(/* webpackChunkName: "about" */ "../views/About.vue")},{path: "/user",component: { render: h => h("router-view") },children: [{ path: "/user", redirect: "/user/login" },{path: "/user/login",name: "login",component: () =>import(/* webpackChunkName: "user" */ "@/views/user/Login.vue")},{path: "/user/register",name: "register",component: () =>import(/* webpackChunkName: "user" */ "@/views/user/Register.vue")}]},{ path: "*", name: "404", component: NotFound }];const router = new VueRouter({mode: "history",base: process.env.BASE_URL,routes});export default router;配置vuex中的⽅法和参数编写⽅法在store下新建modules⽂件夹,新建⼀个user的store⽂件user.js 配置user中的登陆⽅法import router from "@/router";import request from "@/utils/request";const state = {userInfo: {name: "",token: "",password: "",roles: []}};const actions = {submitlogin({ commit }, { payload }) {const { username, password } = payload;//提交mock请求request({url: "/api/user/login",method: "post",data: { name: username, password: password }}).then(response => {if (erInfo.token != "error") {commit("SET_ROLES", erInfo.roles);commit("SET_NAME", );commit("SET_TOKEN", erInfo.token);router.push("/");} else {console.log(erInfo.token);router.push("/404");}});}};const mutations = {SET_TOKEN: (state, token) => {erInfo.token = token;},SET_NAME: (state, name) => { = name;},SET_ROLES: (state, roles) => {erInfo.roles = roles;}};export default {namespaced: true,state,mutations,actions};在store中的index.js中注册user模块import Vue from "vue";import Vuex from "vuex";import user from "./modules/user";e(Vuex);export default new Vuex.Store({state: {},mutations: {},actions: {},modules: { user }});封装axios安装axiosyarn add axios封装axiosimport axios from "axios";function request(options) {return axios(options).then(res => {return res;}).catch(error => {const {response: { status, statusText }} = error;//后期修改为提⽰框console.log({ status: status, statusText: statusText });return Promise.reject(error);});}export default request;配置mock配置devServer,根据vue-cli及webpack中的API,配置代理mock在vue.config.js中添加bodyParserconst bodyParser = require("body-parser");配置devServerdevServer: {before(app) {e(bodyParser.json()); //通过bodyParser获取req.body},proxy: {"/api": {target: "http://localhost:63000",bypass: function(req, res) {if (req.headers.accept.indexOf("html") !== -1) {console.log("Skipping proxy for browser request.");return "/index.html";} else if (process.env.MOCK !== "none") {const name = req.path.split("/api/")[1].split("/").join("_");const mock = require(`./mock/${name}`);const result = mock(req);//删除缓存.否是数据修改后不会变delete require.cache[require.resolve(`./mock/${name}`)];return res.send(result);}}}}},Mock数据在src同级⽬录建⽴mock⽂件夹,按照devServer中的规则建⽴Mock数据。
vue2 createdvnode 的使用

Vue2中createdVNode的使用createdVNode是Vue2中的一个核心函数,用于创建虚拟DOM节点。
虚拟DOM是Vue 中的一个重要概念,它是一种轻量级的JavaScript对象,用于描述DOM节点的结构和属性。
通过使用虚拟DOM,Vue能够高效地更新和渲染页面。
本文将详细介绍createdVNode的用法和相关知识点,包括虚拟DOM的概念、createdVNode的参数和返回值、如何使用createdVNode创建不同类型的虚拟DOM节点等。
虚拟DOM的概念在介绍createdVNode之前,我们先来了解一下虚拟DOM的概念。
虚拟DOM是Vue中的一种技术,它是通过JavaScript对象来描述真实DOM节点的结构和属性。
在Vue中,每个组件都有一个对应的虚拟DOM树,当状态发生变化时,Vue会通过比较新旧虚拟DOM树的差异,然后只更新差异部分的真实DOM,以提高渲染性能。
虚拟DOM具有以下特点: - 轻量级:虚拟DOM是基于JavaScript对象的表示,相比于真实DOM节点,它的创建和更新更加高效。
- 抽象化:虚拟DOM将真实DOM节点抽象成了JavaScript对象,使得我们可以通过JavaScript的方式来操作和管理DOM。
- 平台无关:虚拟DOM是跨平台的,不依赖于具体的浏览器和DOM API。
createdVNode的参数和返回值createdVNode是Vue2中用于创建虚拟DOM节点的函数,它的定义如下:function createVNode(type: VNodeTypes | ClassComponent | typeof NULL_DYNAMIC_COMPONENT,props?: (Data & VNodeProps) | null,children?: unknown,patchFlag?: number,dynamicProps?: string[] | null,isBlockNode?: boolean): VNode {// ...}createdVNode函数接受多个参数: - type:虚拟DOM节点的类型,可以是一个字符串(HTML标签名)或者一个组件(函数或类)。
尚硅谷张天禹老师vue2笔记

尚硅⾕张天禹⽼师vue2笔记脚⼿架⽂件结构├── node_modules├── public│├── favicon.ico: 页签图标│└── index.html: 主页⾯├── src│├── assets: 存放静态资源││└── logo.png││── component: 存放组件││└── HelloWorld.vue││── App.vue: 汇总所有组件││── main.js: ⼊⼝⽂件├── .gitignore: git版本管制忽略的配置├── babel.config.js: babel的配置⽂件├── package.json: 应⽤包配置⽂件├── README.md: 应⽤描述⽂件├── package-lock.json:包版本控制⽂件关于不同版本的Vue1. vue.js与vue.runtime.xxx.js的区别:1. vue.js是完整版的Vue,包含:核⼼功能 + 模板解析器。
2. vue.runtime.xxx.js是运⾏版的Vue,只包含:核⼼功能;没有模板解析器。
2. 因为vue.runtime.xxx.js没有模板解析器,所以不能使⽤template这个配置项,需要使⽤render函数接收到的createElement函数去指定具体内容。
vue.config.js配置⽂件1. 使⽤vue inspect > output.js可以查看到Vue脚⼿架的默认配置。
2. 使⽤vue.config.js可以对脚⼿架进⾏个性化定制,详情见:ref属性1. 被⽤来给元素或⼦组件注册引⽤信息(id的替代者)2. 应⽤在html标签上获取的是真实DOM元素,应⽤在组件标签上是组件实例对象(vc)3. 使⽤⽅式:1. 打标识:<h1 ref="xxx">.....</h1>或<School ref="xxx"></School>2. 获取:this.$refs.xxxprops配置项1. 功能:让组件接收外部传过来的数据2. 传递数据:<Demo name="xxx"/>3. 接收数据:1. 第⼀种⽅式(只接收):props:['name']2. 第⼆种⽅式(限制类型):props:{name:String}3. 第三种⽅式(限制类型、限制必要性、指定默认值):props:{name:{type:String, //类型required:true, //必要性default:'⽼王' //默认值}}备注:props是只读的,Vue底层会监测你对props的修改,如果进⾏了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中⼀份,然后去修改data中的数据。
vue2 面向对象写法

Vue.js 是一个流行的JavaScript 框架,用于构建用户界面。
它采用了一种基于组件的开发模式,使开发人员能够轻松地构建复杂的交互式应用程序。
Vue 2.x 版本引入了面向对象的写法,使代码更加模块化和可维护。
本文将介绍Vue 2 面向对象写法的一些关键概念和用法。
首先,让我们了解一下面向对象编程(Object-Oriented Programming,简称OOP)。
OOP 是一种编程范式,通过将数据和操作封装到对象中,以提高代码的可重用性和可维护性。
在Vue 2 中,我们可以使用面向对象的思想来组织和管理组件。
在Vue 2 中,每个组件都可以看作一个类(Class)。
一个类包含了组件的数据(data)、方法(methods)、计算属性(computed)和生命周期钩子函数(lifecycle hooks)。
通过将这些属性和方法封装到类中,我们可以更好地组织代码,并实现代码的复用。
下面是一个简单的示例,展示了如何使用面向对象的写法来创建一个Vue 组件类:```class MyComponent {constructor() {this.data = {message: 'Hello, Vue!'};}methods() {return {showMessage: function() {console.log(this.data.message);}};}computed() {return {reversedMessage: function() {return this.data.message.split('').reverse().join('');}};}mounted() {console.log('Component mounted.');}}```在上面的示例中,我们定义了一个名为`MyComponent` 的类。
vue学习文档

Vue学习文档1. vue是什么Vue是类似于一个JavaScript的一套框架。
比如Jquery.js核心:Vue的核心思想为数据驱动和组件化(以数据驱动模型)。
2. Vue使用2.1渲染案例1:<div id="app">{{ message }}</div>var app = new Vue({el: '#app',data: {message: 'Hello Vue!'}})说明:el:绑定的dom节点,作用的范围。
只有在这个div的盒子当中vue才会生效。
Data:数据{{}}:用来进行渲染数据内容2.2条件与循环使用2.2.1 v-ifV-if:用来做条件控制<div id="app-3"><p v-if="seen">现在你看到我了</p></div>var app3 = new Vue({el: '#app-3',data: {seen: true}})Seen:true就进行数据渲染Seen:false 就不会显示输出内容注意:v-if会删除dom节点,删除删除完后需要重新加载应用场景:对应显示和隐藏频繁的场景,建议使用v-show来进行操作(频繁删除会消耗性能)。
2.2.2 v-showV-show:跟v-if功能是一样的,但是不会删除掉dom节点,只是进行了一个显示和隐藏的切换应用场景:频繁使用进行切换选择v-show案例:<div id="app-3"><p v-show="seen">现在你看到我了</p></div>var app3 = new Vue({el: '#app-3',data: {seen: true}})说明:v-show也是通过true/false来进行控制显示和隐藏的2.2.3 v-forV-for:用来将多个元素进行遍历案例:<div id="app-4"><ol><li v-for="todo in todos">{{ todo.text }}</li></ol></div>var app4 = new Vue({el: '#app-4',data: {todos: [{ text: '学习 JavaScript' },{ text: '学习 Vue' },{ text: '整个牛项目' }]}})输出结果:2.3交互事件使用现在我们想用一个点击的事件,那应该怎么写呢?为了让用户和你的应用进行交互,我们可以用v-on指令添加一个事件监听器,来进行事件处理。
Vue-eBookReader学习笔记(阅读器解析和渲染部分)

Vue-eBookReader学习笔记(阅读器解析和渲染部分)1、阅读器解析和渲染1.1 动态路由的设置 观察成品可知,在地址栏会出现书名、分类的信息,⽽且可以在地址栏更改信息得到不同的书,这就利⽤了动态路由的技术。
1.1.1 现在先实现,在地址栏输⼊的值直接显⽰到页⾯的效果。
在路由index.js⽂件中的ebook路由下,添加children属性来存放动态路由,children是⼀个数组,每个元素是对象,⾥⾯包含了⼀个动态路由:{path: '/ebook',component: () => import('../views/ebook/index.vue'),children: [{//这⾥的冒号代表后⾯是参数,在EbookReader组件内部可以通过 $route.params.fileName来访问到path: ':fileName',component: () => import('../components/ebook/EbookReader')}]}1.1.2 构造书本地址简单功能实现完毕之后,来写:在地址栏输⼊地址+分类+|+书名可以访问到电⼦书,其实也就是在刚刚基础上将EbookReader组件⾥的打印改为字符串拼接;字符串输⼊样例:http://localhost:8080/#/ebook/History|2013_Book_FungalDiseaseInBritainAndTheUnmounted () {const fileName = this.$route.params.fileName.split('|').join('/')const baseUrl = '192.168.1.112:8082/epub/'console.log(`${baseUrl}${fileName}.epub`)}这样就从nginx上获取到了想要的资源,有了书本的地址就可以开始构造Book对象将书本地址放到vuex中存储,这时由于后来会有很多地⽅都要⽤到这个值,同样使⽤getter和mapGetters来实现简便取值;1.2 书本构造开始1.2.1 将书本渲染到dom上this.book = new Epub(url)创建新book对象获取rendition对象,主要⽤于电⼦书的渲染this.rendition = this.book.renderTo('read', {width: window.innerWidth,height: window.innerHeight//这⾥课程⾥⽼师说要加,但是加上之后发现渲染出来的元素宽度为0,去掉就好了也不知道为什么// method: 'default'})this.rendition.display()展⽰出电⼦书来1.2.2 实现左滑右滑翻页效果这⾥左滑右滑均不⽀持长按,且距离不能太短以与点击事件区别出来this.rendition.on('事件名', '事件处理函数')⽤来给book对象绑定事件this.rendition.on('touchstart', event => {this.touchStartX = event.changedTouches[0].clientXthis.touchStartTime = event.timeStamp})this.rendition.on('touchend', event => {const offsetX = event.changedTouches[0].clientX - this.touchStartXconst time = event.timeStamp - this.touchStartTimeif (time < 500 && offsetX < -40) {this.nextPage()} else if (time < 500 && offsetX > 40) {} else {this.toggleTitleAndMenu()}event.passive = falseevent.stopPropagation() //阻⽌事件传播})上⾯这段代码是获取到滑动的起始和结束的位置与时间,通过简单的运算来判断滑动的⽅向以及时间这⾥⽤的是event.passive = false,⽽不是⽼师的event.preventDefault()是因为,滑动的时候会报错,设置passive为false也可以阻⽌默认⾏为1.2.3 标题栏和菜单栏部分布局和样式都是⽤之前的代码,稍微改动即可,改完之后⼤概样⼦以及过渡动画也完成了这⾥需要滑动页⾯的时候标题栏菜单栏都要隐藏,要增加⼀个menuVisible的state来决定是否显⽰这两样东西,依然是⽤mapGatters 来简化1.2.4 ⽤mixin技术来简化代码1.2.4.1 代码复⽤发现在每个组件⾥都⽤到了以下代码,代码重复度太⼤:import { mapGetters, mapActions } from 'vuex'export const ebookMixin = {computed: {...mapGetters(['menuVisible','fileName'])}}所以将这段代码封装到utils/mixin.js⽂件中,再在要使⽤的组件⾥的script标签⾥⽤import { ebookMixin } from '../../utils/mixin',原理和使⽤mapGetters⼀样差不多再加上⼀个mixin的属性:mixins: [ebookMixin]1.2.4.2 vuex中methods的调⽤⽅法简化之前利⽤了mapGetters和getter计数来让组件⾥引⽤state的数据简便了不少,其实vuex中同样可以使⽤类似的及时让外⾯的组件调⽤⽅法⽐较简单,本来是this.$store.dispatch('⽅法名','参数'),现在可以变为this.⽅法名('参数')和getter差不多,在vuex的index.js⽂件中加上actions属性,同时在modules/actions⽂件⾥将⽅法都封装进去并且export出来,也就是将⽅法都放在⼀起⽅便管理注意这⾥和上⾯的getters有点不⼀样,是直接把book⾥的actions全拿出来放到actions.js⽂件中,接着把book⾥原来的actions删掉引⽤同样和mapGatters差不多,在组件⾥import { mapActions } from 'vuex',但这是⽅法,所以...mapActions([''])要写在methods⾥哦(同样这⼀段也可以写在mixin⾥⽅便管理)1.2.5 字号设置1.2.5.1 布局部分字体的菜单栏部分会多出上⾯那⼀截,主要的实现思路是:字体进度条左边是最⼩的字体,右边是最⼤的字体将菜单栏横着主要分成七个部分(这个数量是由总共有多少可以字号设置来决定的),每个部分分为左右两个部分显⽰⼀个边框(视觉上就是⼀条直线)⼏个部分由中间的⼩点隔开,其实每个⼩点的地⽅都是⼀个⼤点,但只有当选中某⼀个部分(字体)时,那个地⽅的⼤点才会显⽰出来表⽰选中将fontSizeList这种静态数据都放在统⼀的⽂件下管理,这⾥放在utils⽂件夹下的book.js中⽤import { FONT_SIZE_LIST } from '../../utils/book'引⼊进来再在数据⾥定义好⾃⼰的数据 fontSizeList值为FONT_SIZE_LISTexport const FONT_SIZE_LIST = [{ fontSize: 12 },{ fontSize: 16 },{ fontSize: 18 },{ fontSize: 20 },{ fontSize: 22 },{ fontSize: 24 }]每个⼩圆点有个字体,全局有defaultFontSize为当前的字体,每次触发点击事件后通过setFontSize来修改默认字体注意点:当字体设置⾯板出来之后,设置⾯板的阴影要隐藏设置⾯板隐藏,下⼀次再出来的时候字体设置⾯板应该是不出现的1.2.6 字体部分1.2.6.1 布局字体和字号在同⼀个⾯板上,上⾯是字号条占⽐2/3,下⾯是字号 1/3,其中字号设置点开有弹窗效果占⽐就⽤flex布局,垂直分布,⼀个flex为2⼀个为11.2.6.2 字号设置弹窗弹窗分为上下两个部分,上⾯是标题(后⾯⽀持中英切换),下⾯是字体列表先对⼤致布局进⾏设置,再写css,就不再多说,但是都⽤弹性布局(⾮常好)下⾯的字体列表⽤v-for循环显⽰完之后,选中的那个要单独变颜⾊,⽤:class="{'selected': isSelected(item)}"来控制加不加上那个selected的类1.2.6.3 字体设置(⽐字号设置复杂)有⼀步的设置⽅法和字号设置差不多,this.currentBook.rendition.themes.font(font),但这⼀步之后字体并没有发⽣变化epubjs的渲染是通过iframe来实现的,iframe中才是真实的阅读器的dom,要设置字体必须在这个dom⾥⾯设置,所以直接写是没⽤的(⾥⾯是⼀个独⽴的dom)利⽤epubjs的钩⼦函数:// content代表iframe⾥的dom已经加载完毕可以访问// contents是管理资源⽂件// addStylesheet是⼿动添加style样式的函数this.rendition.hooks.content.register(contents => {Promise.all([contents.addStylesheet('http://10.69.198.212:8082/fonts/daysOne.css'),contents.addStylesheet('http://10.69.198.212:8082/fonts/cabin.css'),contents.addStylesheet('http://10.69.198.212:8082/fonts/montserrat.css'),contents.addStylesheet('http://10.69.198.212:8082/fonts/tangerine.css').then(() => {})])})观察epubjs中contents的addStylesheet函数源码,发现它将接收的参数拼成⼀个url,利⽤link标签引⼊css,所以要接收url的css,因此就将字体⽂件放⼊nginx服务器上,传⼊的就是nginx服务器下的那个url上⾯的register函数返回是⼀个promise对象,所以可以利⽤Promise.all这个函数来对那些promise对象进⾏处理,就可以在全部注册完之后⼲点什么了环境变量http://10.69.198.212:8082这个⽹址很可能在⽣产环境和开发环境是不⼀样的,所以在这⾥不能直接写死⽹址,⽽是要添加环境变量在项⽬根⽬录下添加⽂件 .env.development,在⾥⾯写上要替换的⽹址只有以VUE_APP_开头的变量会被webpack.DefinePlugin静态嵌⼊到客户端侧的包中// .env.developmentVUE_APP_RES_URL=http://10.69.198.212:8082// 替换之后contents.addStylesheet(`${process.env.VUE_APP_RES_URL}/fonts/cabin.css`),环境变量是在服务器启动的时候加⼊,所以这⾥要重启服务器1.2.7 字体和字号设置离线缓存⼀般会有要求在客户下⼀次进⼊页⾯的时候,设置仍然保持上⼀次退出的样⼦,所以这⾥⽤到了localStorage来实现先安装cnpm i --save web-storage-cache在utils⽂件夹下创建localStorage.js⽂件⽤来封装localStorage的操作// 基本操作import Storage from 'web-storage-cache'const localStorage = new Storage()export function setLocalStorage (key, value) {return localStorage.set(key, value)}export function getLocalStorage (key) {return localStorage.get(key)}export function removeLocalStorage (key) {return localStorage.delete(key)}export function clearLocalStorage () {localStorage.clear()}下⾯的具体操作代码,每本书都在localStorage⾥有⾃⼰的单独设置localStorage⾥键是${fileName}-info,值是⼀个book对象,以后每次要加新的设置就直接在book对象中加就可以了// 具体操作代码export function setBookObject (fileName, key, value) {let book = getLocalStorage(`${fileName}-info`)if (!book) {book = {}}book[key] = valuesetLocalStorage(`${fileName}-info`, book)}export function getBookObject (fileName, key) {const book = getLocalStorage(`${fileName}-info`)if (book) {return book[key]} else {return null}}export function getFontFamily (fileName) {return getBookObject(fileName, 'fontFamily')}export function saveFontFamily (fileName, font) {setBookObject(fileName, 'fontFamily', font)}加完这些之后要设置,每次换完字体就要saveFontFamily,以及⼀开始渲染的时候也要设置,开始的时候利⽤rendition.display返回的是⼀个promise对象来进⾏操作this.rendition.display().then(() => {const font = getFontFamily(this.fileName)if (font) {this.currentBook.rendition.themes.font(font)this.setDefaultFontFamily(font)} else {saveFontFamily(this.fileName, 'Default')}})其余的设置也是差不多的操作1.2.8 语⾔国际化⾸先准备好了两个不同语⾔的⽂件, ⾥⾯准备好了各个地⽅需要的⽂字利⽤ VueI18N插件安装cnpm i --save vue-i18n在src⽬录下新建lang⽂件夹来管理语⾔lang⽂件夹下的index.js⽂件⾥使⽤插件, 同时注意要在main.js中引⼊这个插件⽂件并注册, 不然⽆法使⽤同样利⽤localStorage来存储当前的语⾔, 以备下⼀次打开时需要1.2.9 主题设置这⾥主题依旧是静态资源⽂件, 所以在utils下的book.js中仍然要加上theme相关信息主题的名字也⽤到了国际化语⾔, 所以book.js中也要使⽤插件vuei18n, 这⾥就有问题了发现i18n.t()函数使⽤的时候报错i18n is undefied, 明明i18n已经在main.js的根组件中注册好了, 为什么还是使⽤不了?这是由于book.js中代码执⾏的时候, i18n插件还没被注册完毕. 也没什么好的解决⽅法, 就在开头引⼊i18n插件吧import i18n from'../lang'可以看看这篇⽂章设置主题要先在eBook对象中注册主题分别需要名字以及对应的样式, 这⾥由于在EBook Reader组件以及EbookThemeSetting组件中都⽤到了themeList, 所以也将theme List的那个混⼊过程加⼊到mixin中, 这样只要引⽤了mixin就都能取到themeList其余就和字体字号⼀样, initTheme⾥判断默认主题什么什么的, 还有localStorage的存储~⼩bug, 发现每个主题只能切换⼀次就不能再换回来了, 所以这⾥把epubjs的版本换成0.3.71 就⾏了1.2.10 全局主题设置主要的思想是动态添加css⽂件, 我们知道, css⽂件的添加是通过link标签实现的, 所以这⾥也就是动态添加link标签来实现 ( 这个函数写在book.js⽂件中并且export出去, 要使⽤的地⽅就引⽤ )export function addClass (url) {const link = document.createElement('link')link.setAttribute('rel', 'stylesheet')link.setAttribute('href', url)link.setAttribute('type', 'text/css')document.querySelector('head').appendChild(link)}这⾥的link标签需要url,我们将主题⽂件放到nginx服务器下, (注意这⾥的地址还是要使⽤环境变量, ~包括之前的book的地址也要). 每次切换主题的时候就调⽤addClass这个函数每次选择切换⼀次主题, 不仅电⼦书的主题要切换全局主题也要切换, 写另外⼀个函数来根据不同的电⼦书主题同步切换到全局主题// 这个函数在EbookSettingTheme和EbookReader中都要⽤到,所以写在mixin中供全局调⽤initGlobalStyle () {switch (this.defaultTheme) {case 'Default': addClass(`${process.env.VUE_APP_RES_URL}/theme/theme_default.css`)breakcase 'Gold': addClass(`${process.env.VUE_APP_RES_URL}/theme/theme_gold.css`)breakcase 'Eye': addClass(`${process.env.VUE_APP_RES_URL}/theme/theme_eye.css`)breakcase 'Night': addClass(`${process.env.VUE_APP_RES_URL}/theme/theme_night.css`)breakdefault: addClass(`${process.env.VUE_APP_RES_URL}/theme/theme_default.css`)}}但是这也下去会有⼀个问题, 每切换⼀次主题就多添加⼀个link标签, 加重了渲染的负担, 所以同时还要想办法移除之前添加的link标签。
vue路由实训心得、收获

vue路由实训心得、收获在学习Vue.js路由实训的过程中,我收获了很多关于Vue.js路由的知识和实践经验,下面是我的一些心得和总结。
1. 理解Vue.js路由的概念和原理在开始学习Vue.js路由实训之前,我对Vue.js路由的概念和原理不是很了解。
通过实训,我深入学习了Vue.js路由的概念、作用、路由映射、路由守卫等方面的知识,了解了Vue.js路由的工作原理和优化方法。
2. 掌握Vue.js路由的使用方法在实训中,我学习了Vue.js路由的基本使用方法,包括创建路由、定义路由、路由映射、路由守卫等。
同时,我还学习了Vue.js路由的生命周期、组件复用、路由事件处理等方面的知识,提高了自己的Vue.js路由使用能力。
3. 理解Vue.js路由的应用场景Vue.js路由实训的另一个重要收获是,我深入了解了Vue.js路由的应用场景,包括单页面应用、API集成、组件化应用等。
通过实践,我学会了如何在Vue.js应用中使用Vue.js路由,更好地实现应用的功能和交互效果。
4. 提高Vue.js应用的性能和可维护性在Vue.js路由实训中,我还学习了如何提高Vue.js应用的性能和可维护性。
例如,我学习了如何优化Vue.js应用的渲染性能,避免大量DOM操作和资源加载等问题,提高应用的流畅度和用户体验。
5. 学习其他Vue.js相关技能除了Vue.js路由实训外,我还学习了其他Vue.js相关技能,例如Vue.js组件、Vue.js指令、Vue.js状态管理等方面的知识,提高了自己的Vue.js应用开发能力。
总之,学习Vue.js路由实训是一次非常有益的经历,让我更加深入地了解了Vue.js路由的概念和原理,掌握了Vue.js路由的使用方法,理解了Vue.js路由的应用场景,提高了自己的性能和可维护性,学习了其他Vue.js相关技能。
通过这些学习,我收获了很多有用的经验和技能,对我的Vue.js应用开发能力有了很大的提升。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
use: <partial name="agreement-list"></partial>
## 事件系统 var parent = new Vue({
template: '', created: function () {
<child msg="hello!"></child>
## prop 绑定类型 <location v-ref:location :province.sync="form.province" :city.sync="form.city"></location>
sync显式双向绑定 once一次性绑 默认情况下,单向绑定
vue-学习笔记2
## 通过 prop 传递数据 默认情况下,组件有独立作用域。这意味着你无法在子组件的模板中引用父级的数据。为了传递数据到拥有独立作用域的子组件中,我们 需要用到 prop。
一个 “prop” 是指组件的数据对象上的一个预期会从父级组件取得的字段。一个子组件需要通过 prop 选项显式声明它希望获得的 prop:
this.$on('child-created', function (child) { console.log('new child created: ') console.log(child)
}) }, components: {
child: { created: function () {
this.$dispatch('child-created', this) } } } }).$mount()
'</thead>', '<tbody>',
'<tr v-for="item in list">', '<td>{{item.agreementCode}}</td>', '<td>{{panyName}}</td>', '<td>{{statusText[item.status + ""]}}</td>', '<td>{{item.dealId}}</td>',
/*指令简写方式 -- 绑定两个类及一个点击事件*/ <input :class="['class1','class2']" type="text" @click="submitForm" />
1.
绑定click事件
<a @click="doSomething"></a>
绑定动态属性
<a :href="url"></a>
2. <!-- 阻止单击事件冒泡 --> <a @click.stop="doSomething"></a>
<!-- 只在按下回车键的时候触发事件 --> <input @keyup.enter="submit">
3. <!-- debounce 设置一个最小的延时 --> <input v-model="note" debounce="500">
<!-- 在 "change" 而不是 "input" 事件中更新数据 --> <input v-model="msg" lazy>
## 私有资源 Vue.partial('agreement-list', [
'<h3>协议列表</h3>', '<table class="c-app-list-table">',
'<thead>', '<tr>', '<th>协议号</th>', '<th>企业名称</th>', '<th>状态</th>', '<th>DealId</th>', '</tr>',
## 组件生命周期 每一个组件,或者说 Vue 的实例,都有着自己的生命周期:它会被创建、编译、插入、移除,最终销毁。在这每一个时间点,实例都会 触发相应的事件,而在创建实例或者定义组件时,我们可以传入生命周期钩子函数来响应这些事件 var MyComponent = Vue.extend({ created: function () {
## 子组件引用 v-ref : <location v-ref:location :provincnc="form.city"></location>
## 路由
和Angular一样,Vue也具有它的路由功能。通过路由功能,我们可以实现各个组件的按需加载,轻松构建单页应用
ponent('child', { props: ['msg'], // 声明 prop // prop 可以在模板内部被使用, // 也可以类似 `this.msg` 这样来赋值 template: '<span>{{msg}}</span>' })
然后,我们可以像这样向这个组件传递数据:
console.log('An instance of MyComponent has been created!') } })
## 简写方式
/* v-bind: 用来绑定对象或者元素及属性的[比如class,自定义属性,一个对象]; v-on:用来绑定事件的[比如click,submit等]
缩写方式 v-bind: === : v-on: === @ */ /*常规的vue写法 -- 绑定两个类及一个点击事件*/ <input v-bind:class="['class1','class2']" type="text" v-on:click="submitForm" />