- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的一些同事使用 Vue.js 开始了一个相当复杂的 Web 应用程序。他们希望能够使用我过去使用 JQuery 从头开始制作的一些小部件,因为重新实现它们需要大量的精力/时间。
我知道如果您小心的话,可以安全地将 JQuery 与 Vue.js 一起使用,但是我能够找到的信息似乎归为相当模糊的博客文章,而且我的同事已经通知我,他们正在努力弄清楚如何去做吧。因此,我正在考虑是否可以找到一种方法将我的小部件很好地包装到一个可移植的跨框架库中(对于可以在 Vue.js 中使用的初学者)。例如,类似于人们如何创建提供跨语言 API 的绑定(bind)。理想情况下,它应该让人们很容易在 Vue.js 中使用它,并且应该消除潜在陷阱的危险。这样做有什么问题吗,是否有任何现有的工作可以利用,或者人们这样做的惯用方式?
对于添加的上下文,目前,小部件有一个接口(interface),其中包括一个构造函数(您可以在其中传递将附加到的父 DOM 元素的 id)、一个配置函数,并且它还在更改时发出多个信号/事件(虽然,这些可以由定期检查其状态的函数替换)。
最佳答案
就创建可移植和跨框架库而言,我认为 jQuery 只是一个依赖项,它允许您创建某些元素并执行某些任务,您可以根据目标框架的要求拦截和/或修改这些元素。因此,您实际上是在围绕它创建一个包装器 组件 ,因为当今排名前三的 JavaScript 框架(React、Vue、Angular)都是基于组件的。
主要区别之一(简单地说)是: react 系统与 DOM 操作。
现在,谈论将 jQuery 插件移植到 Vue — 我不是这两个库的专家,但我自己来自 jQuery,我想说这就像在 Vue 组件内部 data
上保留对小部件/插件实例的引用一样简单和/或 props
并让它有选择地公开相应的方法。方法公开部分是可选的原因与区分一个库与另一个库的原因相同——Vue 在库和框架之间扩展时更加通用。
在 jQuery 中,您将创建一个对象的实例并将其传递给它的公共(public)方法用法;而在 Vue 中,除了根实例(您是 could ,但您通常不必)之外,您不会显式创建实例——因为组件本身 是(内部构造的)实例 。维护其状态和数据是组件的责任;兄弟和/或父组件通常没有 直接 访问它们。
Vue 和 jQuery 的相似之处在于它们都支持状态/数据同步。使用 jQuery,很明显,因为所有引用都在全局范围内;对于 Vue,可以使用 v-model
或 .sync
修饰符(在 Vue 3 中替换为 v-model
上的参数)。此外,他们还使用稍微不同的方法进行事件订阅。
让我们使用 jQuery Autocomplete widget 并为其添加一些 Vue 支持。我们将关注 3 件事(选项、事件和方法),并以它们各自的 3 项作为示例和比较。我不能在这里涵盖所有内容,但这应该会给你一些基本的想法。
设置:jQuery
为了符合您的规范,我们假设这个小部件/插件是 new
范围内的 window
类。
在 jQuery 中,您将编写以下内容(在 document
准备好或在关闭 <body>
标记之前包装在 IIFE 中):
var autocomplete = new Autocomplete({
source: [
'vue',
'react',
'angular',
'jquery'
],
appendTo: '#autocomplete-container',
disabled: false,
change: function(event, ui) { },
focus: function(event, ui) { },
select: function(event, ui) { }
});
// And then some other place needing manual triggers on this instance
autocomplete.close();
var isDisabled = autocomplete.option('disabled');
autocomplete.search('ue'); // Matches 'vue' and 'jquery' ;)
在父作用域中的某处预定义或动态创建目标元素:
<input type="search" class="my-autocomplete" />
移植到 Vue
mounted
钩子(Hook)中实例化这个插件,因为这是我们的目标元素将被创建并可以真正构建的地方。在图表
here 中了解有关生命周期 Hook 的更多信息。
Autocomplete.vue
<template>
<!--
Notice how this `input` element is added right here rather than we requiring
the parent component to add one, because it's now part of the component. :)
-->
<input type="search" class="my-autocomplete" />
</template>
<script>
export default {
// Basically, this is where you define IMMUTABLE "options", so to speak.
props: {
source: {
type: Array,
default: () => []
},
disabled: {
type: Boolean,
default: false
}
},
// And this is where to prepare and/or specify the internal options of a component.
data: () => ({
instance: null
}),
mounted() {
// `this` here refers to the local Vue instance
this.instance = new Autocomplete({
source: this.source,
disabled: this.disabled,
appendTo: this.$el // Refers to the `input` element on the template,
change: (event, ui) => {
// You can optionally pass anything in the second argument
this.$emit('change', this.instance);
},
focus: (event, ui) => {
this.$emit('focus', this.instance, event);
},
select: (event, ui) => {
this.$emit('select', this, event, ui);
}
});
},
methods: {
close() {
this.instance.autocomplete('close');
},
getOption(optionName) {
return this.instance.autocomplete('option', optionName);
},
search(keyword) {
this.instance.autocomplete('search', keyword);
}
}
}
</script>
使用组件:
Parent.vue
(或其他)
<template>
<div class="parent">
<autocomplete
ref="autocomplete"
:source="items"
:disabled="disabled"
@change="onChange"
@focus="onFocus"
@select="onSelect">
</autocomplete>
</div>
</template>
<script>
import Autocomplete from 'path/to/your-components/Autocomplete.vue';
export default {
data: () => ({
items: [
'vue',
'react',
'angular',
'jquery'
],
disabled: false
}),
methods: {
onChange() {
},
onFocus() {
},
onSelect() {
}
},
mounted() {
// Manually invoke a public method as soon as the component is ready
this.$refs.autocomplete.search('ue');
},
components: {
Autocomplete
}
}
</script>
我们还没有到那里!我特意省略了上面例子的
"two-way binding" 部分,让我们现在仔细看看。但是,这一步是可选的,只有当您需要在组件(父 ↔ 子)之间同步数据/状态时才应该执行,例如:您在组件上有一些逻辑,当某些值获得时,将输入的边框颜色设置为红色进入。现在,由于您正在修改作为 prop 绑定(bind)到该组件的父状态(例如
invalid
或
error
),您需要通过
$emit
-ting 新值通知他们其更改。
Autocomplete.vue
组件上,为简洁起见,省略了其他所有内容):
{
model: {
prop: 'source',
event: 'modified' // Custom event name
},
async created() {
// An example of fetching remote data and updating the `source` property.
const newSource = await axios.post('api/fetch-data').then(res => res.data);
// Once fetched, update the jQuery-wrapped autocomplete
this.instance.autocomplete('option', 'source', newSource);
// and tell the parent that it has changed
this.$emit('modified', newSource);
},
watch: {
source(newData, oldData) {
this.instance.autocomplete('option', 'source', newData);
}
}
}
我们基本上是
watch
-ing“急切地”进行数据更改。如果愿意,您可以使用
$watch
实例方法懒惰地执行此操作。
<template>
<div class="parent">
<autocomplete
ref="autocomplete"
v-model="items"
:disabled="disabled"
@change="onChange"
@focus="onFocus"
@select="onSelect">
</autocomplete>
</div>
</template>
这将启用上述双向绑定(bind)。你可以对其他你需要“ react ”的 Prop 做同样的事情,比如这个例子中的
disabled
Prop ——只是这次你会使用
.sync
修饰符;因为在 Vue 2 中,不支持多个
v-model
。 (如果你还没有走得太远,我建议你一直使用 Vue 3 🙂)。
this
对象为 undefined
、 null
或在嵌套方法或外部函数中引用时出现意外情况。转到 the docs 并搜索“箭头函数”以获取完整说明以及如何避免遇到此问题。 const Autocomplete = Vue.extend({
template: `
<div class="autocomplete-wrapper">
<p>{{label}}</p>
<input type="search" class="my-autocomplete" />
</div>
`,
props: {
source: {
type: Array,
default: () => []
},
disabled: {
type: Boolean,
default: false
},
label: {
type: String
}
},
model: {
prop: 'source',
event: 'modified'
},
data: () => ({
instance: null
}),
mounted() {
const el = this.$el.querySelector('input.my-autocomplete');
this.instance = $(el).autocomplete({
source: this.source,
disabled: this.disabled,
change: (event, ui) => {
// You can optionally pass anything in the second argument
this.$emit('change', this.instance);
},
focus: (event, ui) => {
this.$emit('focus', this.instance, event);
},
select: (event, ui) => {
this.$emit('select', this, event, ui);
}
});
},
methods: {
close() {
this.instance.autocomplete('close');
},
getOption(optionName) {
return this.instance.autocomplete('option', optionName);
},
search(keyword) {
this.instance.autocomplete('search', keyword);
},
disable(toState) {
this.instance.autocomplete('option', 'disabled', toState);
}
},
watch: {
source(newData, oldData) {
this.instance.autocomplete('option', 'source', newData);
},
disabled(newState, oldState) {
this.disable(newState);
}
}
});
new Vue({
el: '#app',
data: () => ({
items: [
'vue',
'react',
'angular',
'jquery'
],
disabled: false
}),
computed: {
computedItems: {
get() {
return this.items.join(', ');
},
set(val) {
this.items = val.split(', ')
}
}
},
methods: {
onChange() {
// Do something
},
onFocus() {},
onSelect(instance, event, ui) {
console.log(`You selected: "${ui.item.value}"`);
}
},
components: {
Autocomplete
}
})
#app {
display: flex;
justify-content: space-between;
}
#app > div {
flex: 0 0 50%;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
<link rel="stylesheet" href="/resources/demos/style.css" />
<script src="https://vuejs.org/js/vue.min.js"></script>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="app">
<autocomplete
v-model="items"
:disabled="disabled"
label='Type something (e.g. "ue")'
@change="onChange"
@focus="onFocus"
@select="onSelect">
</autocomplete>
<div>
<p>Edit this comma-separated list of items and see them reflected on the component</p>
<textarea
v-model.lazy="computedItems"
cols="30"
rows="3">
</textarea>
</div>
</div>
window
范围
和 中,您正在使用 ESLint,您需要确保它们被指定为全局变量;否则,
no-undef
规则将对已访问但未在同一文件中定义的变量发出警告。解决方法见
this post。
关于javascript - 有没有一种很好的方法可以将基于 JQuery 的小部件包装到一个可以在 Vue.js 中轻松使用的模块中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64979260/
我想向一些用户公开一个 Web 部件,但不是所有用户。如何在“添加 Web 部件”弹出窗口中显示或隐藏 Web 部件?我想通过代码来做到这一点,我希望使用 SharePoint 角色来实现这一点。 最
我无法创建两个以上的 StatusBar 部分: HWND hStatusBar = CreateWindowEx(0, STATUSCLASSNAME, "", WS_CHILD | WS_VISI
使用 SharePoint 2007,如何在编辑页面模式下允许将 CEWP 添加到“添加 Web 部件”对话框的选择菜单?目前,我只能添加公告、日历、链接、共享文档、任务,但我无法添加 CEWP。我可
哪个 Web 部件以及如何配置它以查看来自不同网站集的列表? 请注意,我不想查看页面,而是查看列表。例如,在单独的网站集下查看来自不同团队网站的公告。 预先感谢您的帮助。 最佳答案 Data Form
以下是我在 FeatureDeactivation 事件处理程序中添加的代码片段。我无法获得删除 System.Web.UI.WebControls.WebParts 类型的 webpart 的解决方
我一直在尝试跟踪来自以下方面的信息: Long URL clipped to stop breaking the page 和 http://msdn.microsoft.com/en-us/libr
我想创建一个自定义 Web 部件,它具有 1 个以上的筛选器 Web 部件,并且可以在运行时/设计时连接到报表查看器 Web 部件(集成模式)。 我为此搜索了很多,但找不到一种方法来让单个 Web 部
我正在尝试创建一个 Web 部件,使用户无需离开 AllItems.aspx 页面即可编辑项目。 Web 部件应具有与 EditForm.aspx 页面类似的功能。 我已经使用 ConnectionC
这些年发布的许多应用程序都有新的 GUI 部件。iTunes 或 Twitter.app 中垂直布局的最小、最大和关闭按钮(但最新的具有默认布局),Safari 和终端中的选项卡控件,GarageBa
在具有数据库依赖性的 WSS3 或 MOSS2007 中部署 Web 部件的最佳方法是什么? .wsp 是否应该包含创建数据库的代码,我应该将 .wsp 封装在另一个处理数据库创建的安装程序中,还是应
我在我们位于 http://sharepoint:12345 的 moss 服务器上创建了一个新的共享点站点并毫无问题地向其添加了 CQWP。 我有一个指向同一台服务器的域名。所以我指向了http:/
在官方 Office 2007 站点中有许多对筛选器 Web 部件的引用。当我尝试添加其中之一时,我的 Sharepoint 中的 Web 部件列表没有显示任何筛选器 Web 部件。 如果有人遇到相同
我被要求在 Sharepoint 中创建一个 Web 部件,列出用户在网站集中访问的最后 10 个文档。 我的客户想要一种快速的方式让用户访问文档,这样他们就不必翻遍文件夹结构来查找文档,因为大多数时
我需要使用 C# 以编程方式将 SharePoint Web 部件“站点用户”添加到页面。 我知道如何添加 Web 部件,但如何从 Share Point 获取“站点用户”Web 部件?我不知道如何实
我正在使用 MEF 在我的应用程序中加载插件。一切正常,但我希望在将新部件放入我的应用程序文件夹时发现它们。这可能吗? DirectoryCatalog 有一个 Changed 事件,但我不确定它是如
我有一个 Winforms 桌面应用程序正在加载具有相同接口(interface)类型的多个 MEF 部件。 问题:当我尝试加载多个相同类型时,出现以下异常: 组成保持不变。由于以下错误,更改被拒绝:
我有一个内容查询 Web 部件,它按内容类型对网站集进行查询。我已按内容类型对其进行了分组,因此我有: -- Agenda (Content Type) ----Agenda #1 ----Agend
考虑以下 SharePoint 站点层次结构: - Site Collection - Site1 - Subsite1 - AnotherSubsite1
好吧,在我的 SharePoint (2013) 网站中,我制作了一个简单的 JavaScript Web 部件,每五分钟刷新一次页面。我去调整时间,在刷新前输入等待时间的地方退格,然后不假思索地退出
我不知道 Sharepoint 脚本,我的同事也不知道 JavaScript。他使用了他在 http://www.wonderlaura.com/Lists/Posts/Post.aspx?ID=22
我是一名优秀的程序员,十分优秀!